AndroidStudio使用百度SDK完成OCR文字识别

阅读: 评论:0

AndroidStudio使用百度SDK完成OCR文字识别

AndroidStudio使用百度SDK完成OCR文字识别

前言

OCR 是 Optical Character Recognition 的缩写,翻译为光学字符识别,指的是针对印刷体字符,采用光学的方式将纸质文档中的文字转换成为黑白点阵的图像文件,通过识别软件将图像中的文字转换成文本格式,供文字处理软件进一步编辑加工的技术(当然,这是我抄别人的原话)。

先安利一下百度智能云,有大佬建好的轮子,咱们申请一下就可以用了,审核很快。当然也可以使用腾讯云和阿里云。

接入百度SDK

申请免费试用之后(当然要申请免费的,学习成本低),下载(下载地址)解压,会有这样的文件夹:

百度老哥已经给我们详细的提示了,这里可以了解下各个包的用法,简单过一下。如果不需要使用百度给的UI的话,只导入libs下的文件到项目中的lib中就可以了,其中libs中有四个文件夹和一个jar包,四个文件夹中是so文件,导入so文件看这里。

在adle中的android下面添加sourceSets {main {jniLibs.srcDirs= ['libs']}}加上这串代码,就可以实现将module下libs中的so一起打包到apk中。


如果你想导入UI包怎么办?百度的4已经告诉大家最好的方法是以模块方式导入,这里也介绍一下模块方式导入。

接下来选择对应的文件夹就行了,当然没那么简单,下面还需要在主工程下引入进去。
在adle文件的dependencies里加入
implementation project(path: ‘:ocr_ui’)
在adle下加入
include ‘:app’, ':ocr_ui’
这样就导入模块成功了。

代码部分

我是采用了导入明文ak,sk的方式,UI我也导入了,但是相机那里出了问题,还不能使用。大家可以自己写个启动相机获取图片的方法,因为还需要用到provider的关系,我并没有使用,而是直接从图库选择图片这种方便的形式,有兴趣的童鞋可以自己补上拍照的方式。

package st;import androidx.appcompat.app.AppCompatActivity;t.Intent;
import android.os.Bundle;
import android.os.Looper;
import android.view.View;
import android.widget.Toast;
import sdk.OCR;
import sdk.OnResultListener;
import ption.OCRError;
import del.AccessToken;public class MainActivity extends AppCompatActivity {private boolean hasGotToken = false;@Overrideprotected void onCreate(Bundle savedInstanceState) {Create(savedInstanceState);setContentView(R.layout.activity_main);initAccessTokenWithAkSk();findViewById(R.id.btn_simple_text).setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View view) {if (!checkTokenStatus()) {return;}Intent intent = new Intent(MainActivity.this, SimpleTextActivity.class);startActivity(intent);}});}private boolean checkTokenStatus() {if (!hasGotToken) {Toast.makeText(getApplicationContext(), "token未获取到", Toast.LENGTH_SHORT).show();}return hasGotToken;}/*** 使用明文方式初始化token*/private void initAccessTokenWithAkSk() {Instance(this).initAccessTokenWithAkSk(new OnResultListener<AccessToken>() {@Overridepublic void onResult(AccessToken accessToken) {String token = AccessToken();hasGotToken = true;}@Overridepublic void onError(OCRError error) {error.printStackTrace();Looper.prepare();Toast.makeText(MainActivity.this, "token获取失败.........", Toast.LENGTH_SHORT).show();}}, this, "此处应该填你的AK", "你的SK");}
}

主页面现在只写了一个按钮,普通文本识别按钮,因为初步只完成了这个,后续有空我会把其他的识别都加上,毕竟百度送的免费的30天不用可就浪费了。initAccessTokenWithAkSk方法进行token通行证的确认ak和sk大家可以在百度控制台那里获取,和使用其他sdk一样都会创建应用,获取明文密钥的。

package st;import androidx.appcompat.app.AppCompatActivity;
app.ActivityCompat;
import android.Manifest;
import android.app.Activity;
import android.app.AlertDialog;
t.Intent;
t.pm.PackageManager;
import android.database.Cursor;
import android.Uri;
import android.os.Bundle;
import android.provider.MediaStore;
TextUtils;
import android.view.View;
import android.widget.TextView;
import sdk.OCR;
import sdk.OnResultListener;
import ption.OCRError;
import del.GeneralBasicParams;
import del.GeneralResult;
import del.WordSimple;
import ui.camera.CameraActivity;
import ui.camera.CameraNativeHelper;
import ui.camera.CameraView;import java.io.File;
import java.util.List;public class SimpleTextActivity extends AppCompatActivity {private static final int REQUEST_CODE_CAMERA = 102;private int REQUEST_CODE_ALBUM = 2;private int REQUEST_ENHANCED_CODE_ALBUM = 3;private TextView infoTextView;private AlertDialog.Builder alertDialog;@Overrideprotected void onCreate(Bundle savedInstanceState) {Create(savedInstanceState);setContentView(R.layout.layout_simple_text);alertDialog = new AlertDialog.Builder(this);infoTextView = findViewById(R.id.info_text_view);CameraNativeHelper.init(this, Instance(this).getLicense(),new CameraNativeHelper.CameraNativeInitCallback() {@Overridepublic void onError(int errorCode, Throwable e) {String msg;switch (errorCode) {case CameraView.NATIVE_SOLOAD_FAIL:msg = "加载so失败,请确保apk中存在ui部分的so";break;case CameraView.NATIVE_AUTH_FAIL:msg = "授权本地质量控制token获取失败";break;case CameraView.NATIVE_INIT_FAIL:msg = "本地质量控制";break;default:msg = String.valueOf(errorCode);}infoTextView.setText("本地质量控制初始化错误,错误原因: " + msg);}});findViewById(R.id.take_a_photo).setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View view) {if (checkGalleryPermission()) {Intent intent = new Intent(SimpleTextActivity.this, CameraActivity.class);intent.putExtra(CameraActivity.KEY_OUTPUT_FILE_PATH, SaveFile(getApplication()).getAbsoluteFile());intent.putExtra(CameraActivity.KEY_CONTENT_TYPE, CameraActivity.CONTENT_TYPE_GENERAL);startActivityForResult(intent, REQUEST_CODE_CAMERA);}}});findViewById(R.id.select_a_photo).setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View view) {Intent intent = new Intent(Intent.ACTION_PICK, null);intent.setDataAndType(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, "image/*");startActivityForResult(intent, REQUEST_CODE_ALBUM);}});findViewById(hanced_photo).setOnClickListener(new View.OnClickListener() {@Overridepublic void onClick(View view) {Intent intent = new Intent(Intent.ACTION_PICK, null);intent.setDataAndType(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, "image/*");startActivityForResult(intent, REQUEST_ENHANCED_CODE_ALBUM);}});}/*** 文字普通识别* @param filePath*/private void recSimpleText(String filePath) {// 通用文字识别参数设置GeneralBasicParams param = new GeneralBasicParams();param.setDetectDirection(true);param.setImageFile(new File(filePath));// 调用通用文字识别服务Instance(this).recognizeGeneralBasic(param, new OnResultListener<GeneralResult>() {@Overridepublic void onResult(GeneralResult generalResult) {if (generalResult != null) {//alertText("", parseResultBean(generalResult));setInfoTextView(parseResultBean(generalResult));}}@Override public void onError(OCRError error) {// 调用失败,返回OCRError对象alertText("调用失败", Message());} });}/*** 文字高精度识别* @param filePath*/private void recEnhancedText(String filePath) {GeneralBasicParams params = new GeneralBasicParams();params.setDetectDirection(true);params.setImageFile(new File(filePath));Instance(this).recognizeAccurateBasic(params, new OnResultListener<GeneralResult>() {@Overridepublic void onResult(GeneralResult generalResult) {if (generalResult != null) {//alertText("", parseResultBean(generalResult));setInfoTextView(parseResultBean(generalResult));}}@Overridepublic void onError(OCRError ocrError) {// 调用失败,返回OCRError对象alertText("调用失败", Message());}});}/*** 解析返回结果* @param generalResult* @return*/private String parseResultBean(GeneralResult generalResult) {StringBuilder stringBuilder = new StringBuilder();List<?> list = WordList();for (Object o : list) {if (o instanceof WordSimple) {stringBuilder.append(((WordSimple) o).getWords());stringBuilder.append("nn");}}String();}/*** 检查是否有权限* @return*/private boolean checkGalleryPermission() {int ret = ActivityCompat.checkSelfPermission(SimpleTextActivity.this, Manifest.permission.READ_EXTERNAL_STORAGE);if (ret != PackageManager.PERMISSION_GRANTED) {questPermissions(SimpleTextActivity.this,new String[] {Manifest.permission.READ_EXTERNAL_STORAGE},1000);return false;}return true;}@Overrideprotected void onActivityResult(int requestCode, int resultCode, Intent data) {ActivityResult(requestCode, resultCode, data);if (requestCode == REQUEST_CODE_CAMERA && resultCode == Activity.RESULT_OK) {if (data != null) {String contentType = StringExtra(CameraActivity.KEY_CONTENT_TYPE);String filePath = SaveFile(getApplicationContext()).getAbsolutePath();if (!TextUtils.isEmpty(contentType)) {if (CameraActivity.CONTENT_TYPE_GENERAL.equals(contentType)) {recSimpleText(filePath);}}}}else if (requestCode == REQUEST_CODE_ALBUM) {// 从相册返回的数据if (data != null) {// 得到图片的全路径Uri uri = Data();recSimpleText(getRealPathFromURI(uri));}}else if (requestCode == REQUEST_ENHANCED_CODE_ALBUM) {// 从相册返回的数据if (data != null) {// 得到图片的全路径Uri uri = Data();recEnhancedText(getRealPathFromURI(uri));}}}/*** 错误弹窗* @param title* @param message*/private void alertText(final String title, final String message) {this.runOnUiThread(new Runnable() {@Overridepublic void run() {alertDialog.setTitle(title).setMessage(message).setPositiveButton("确定", null).show();}});}/*** 设置显示结果* @param text*/private void setInfoTextView(final String text) {runOnUiThread(new Runnable() {@Overridepublic void run() {infoTextView.setText(text);}});}/*** 将URI转化为string格式* @param contentURI* @return*/private String getRealPathFromURI(Uri contentURI) {String result;Cursor cursor = getContentResolver().query(contentURI, null, null, null, null);if (cursor == null) {// Source is Dropbox or other similar local file pathresult = Path();} else {veToFirst();int idx = ColumnIndex(MediaStore.Images.ImageColumns.DATA);result = String(idx);cursor.close();}return result;}@Overrideprotected void onDestroy() {// 释放本地质量控制模型lease();Destroy();}
}

这里面我也是仿照Demo写的,但是不一样的是我只是做了简单的文字识别,而且相机拍照emmm还是坏的。原因也是我了解了一下才知道拍照所需要的东西并不止这些,需要另外准备,为了先简单实现识别,这个拍照之后再做吧。方法的注释大概解释了每个方法的作用,其实并没有什么好说的,因为这都是根据百度API介绍写的最简单的,简单来说就是打开相册-获取图片地址-传到百度服务器-返回结果类,然后自己解析结果类里面的list即可。如果没有使用到UI的话,那也用不到CameraActivity之类的。目前我也没有使用。

结果

先来一个不是很清楚的渣手机拍照

昨晚的五杀拍照!你看文字还是识别的很准确的,但是带了符号之类的会影响识别。
百度sdk也说了 最好控制图片大小,因为就算太大的图片上传也会被压缩,影响质量。同时一个页面中的字数建议小于70个字,字数过多过密也会影响识别结果,当然这是高精度下的识别结果,你问我普通识别呢?这。。。普通识别下建议只用于截屏或者文档识别吧,要不然识别的内容惨不忍睹。

再来看看一个截屏下的识别结果:

我这算不算受到骚扰呢?报警可以吗?退订还没用呢0_0

自己完成了之后也不知道该怎么向别人讲述,如果代码片段中有不清楚的地方可以单独问我吼。

本文发布于:2024-02-03 00:49:22,感谢您对本站的认可!

本文链接:https://www.4u4v.net/it/170689256947565.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

标签:文字   AndroidStudio   SDK   OCR
留言与评论(共有 0 条评论)
   
验证码:

Copyright ©2019-2022 Comsenz Inc.Powered by ©

网站地图1 网站地图2 网站地图3 网站地图4 网站地图5 网站地图6 网站地图7 网站地图8 网站地图9 网站地图10 网站地图11 网站地图12 网站地图13 网站地图14 网站地图15 网站地图16 网站地图17 网站地图18 网站地图19 网站地图20 网站地图21 网站地图22/a> 网站地图23