转载请注明出处,本文地址:https://blog.csdn.net/Weiye__Lee/article/details/80952724

写在前面

  最近因为业务需要,要在Android端实现个扫描身份证识别其中文字的功能,网上溜达了一圈。
  Android比较推荐的是:
  GitHub:https://github.com/rmtheis/tess-two
  当然也有第三方提供的解决方案,比如百度提供的文字识别:http://ai.baidu.com/tech/ocr。
  咱做技术的还是先折腾折腾,特此记录下过程,也希望能帮助到同样折腾的人

效果图(名字打了马赛克)

过程

先理下要实现这样的效果,我们需要做些什么

  1. 在Android端需要自定义个含取景框的自定义相机
  2. 对拍摄的图片进行灰度化、二值化处理
  3. 引入tess-two 库,调用相应api将步骤2处理后的图片传入处理

1、自定义相机

  这一步主要是写个布局,使用Camera和SurfaceView做个自定义相机,具体实现可看demo代码,里面有个取景框是专门用来截取出我们关心的区域的

2、图片处理

  机器视觉分为三个阶段 : 图像转化、图像分析、图像理解。若要将一幅图像转化为方便分析理解的格式,有一个很关键的过程就是“图像二值化”。一幅图像能否分析理解的准确很大程度上来说取决于二值化(非黑即白)效果的好坏。而在二值化之前,有一个重要步骤,那便是“图像灰度化”

  所以,先将图片灰度化,这里有个公式:f(x) = R*0.3+G*0.51+B*0.11,实际需要做的就是将图片的每个像素(这里假定android里用ARGB表示一个像素点)的red、green、blue取出并代入此公式算出每个点的灰度值,这样便实现了灰度化
  
  再来看看二值化,二值化的原理就是取一个阈值,然后将每个像素点的灰度值和这个阈值进行比较,如果大于阈值则定为白色,反之为黑色(这里假定要识别的图像是白底黑字),如此一来便实现了二值化。可以看到,最重要的是这个阈值,该怎么取值才合理,最简单的阈值取定便是取整幅图画的均值了:
  
  效果看上去还不错,实际上用到身份证识别或文字识别上,受阴影等因素的影响,效果就差很多了,因此,优化算法还是很有必要的,网上流传着多种二值化算阈值的算法,这里目前尝试了以下几种:
   
1. 阈值迭代算法(效果不理想,字体的笔画容易站在一起,阴影影响大)
  https://www.cnblogs.com/gxclmx/p/6916515.html
  
2. 基于Otsu阈值二值化(跟上面的迭代算法效果差不多,阴影影响大)
  https://blog.csdn.net/mao0514/article/details/47041597
  
3. 矩阵二值化算法
  https://blog.csdn.net/lj501886285/article/details/52425157
  这个算法的阈值是自适应的,对于每个像素点都构造了一个小矩阵来衡量阈值的取值,也就是说每个点都跟它周围的细节相关,这样比起用单一的整体阈值去衡量每个点,显然更具说服力。而事实证明,这个算法应用后的二值化测试效果确实杠杠的
  

3、tess-two api识别

  这一步就比较简单了,直接上步骤:
1. 引入依赖

dependencies {implementation 'com.rmtheis:tess-two:9.0.0'
}
  1. 调用api识别
TessBaseAPI tessBaseAPI = new TessBaseAPI();
tessBaseAPI.init(DATAPATH, "chi_sim");//传入训练文件目录和训练文件
tessBaseAPI.setImage(bitmap);
String text = tessBaseAPI.getUTF8Text();    

  就这样短短4行代码便可识别出文字了,这里有个坑要注意,看下tessBaseAPI.init这个方法源码:

public boolean init(String datapath, String language) {return init(datapath, language, OEM_DEFAULT);}

可以看到又调用了另一个init方法

 public boolean init(String datapath, String language, @OcrEngineMode int ocrEngineMode) {if (datapath == null)throw new IllegalArgumentException("Data path must not be null!");if (!datapath.endsWith(File.separator))datapath += File.separator;File datapathFile = new File(datapath);if (!datapathFile.exists())throw new IllegalArgumentException("Data path does not exist!");File tessdata = new File(datapath + "tessdata");if (!tessdata.exists() || !tessdata.isDirectory())throw new IllegalArgumentException("Data path must contain subfolder tessdata!");//noinspection deprecationif (ocrEngineMode != OEM_CUBE_ONLY) {for (String languageCode : language.split("\\+")) {if (!languageCode.startsWith("~")) {File datafile = new File(tessdata + File.separator + languageCode + ".traineddata");if (!datafile.exists())throw new IllegalArgumentException("Data file not found at " + datafile);// Catch some common problematic initialization cases.if (languageCode.equals("ara") || (languageCode.equals("hin") &&ocrEngineMode == OEM_DEFAULT)) {boolean sampleCubeFileExists = new File(tessdata +File.separator + languageCode + ".cube.params").exists();if (!sampleCubeFileExists) {throw new IllegalArgumentException("Cube data files not found." +" See https://github.com/rmtheis/tess-two/issues/239");}}}}}boolean success = nativeInitOem(mNativeData, datapath, language, ocrEngineMode);if (success) {mRecycled = false;}return success;}

这里注意下面这一段代码,api要求DATAPATH目录下,必须有tessdata这样一个子目录,也就是说,训练文件必须放在这个子目录下

File tessdata = new File(datapath + "tessdata");if (!tessdata.exists() || !tessdata.isDirectory())throw new IllegalArgumentException("Data path must contain subfolder tessdata!");

  一个文字识别的demo就此完成了,稍后会传上demo到github,demo做的是身份证,所以对图片的截取处理是针对身份证的,当然也可应用到其他营业执照啥的了。
  最后,在查资料的时候发现一个身份证识别demo:IdCardReconition,处理效果挺快,效果也蛮不错的,但是查看代码后发现处理都是在so文件里并且处理貌似只针对身份证,也不清楚是怎么做的,有了解的望告知

附上github:TextOcrExample

待完善

  1. 图像处理的算法是有待完善的,特别是速度上
  2. tess-two api识别的速度上,也可考虑针对特定场景定制训练文件,这样速度上也会有所提升
  3. 去除噪点

PS:对于速度上的要求,个人觉得可以在网络畅通的情况下,采用上传图片到服务器去处理,然后再反馈回给客户端。在服务端可做的事就多了,单台服务器计算资源就好过手机太多,况且我们还可以做分布式并发处理呢?速度相信是杠杠的,像百度这些第三方一般也是提供服务上传图片来识别的,速度那是相当快。最后感谢阅读,如果有什么不对的望大神指正,喜欢就star一下呗,谢谢!

参考

  1. tesseract ocr训练样本库 识别字库
  2. tess-two

Android基于tess-two的离线身份证等图片文字识别相关推荐

  1. Android基于虹软SDK实现离线人脸识别

    一.需求 Android端实现离线人脸识别功能,即对比两张人脸是否是同一个人. 二.解决方案 选用虹软人脸识别SDK来实现人脸特征数据比对. 三.步骤 1. 打开虹软开发者中心 开发者中心 2. 新建 ...

  2. 【数字图像处理课程设计】基于非深度学习方法实现身份证定位与正反面识别

    文章目录 基于透视矫正与区域特征匹配的身份证图像定位与正反面识别 摘要 实现细节 1.总体流程 2.前景背景分割 3.身份证角点定位 4.透视变换 5.模板匹配 5.1 基于区域颜色匹配的国徽检测 5 ...

  3. Android 图片文字识别DEMO(基于百度OCR)

    前言   OCR 是 Optical Character Recognition 的缩写,翻译为光学字符识别,指的是针对印刷体字符,采用光学的方式将纸质文档中的文字转换成为黑白点阵的图像文件,通过识别 ...

  4. 二维码/条码识别、身份证识别、银行卡识别、车牌识别、图片文字识别、黄图识别、驾驶证(驾照)识别

    Scanner 项目地址:shouzhong/Scanner 简介: 二维码/条码识别.身份证识别.银行卡识别.车牌识别.图片文字识别.黄图识别.驾驶证(驾照)识别 更多:作者   提 Bug 标签: ...

  5. 身份证、银行卡、车牌、图片文字识别、黄图识别、驾驶证识别库实现功能

    预览图效果: 原文来自:http://code.662p.com/view/19388.html  ,需要自己去下载就可以了. 使用 依赖 implementation 'com.shouzhong: ...

  6. Android集成百度OCR图片文字识别——总结

    近期由于工作内容的需要,我要给项目集成一个图片文字识别功能,据说百度的不错,所以今天写一个关于百度OCR的集成总结,以便以后再次使用不用去看官方文档. 首先肯定是要在百度管理平台注册账号并登录,然后照 ...

  7. Android图片文字识别(阿里OCR接口)

    最近使用了阿里云的OCR文字识别API 先来看看效果 我使用的是通用类文字识别,具体实现过程如下: 1.购买阿里云的通用类文字识别 目前是0元免费的,可以使用500次.购买成功后到->控制台-& ...

  8. 【基于pytesseract进行图片文字识别】

    基于pytesseract进行图片文字识别 前言 一.模块pytesseract实现图片文字OCR识别过程 1.了解 2.下载 3.后续添加语言 4.下载相应的库 二.使用步骤 总结 前言 我有一个图 ...

  9. 基于PaddleOCR开发uni-app离线身份证识别插件

    目录 目的 准备工作 1.HbuilderX 2.Android Studio 并配置 NDK 3.基于PaddleOCR的离线身份证识别插件 开始 1.在android sudio创建一个项目,并创 ...

最新文章

  1. oracle ORA-01113的解决方法(file 1 needs media recovery)
  2. 16、用VS2005调试编译驱动程序
  3. Python去线性化趋势
  4. 云计算是怎样入侵统一通信领域的
  5. python382怎么用_用python做UDP连接
  6. linq 分组求和的一般方法
  7. Makefile 的 遗漏分隔符错误信息
  8. datasnap ajax jsonp,有没有办法在Delphi DataSnap REST服务器上使用JSONP?
  9. Python字典类型内部做判断赋值
  10. ny 2 括号配对问题
  11. shell脚本:监控MySQL服务是否正常
  12. 能自动生成标注的APP,尝试一下吧
  13. 什么是网站被黑,如何处理网站被黑?
  14. 典型用户和用户场景描述
  15. 【兴趣】无需电和油的水锤泵的抽水方式
  16. IBM云对象存储Cleversafe 大力拓展全新战场
  17. 千万别在微社区太投入
  18. 速记计算机键盘,键盘字母排列的速记公式
  19. iphone、ipad屏幕分辨率
  20. PHP数组转字符串与PHP字符串转数组的相关方法解析

热门文章

  1. 十六进制颜色码转换成RGB颜色值:
  2. android自定义视频列表,Android仿京东天猫列表页播视频看这一篇就足够了
  3. 微信小程序-图片上传
  4. matlab function_Matlab绘制地图
  5. Mac 终端连接数据库
  6. python在excel中插入二维码
  7. Spring Security新版配置
  8. 面试官问我为啥B+树一般都不超过3层?3层B+树能存多少数据?redo log与binlog的两阶段提交?
  9. GEE:净初级生产量(NPP)数据下载(每月/每年)
  10. 【Python】uiautomation+openai构建基于chatGPT的微信聊天机器人