广州网站建设58,手机号码网站建设,自己建的网站能赚钱吗,可以下载电影的网站怎么做一、引言 什么是OCR#xff1f;OCR(Optical Character Recognition#xff0c;光学字符识别)是指电子设备(例如扫描仪或数码相机)检查纸上打印的字符#xff0c;通过检测暗、亮的模式确定其形状#xff0c;然后用字符识别方法将形状翻译成计算机文字的过程。简单地说#…一、引言 什么是OCROCR(Optical Character Recognition光学字符识别)是指电子设备(例如扫描仪或数码相机)检查纸上打印的字符通过检测暗、亮的模式确定其形状然后用字符识别方法将形状翻译成计算机文字的过程。简单地说OCR是一种技术该项技术采用光学的方式将纸质文档中的文字转换为黑白点阵图像然后通过识别软件将图像中的文字转换成文本格式供文字处理软件进一步编辑加工。 什么是TesseractTesseract was originally developed at Hewlett-Packard Laboratories Bristol UK and at Hewlett-Packard Co, Greeley Colorado USA between 1985 and 1994, with some more changes made in 1996 to port to Windows, and some Cizing in 1998. In 2005 Tesseract was open sourced by HP. From 2006 until November 2018 it was developed by Google.Tesseract最初是在英国布里斯托尔的惠普实验室和美国科罗拉多州格里利的惠普公司于1985年至1994年间开发的1996年做了一些更改以移植到Windows并在1998年进行了一些c化。2005年Tesseract被惠普开源。从2006年到2018年11月它由谷歌开发。简单地说Tesseract 就是上面OCR所说的“识别软件”的具体实现。 OCR的识别对象(输入)是一张图片而识别结果(输出)是计算机文字。在Android手机端主要存在两种图片的获取方式一种是从相册中选择一个另一个是直接拍照获得。因此本文将实现最简单的OCR思路首先从手机中获得一张图片然后将其输入到Tesseract库最后通过该库输出识别结果。由于只是学习该库的使用方式所以博主忽略了其它辅助性的功能比如拍照识别。 二、Android通过Tesseract实现OCR
1、在Module的build.gradle文件中添加以下依赖
implementation com.rmtheis:tess-two:9.1.0
2、在AndroidManifest.xml文件中添加以下权限 uses-permission android:nameandroid.permission.READ_EXTERNAL_STORAGE /uses-permission android:nameandroid.permission.WRITE_EXTERNAL_STORAGE /
3、在MainActivity中申请权限 建议在onCreate方法中执行下面的checkPermission方法 // 检查应用所需的权限如不满足则发出权限请求private void checkPermission() {if (ContextCompat.checkSelfPermission(getApplicationContext(),Manifest.permission.READ_EXTERNAL_STORAGE) ! PackageManager.PERMISSION_GRANTED) {ActivityCompat.requestPermissions(MainActivity.this,new String[]{Manifest.permission.READ_EXTERNAL_STORAGE}, 120);}if (ContextCompat.checkSelfPermission(getApplicationContext(),Manifest.permission.WRITE_EXTERNAL_STORAGE) ! PackageManager.PERMISSION_GRANTED) {ActivityCompat.requestPermissions(MainActivity.this,new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, 121);}}
4、从assets中读取一张读片 既用于显示又用于识别 // 从assets中读取一张Bitmap类型的图片private Bitmap getBitmapFromAssets(Context context, String filename) {Bitmap bitmap null;AssetManager assetManager context.getAssets();try {InputStream is assetManager.open(filename);bitmap BitmapFactory.decodeStream(is);is.close();Log.i(TAG, 图片读取成功。);Toast.makeText(getApplicationContext(), 图片读取成功。, Toast.LENGTH_SHORT).show();} catch (IOException e) {Log.i(TAG, 图片读取失败。);Toast.makeText(getApplicationContext(), 图片读取失败。, Toast.LENGTH_SHORT).show();e.printStackTrace();}return bitmap;}
5、做好OCR的准备工作 去https://github.com/tesseract-ocr/下载.traineddata语言包然后放在项目assets目录下并通过以下代码复制到Android文件系统中 // 为Tesserect复制(从assets中复制过去)所需的数据private void prepareTess() {try{// 先创建必须的目录File dir getExternalFilesDir(TESS_DATA);if(!dir.exists()){if (!dir.mkdir()) {Toast.makeText(getApplicationContext(), 目录 dir.getPath() 没有创建成功, Toast.LENGTH_SHORT).show();}}// 从assets中复制必须的数据String pathToDataFile dir / DATA_FILENAME;if (!(new File(pathToDataFile)).exists()) {InputStream in getAssets().open(DATA_FILENAME);OutputStream out new FileOutputStream(pathToDataFile);byte[] buff new byte[1024];int len;while ((len in.read(buff)) 0) {out.write(buff, 0, len);}in.close();out.close();}} catch (Exception e) {Log.e(TAG, e.getMessage());}}
6、点击按钮后调用以下方法执行OCR识别 // OCR识别的主程序private void mainProgram() {// 从assets中获取一张Bitmap图片Bitmap bitmap getBitmapFromAssets(MainActivity.this, TARGET_FILENAME);// 同时显示在界面main_iv_image.setImageBitmap(bitmap);if (bitmap ! null) {// 准备工作创建路径和Tesserect的数据prepareTess();// 初始化TesserectTessBaseAPI tessBaseAPI new TessBaseAPI();String dataPath getExternalFilesDir(/).getPath() /;tessBaseAPI.init(dataPath, eng);// 识别并显示结果String result getOCRResult(tessBaseAPI, bitmap);main_tv_result.setText(result);}}// 进行OCR并返回识别结果private String getOCRResult(TessBaseAPI tessBaseAPI, Bitmap bitmap) {tessBaseAPI.setImage(bitmap);String result -;try{result tessBaseAPI.getUTF8Text();}catch (Exception e){Log.e(TAG, e.getMessage());}tessBaseAPI.end();return result;}
7、编译运行效果如图 个人感觉识别率不是很准一般般。
8、源代码贴一下 MainActivity.java
import androidx.appcompat.app.AppCompatActivity;
import androidx.core.app.ActivityCompat;
import androidx.core.content.ContextCompat;import android.Manifest;
import android.content.Context;
import android.content.pm.PackageManager;
import android.content.res.AssetManager;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Bundle;
import android.util.Log;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.TextView;
import android.widget.Toast;import com.googlecode.tesseract.android.TessBaseAPI;import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;public class MainActivity extends AppCompatActivity {public static final String TESS_DATA /tessdata;private static final String TARGET_FILENAME vin_demo.png;private static final String DATA_FILENAME eng.traineddata;private static final String TAG MainActivity.class.getSimpleName();private Button main_bt_recognize;private TextView main_tv_result;private ImageView main_iv_image;Overrideprotected void onCreate(Bundle savedInstanceState) {super.onCreate(savedInstanceState);// 设置布局文件setContentView(R.layout.activity_main);// 检查并请求应用所需权限checkPermission();// 获取控件对象initView();// 设置控件的监听器setListener();}private void setListener() {// 设置识别按钮的监听器main_bt_recognize.setOnClickListener(new View.OnClickListener() {Overridepublic void onClick(View view) {// 识别之前需要再次检查一遍权限checkPermission();// 点击后的主程序mainProgram();}});}// 获得界面需要交互的控件private void initView() {main_bt_recognize findViewById(R.id.main_bt_recognize);main_tv_result findViewById(R.id.main_tv_result);main_iv_image findViewById(R.id.main_iv_image);}// 检查应用所需的权限如不满足则发出权限请求private void checkPermission() {if (ContextCompat.checkSelfPermission(getApplicationContext(),Manifest.permission.READ_EXTERNAL_STORAGE) ! PackageManager.PERMISSION_GRANTED) {ActivityCompat.requestPermissions(MainActivity.this,new String[]{Manifest.permission.READ_EXTERNAL_STORAGE}, 120);}if (ContextCompat.checkSelfPermission(getApplicationContext(),Manifest.permission.WRITE_EXTERNAL_STORAGE) ! PackageManager.PERMISSION_GRANTED) {ActivityCompat.requestPermissions(MainActivity.this,new String[]{Manifest.permission.WRITE_EXTERNAL_STORAGE}, 121);}}// OCR识别的主程序private void mainProgram() {// 从assets中获取一张Bitmap图片Bitmap bitmap getBitmapFromAssets(MainActivity.this, TARGET_FILENAME);// 同时显示在界面main_iv_image.setImageBitmap(bitmap);if (bitmap ! null) {// 准备工作创建路径和Tesserect的数据prepareTess();// 初始化TesserectTessBaseAPI tessBaseAPI new TessBaseAPI();String dataPath getExternalFilesDir(/).getPath() /;tessBaseAPI.init(dataPath, eng);// 识别并显示结果String result getOCRResult(tessBaseAPI, bitmap);main_tv_result.setText(result);}}// 从assets中读取一张Bitmap类型的图片private Bitmap getBitmapFromAssets(Context context, String filename) {Bitmap bitmap null;AssetManager assetManager context.getAssets();try {InputStream is assetManager.open(filename);bitmap BitmapFactory.decodeStream(is);is.close();Log.i(TAG, 图片读取成功。);Toast.makeText(getApplicationContext(), 图片读取成功。, Toast.LENGTH_SHORT).show();} catch (IOException e) {Log.i(TAG, 图片读取失败。);Toast.makeText(getApplicationContext(), 图片读取失败。, Toast.LENGTH_SHORT).show();e.printStackTrace();}return bitmap;}// 为Tesserect复制(从assets中复制过去)所需的数据private void prepareTess() {try{// 先创建必须的目录File dir getExternalFilesDir(TESS_DATA);if(!dir.exists()){if (!dir.mkdir()) {Toast.makeText(getApplicationContext(), 目录 dir.getPath() 没有创建成功, Toast.LENGTH_SHORT).show();}}// 从assets中复制必须的数据String pathToDataFile dir / DATA_FILENAME;if (!(new File(pathToDataFile)).exists()) {InputStream in getAssets().open(DATA_FILENAME);OutputStream out new FileOutputStream(pathToDataFile);byte[] buff new byte[1024];int len;while ((len in.read(buff)) 0) {out.write(buff, 0, len);}in.close();out.close();}} catch (Exception e) {Log.e(TAG, e.getMessage());}}// 进行OCR并返回识别结果private String getOCRResult(TessBaseAPI tessBaseAPI, Bitmap bitmap) {tessBaseAPI.setImage(bitmap);String result -;try{result tessBaseAPI.getUTF8Text();}catch (Exception e){Log.e(TAG, e.getMessage());}tessBaseAPI.end();return result;}
} layout_main.xml
?xml version1.0 encodingutf-8?
LinearLayout xmlns:androidhttp://schemas.android.com/apk/res/androidxmlns:apphttp://schemas.android.com/apk/res-autoxmlns:toolshttp://schemas.android.com/toolsandroid:layout_widthmatch_parentandroid:layout_heightmatch_parenttools:context.MainActivityScrollViewandroid:layout_widthmatch_parentandroid:layout_heightmatch_parentLinearLayoutandroid:layout_widthmatch_parentandroid:layout_heightwrap_contentandroid:orientationvertical ImageViewandroid:idid/main_iv_imageandroid:layout_widthmatch_parentandroid:layout_heightwrap_contentandroid:layout_gravitycenter_horizontalandroid:layout_marginLeft5dpandroid:layout_marginRight5dp/Buttonandroid:idid/main_bt_recognizeandroid:layout_widthmatch_parentandroid:layout_heightwrap_contentandroid:layout_marginLeft5dpandroid:layout_marginRight5dpandroid:layout_gravitycenter_horizontalandroid:text读取一张图片并识别 /TextViewandroid:layout_widthmatch_parentandroid:layout_heightwrap_contentandroid:layout_marginLeft5dpandroid:layout_marginRight5dpandroid:layout_gravitycenter_horizontalandroid:text识别结果 /TextViewandroid:idid/main_tv_resultandroid:layout_widthmatch_parentandroid:layout_heightwrap_contentandroid:layout_marginLeft5dpandroid:layout_marginRight5dpandroid:layout_gravitycenter_horizontal //LinearLayout/ScrollView
/LinearLayout AndroidManifest.xml
?xml version1.0 encodingutf-8?
manifest xmlns:androidhttp://schemas.android.com/apk/res/androidpackagecom.cs.ocrdemo4csdnuses-permission android:nameandroid.permission.READ_EXTERNAL_STORAGE /uses-permission android:nameandroid.permission.WRITE_EXTERNAL_STORAGE /applicationandroid:allowBackuptrueandroid:iconmipmap/ic_launcherandroid:labelstring/app_nameandroid:roundIconmipmap/ic_launcher_roundandroid:supportsRtltrueandroid:themestyle/Theme.OCRDemo4CSDNactivityandroid:name.MainActivityandroid:exportedtrueintent-filteraction android:nameandroid.intent.action.MAIN /category android:nameandroid.intent.category.LAUNCHER //intent-filter/activity/application
/manifest build.gradle(Module)
plugins {id com.android.application
}android {compileSdk 34defaultConfig {applicationId com.cs.ocrdemo4csdnminSdk 21targetSdk 34versionCode 1versionName 1.0testInstrumentationRunner androidx.test.runner.AndroidJUnitRunner}buildTypes {release {minifyEnabled falseproguardFiles getDefaultProguardFile(proguard-android-optimize.txt), proguard-rules.pro}}compileOptions {sourceCompatibility JavaVersion.VERSION_1_8targetCompatibility JavaVersion.VERSION_1_8}
}dependencies {implementation androidx.appcompat:appcompat:1.2.0implementation com.google.android.material:material:1.3.0implementation androidx.constraintlayout:constraintlayout:2.0.4testImplementation junit:junit:4.androidTestImplementation androidx.test.ext:junit:1.1.2androidTestImplementation androidx.test.espresso:espresso-core:3.3.0implementation com.rmtheis:tess-two:9.1.0
} vin_demo.png 随便从网上下的图片(保证存在光学字符即可)。 eng.traineddata 从https://github.com/tesseract-ocr/下载的如果不行从https://github.com/raykibul/Android-OCR-Testing/tree/main下载。 三、参考资料 1、光学字符识别 2、GitHub - tesseract-ocr/tesseract 3、GitHub - raykibul/Android-OCR-Testing 四、总结语 1、跟着别人的CSDN博客捣鼓了一天多但是没能调通一直在报错比如遇到“Could not initialize Tesseract API with languageeng”、“getUTF8Text导致android tesseract崩溃”等等问题。后边看了GitHub上边比较新的代码(诸位如果代码参考了我的博客还是没能调通建议看看这份代码)然后就跑通了。目前还不知道原因是啥。 2、我看Tesseract这个库的识别结果并不是十分准确尤其是对于拍照出来的结果识别率很低再从这个库的发展历史来看好像现在都没有什么人再维护它了(最后的维护者是谷歌而且停留在2018年)所以对于现在(今年是2023年)而言我感觉它已经有点属于是过时技术。大家可以寻求一些比较新的技术方案毕竟现在大模型都搞得这么牛了OCR这种应该搞得更好才是。