前言
年关扫福的号角一吹响,日常社交用语里就多了一句:你有敬业福嘛?今年是集五福的第6年,这场搭载手机的年味仪式,让古早的“福”文化又登上新时代的C位。
不难发现,我们拿着手机,不管面对的是笔端纤细的手写福,还是电子屏幕上五花八门的花体福,“扫福”功能都能轻易识别。那么,是什么技术实现扫福,又让扫福得以如此简单易操作,本文试着对扫福进行一次技术详解,看完这篇,没准你的app也能来一次“万物皆可扫”的有趣活动。
“AR扫福”技术解读
1、OCR原理
“AR扫福”加持的第一个技术是光学字符识别技术(Optical Character Recognition, OCR),手机等电子设备扫描任意载体上较为清晰的字符,通过对字符明暗的检测确定其形状,再通过字符形状识别翻译输出对应的文字。
常见的OCR应用
如今OCR技术已经深入生活的诸多方面。例如,身份证、护照、车牌号等证件识别,纸质文档扫描识别,时下一些在线答题的学习软件也凭借OCR实现了拍照搜题功能。
OCR的技术路线
预处理环节的五大“门神”
(1)灰度化
字符输入设备后,在预处理环节,首先经过“灰度化”处理,降低复杂背景环境的干扰,只保留敏感度信息的图片。灰度化满足的公式一般为:Gray=0.299R+0.587G+0.114B
(2)二值化
图片灰度化后进行“二值化”做进一步背景简化,环节将图片简化为非黑即白的前景信息和背景信息,前景信息是需要读取的信息为为黑色,背景信息为白色。
(3)降噪
要完成更精确的识别还需要对图片进行降噪处理。图像噪声是指存在于图像数据中的不必要的或多余的干扰信息,图像噪声的来源在图像获取和传递过程中收到传感器材质、工作环境以及传输介质等的各种影响,都会产生。二值化后的字符周围小黑点越多图片噪声越大,影响字符的精确切割。所以二值化后再进行图片降噪成为必要。
(4)倾斜矫正
降噪处理后,为了方便后续的字符切割,还要进行一道倾斜校正的工序,即将歪斜的图片以字符的公正排布进行图片矫正。霍夫变换时最常用的矫正方法,基于二值图片进行直线检测,基本原理在于利用点与线的对偶性,将断续的字符连城一条直线,在进行直线水平矫正。
(5)字符切割
经过重重筛选,最后筛出具有明确清晰字符的图片,就可进行行切分和字符切分。为下一步字符识别和翻译输出做准备。
字符识别和翻译
以上一顿操作,提取出真实需要的内容,处理清晰化的字符再与模板库进行匹配,输出匹配结果。
2、用ML机器学习实现“扫福”功能
华为机器学习服务(HUAWEI ML Kit)提供文本识别能力,利用OCR技术,将拍摄到的文字提取出来,转换为文本信息。除了简体中文,该能力还支持在手机端识别日文、韩文、英文、西班牙文、葡萄牙文、意大利文、德文、法文和俄文,下面我们就来看看如何简单地实现这一强大功能。
在开始开发前,需要先配置HMS Core的Maven仓地址,具体可以参考:配置Maven仓地址
之后将文本识别的基础SDK包和语言包添加到依赖中。
-
dependencies{
-
……
-
// 引入基础SDK
-
implementation
'com.huawei.hms:ml-computer-vision-ocr:2.0.5.300'
-
// 引入中英文文字识别模型包
-
implementation
'com.huawei.hms:ml-computer-vision-ocr-cn-model:2.0.5.300'
-
……
-
}
为了实现实时根据拍摄到的画面进行文字识别,我们选用ML Kit的端侧视频流文本识别能力,首先创建并初始化一个LensEngine对象
-
private LensEngine lensEngine =
null;
-
private void createLensEngine() {
-
if (
this.lensEngine ==
null) {
-
this.lensEngine = new LensEngine(
this,
this.cameraConfiguration,
this.graphicOverlay);
-
}
-
try {
-
this.lensEngine.setMachineLearningFrameTransactor(
this.localTextTransactor);
-
isInitialization =
true;
-
}
catch (Exception e) {
-
Toast.makeText(
-
this,
-
"Can not create image transactor: " + e.getMessage(),
-
Toast.LENGTH_LONG)
-
.show();
-
}
-
}
接下来创建文本识别的处理类“LocalTextTransactor”,继承BaseTransactor<MLText>接口
public class LocalTextTransactor extends BaseTransactor<MLText>
在其中的LocalTextTransactor方法中,创建一个MLTextAnalyzer文本分析器,并且将识别的语种设置为中文“zh”
-
MLLocalTextSetting
options = new MLLocalTextSetting.Factory()
-
.setOCRMode(MLLocalTextSetting.OCR_TRACKING_MODE)
-
.setLanguage(language)
-
.create();
-
MLTextAnalyzer
analyzer = MLAnalyzerFactory.getInstance().getLocalTextAnalyzer(options);
-
当获取到文本的识别结果之后,将识别到的字符打印显示到对应的位置
-
protected void onSuccess(
-
Bitmap originalCameraImage,
-
MLText results,
-
FrameMetadata frameMetadata,
-
GraphicOverlay graphicOverlay) {
-
this.mlText =results;
-
this.latestImageMetaData = frameMetadata;
-
graphicOverlay.clear();
-
List<MLText.Block> blocks = results.getBlocks();
-
if ((Build.VERSION.SDK_INT <= Build.VERSION_CODES.M) && originalCameraImage !=
null) {
-
CameraImageGraphic imageGraphic = new CameraImageGraphic(graphicOverlay, originalCameraImage);
-
graphicOverlay.addGraphic(imageGraphic);
-
}
-
if (blocks.size() >
0) {
-
this.mCount =
0;
-
this.mHandler.sendEmptyMessage(Constant.SHOW_TAKE_PHOTO_BUTTON);
-
}
else {
-
this.mCount++;
-
if (
this.mCount >
1) {
-
this.mHandler.sendEmptyMessage(Constant.HIDE_TAKE_PHOTO_BUTTON);
-
}
-
}
-
for (int i =
0; i < blocks.size(); i++) {
-
List<MLText.TextLine> lines = blocks.
get(i).getContents();
-
for (int j =
0; j < lines.size(); j++) {
-
// Display by line, without displaying empty lines.
-
if (lines.
get(j).getStringValue() !=
null && lines.
get(j).getStringValue().trim().length() !=
0) {
-
BaseGraphic textGraphic = new LocalTextGraphic(graphicOverlay,
-
lines.
get(j));
-
graphicOverlay.addGraphic(textGraphic);
-
}
-
}
-
}
-
graphicOverlay.postInvalidate();
-
}
调用LensEngine的run方法,启动相机读取视频流,即可进行识别
-
SurfaceView mSurfaceView = findViewById(R.id.surface_view);
-
try {
-
lensEngine.run(mSurfaceView.getHolder());
-
}
catch (IOException e) {
-
// 异常处理逻辑。
-
}
-
-
识别完成之后,停止分析器,释放对应的视频流资源
-
if (analyzer !=
null) {
-
try {
-
analyzer.stop();
-
}
catch (IOException e) {
-
// 异常处理。
-
}
-
}
-
if (lensEngine !=
null) {
-
lensEngine.release();
总结与思考
凭借OCR技术和华为机器学习能力,能轻易实现“扫福”,强大的功能带来的识别范围不止于“福”字,“万物皆可扫”也成为可能,如何更好地利用功能为运营加分,为增长蓄能,“扫福”已经做了一个不错的示范,更好的范例和成果等你去大胆实践。
>>访问华为开发者联盟官网,了解更多相关内容
>>获取开发指导文档
关注我们,第一时间了解华为移动服务最新技术资讯~
转载:https://blog.csdn.net/HUAWEI_HMSCore/article/details/113770425