在安卓中使用Firebase ML Kit实现中文OCR识别功能
一、前言
1.什么是Firebase
Firebase是由Google提供的实时全方位的移动后端云服务平台,这是一个主要功能都基于云端的服务平台,其提供多项远程功能如:远程数据库、认证、云存储、云函数;同样也提供一些本地功能如:本地数据库,性能检测,崩溃策略。本文提到的MLkit也是其提供的本地客户端功能之一
2.什么是ML Kit
ML Kit是谷歌官方提供的一款机器学习 SDK,同样的也提供了“设备端”和“云端”两种API。它包含了一系列预训练模型,提供诸如文字/人脸/条码识别、图像标注、智能回复等功能,帮助开发者在移动端上快速添加机器学习功能
二、基础准备
在开发中加入ML Kit需要我们已有一个安卓项目(可以是空项目,也可以是已有内容的项目),用于绑定至Firebase的云项目中,绑定方式可以查看谷歌官方给出的文档:
如何将Firebase依赖添加至安卓项目中
在Firebase中注册应用包的过程:

注册好之后按照步骤,添加对应的依赖重新构建项目即可
三、实现过程
1.布局实现
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:id="@+id/main"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:orientation="vertical"
tools:context=".MainActivity">
<ImageView
android:id="@+id/image_view"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"/>
<Button
android:id="@+id/btn_capture"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/get_image"/>
<TextView
android:id="@+id/text_result"
android:layout_width="match_parent"
android:layout_height="0dp"
android:layout_weight="1"
android:text="@string/ocr_result"/>
</LinearLayout>
这里总共涉及三个部件:
显示图片的视图,可以用于绑定拍摄后获得的照片,也可以用于后续丰富扩展内容,比如通过相册选取图片进行识别时,获得更好的用户交互体验;
拍摄图片的按钮,单击这个按钮将会触发获取照相机权限的逻辑,进入拍照界面
显示识别出文字的文本内容,如果没有识别出文字将不作更改
布局的实现效果:

2.逻辑实现
预先定义的常量以及预先定义的对象
//调用拍照功能的请求码
private static final int REQUEST_IMAGE_CAPTURE = 1;
//调用相机权限的请求码
private static final int CAMERA_PERMISSION_REQUEST_CODE = 2;
private ImageView imageView;
private TextView textViewResult;
添加相机权限至AndroidManifest.xml:
<uses-permission android:name="android.permission.CAMERA" />
<uses-feature android:name="android.hardware.camera" android:required="true" />
在onCreate中绑定唤起照相机的监听器,这里先判断是否已获得相机权限Manifest.permission.CAMERA如果没有权限,则请求相机权限 ActivityCompat.requestPermissions如果已有权限,则直接调用 dispatchTakePictureIntent() 方法通过intent挨唤起拍照程序
btnCapture.setOnClickListener(v -> {
if (ContextCompat.checkSelfPermission(this, Manifest.permission.CAMERA)
!= PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(this,
new String[]{Manifest.permission.CAMERA},
CAMERA_PERMISSION_REQUEST_CODE);
} else {
dispatchTakePictureIntent();
}
});
这是第一次得到权限请求时,进行的处理,此时我们的虚拟机上会弹出一个请示框,提示我们这个app申请打开xx应用或者内容(我在实现到这里第一反应就是万恶的摇一摇广告跳转app,或许我们也可以不用弹窗直接通过请求?):
@Override
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
if (requestCode == CAMERA_PERMISSION_REQUEST_CODE) {
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
dispatchTakePictureIntent();
}
}
}
自定义的dispatchTakePictureIntent()函数,我们在这里唤起照相机
private void dispatchTakePictureIntent() {
Intent takePictureIntent = new Intent(MediaStore.ACTION_IMAGE_CAPTURE);
if (takePictureIntent.resolveActivity(getPackageManager()) != null) {
startActivityForResult(takePictureIntent, REQUEST_IMAGE_CAPTURE);
}
}
重写onActivityResult()函数,当用户拍完照片从照相机返回至app时触发,并且进行检测,当请求码为我们定义的REQUEST_IMAGE_CAPTURE、返回码为RESULT_OK时,说明拍照被调用成功并且我们成功获取到了拍照返回的照片;我们只需要从intent中提取出照片,在调用关键函数recognizeTextFromImage()进行识别即可实现功能
@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
super.onActivityResult(requestCode, resultCode, data);
if (requestCode == REQUEST_IMAGE_CAPTURE && resultCode == RESULT_OK) {
Bundle extras = data.getExtras();
Bitmap imageBitmap = (Bitmap) extras.get("data");
imageView.setImageBitmap(imageBitmap);
recognizeTextFromImage(imageBitmap);
}
}
这是上文提到的关键函数recognizeTextFromImage(),我们使用它来完成中文的识别,这里使用ML Kit提供的中文识别器ChineseTextRecognizerOptions创建了一个Builder来拼接从照片中识别出的文字,并且添加了两个监听器,当识别成功时,输出识别的内容(什么都没识别到也是识别成功,如果想要完善这个部分可以新增一个空值判断,当识别到的text为空时,可以输出提示);失败时则会输出失败信息
private void recognizeTextFromImage(Bitmap bitmap) {
InputImage image = InputImage.fromBitmap(bitmap, 0);
TextRecognition.getClient(new ChineseTextRecognizerOptions.Builder().build())
.process(image)
.addOnSuccessListener(text -> {
textViewResult.setText(text.getText());
})
.addOnFailureListener(e -> {
textViewResult.setText("Failed to recognize text: " + e.getMessage());
});
}
识别效果(调用的虚拟机照相机,所以拍出来的图片也是虚拟的,图中不存在任何文字,所以按钮下方也没有任何文本):

四、扩展
基本功能的实现在前文都已经有提及,但是这显然很粗糙,我们可以对其进行更多的完善,这边可以给出一些完善举例
扩展案例:添加通过相册选取图片
想要通过相册来选取图片进行识别,就要添加新的逻辑。我们一样先添加两个用于满足该功能的常量:
private static final int PICK_IMAGE_REQUEST = 3;
private static final int READ_EXTERNAL_STORAGE_REQUEST_CODE = 4;
添加相册权限:
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
添加唤起相册的按钮:
<Button
android:id="@+id/btn_gallery"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="@string/open_gallery"/>
绑定按钮的唤起逻辑,添加监听器,当请求码满足对应条件时(条件类似于前文,满足对应的常量即可),调用openGallery()函数:
Button btnGallery = findViewById(R.id.btn_gallery);
btnGallery.setOnClickListener(v -> {
if (ContextCompat.checkSelfPermission(this, Manifest.permission.READ_EXTERNAL_STORAGE)
!= PackageManager.PERMISSION_GRANTED) {
ActivityCompat.requestPermissions(this,
new String[]{Manifest.permission.READ_EXTERNAL_STORAGE},
READ_EXTERNAL_STORAGE_REQUEST_CODE);
} else {
openGallery();
}
});
打开相册的openGallery()方法,一样是通过intent来打开:
private void openGallery() {
Intent intent = new Intent(Intent.ACTION_PICK, MediaStore.Images.Media.EXTERNAL_CONTENT_URI);
startActivityForResult(intent, PICK_IMAGE_REQUEST);
}
在onActivityResult()函数中添加新的判断条件,当得到的请求为PICK_IMAGE_REQUEST(即打开相册的请求)时,执行下面的逻辑来通过intent得到从相册中选取到的图片进行识别:
try {
android.net.Uri imageUri = data.getData();
Bitmap bitmap = MediaStore.Images.Media.getBitmap(this.getContentResolver(), imageUri);
imageView.setImageBitmap(bitmap);
recognizeTextFromImage(bitmap);
} catch (Exception e) {
textViewResult.setText("Error loading image: " + e.getMessage());
}
在onRequestPermissionsResult()函数中补充首次请求的逻辑,if判断的条件逻辑跟之前的类似,更换对应的常量即可:
if (grantResults.length > 0 && grantResults[0] == PackageManager.PERMISSION_GRANTED) {
openGallery();
}
最终实现的通过相册选取效果,选择了照片之后识别效果是一样的:

五、总结
本文提供了作者使用Firebase中的ML Kit实现对图片进行中文识别的功能的一些思路与过程,在当今的ai热潮下,使用这个已经集成的模块并不困难;所以我在文中还添加了一份简单的扩展,当然,这个功能还能集成到其他app内,这需要一定的想象力和创造力,正是当前的ai所做不到的事情;好好的发挥自己的创造力才能不被淹没在现在这个ai时代的浪潮中
作者:吴鑫
原文链接:在安卓中使用Firebase ML Kit实现中文OCR识别功能
更多推荐
所有评论(0)