前言:

前天领导问,类似扫描文件识别图中文字的功能如何实现,找一下第三方的开源库,尝试下,于是有了这篇文章;

分析:

识别场景中,识别身份证信息当属典型,查阅了几篇文章,后续的实现中也多导入了其代码;

【iOS身份证号码识别】

【图像识别技术(OCR)在iOS中的简单应用】

OpenCV:

OpenCV(开源计算机视觉库)是在BSD许可下发布的,因此对学术和商业使用都是免费的。它有c++、Python和Java接口,支持Windows、Linux、Mac OS、iOS和Android。OpenCV是为计算效率而设计的,并且非常注重实时应用。用优化的C/ c++编写的库可以利用多核处理。使用OpenCL,它可以利用底层异构计算平台的硬件加速。

OpenCV在全球范围内被采用,拥有超过4.7万的用户社区,估计下载量超过1400万。它用途广泛。

OCR:

OCR (Optical Character Recognition,光学字符识别)是指电子设备(例如扫描仪或数码相机)检查纸上打印的字符,通过检测暗、亮的模式确定其形状,然后用字符识别方法将形状翻译成计算机文字的过程;即,针对印刷体字符,采用光学的方式将纸质文档中的文字转换成为黑白点阵的图像文件,并通过识别软件将图像中的文字转换成文本格式,供文字处理软件进一步编辑加工的技术。如何除错或利用辅助信息提高识别正确率,是OCR最重要的课题,ICR(Intelligent Character Recognition)的名词也因此而产生。衡量一个OCR系统性能好坏的主要指标有:拒识率、误识率、识别速度、用户界面的友好性,产品的稳定性,易用性及可行性等。

TesseractOCR:

TesseractOCR是谷歌开源的一个OCR引擎,从github上下载Tesseract的工程和语言包(tessdata),TesseractOCR并没有自带语言包,如果要识别中文,还需要将中文包(名称:chi_sim.traineddata)导入到tessdata中。

下载:

OpenCV下载;

Tesseract OCR iOS下载;

项目实践:

新建项目IdentiferIDCard,编辑Podfile;

项目安装使用:

使用Cocoapods;安装等待的时间可能会很长;

Xcode编译前修改:


关于语言包:

tessdata 语言包下载;

这个语言包比较大,如果只需要中文的语言包可以只下载中文的;

字体训练中文包(版本匹配版);

遇到的各种问题及解决办法:(参考链接如下)

编译运行的两个错误是因为NO宏引起的 由于系统不支持 改为CNO即可;

【iOS实现图像文字识别功能】

【身份证识别】

为了图片更加可辨识,使用了一个第三方的剪裁图片库:

核心代码(摘录):

IdentifierIDCardManager.h

#import <Foundation/Foundation.h>
@class UIImage;typedef void (^CompleateBlock)(NSString *text);@interface IdentifierIDCardManager : NSObject/***  初始化一个单例**  @return 返回一个RecogizeCardManager的实例对象*/
+ (instancetype)recognizeCardManager;/***  根据身份证照片得到身份证号码**  @param cardImage 传入的身份证照片*  @param compleate 识别完成后的回调*/
- (void)recognizeCardWithImage:(UIImage *)cardImage compleate:(CompleateBlock)compleate;@end

IdentifierIDCardManager.mm

#import "IdentifierIDCardManager.h"#import <opencv2/opencv.hpp>
#import <opencv2/imgproc/types_c.h>
#import <opencv2/imgcodecs/ios.h>
#import <TesseractOCR/TesseractOCR.h>@implementation IdentifierIDCardManager+ (instancetype)recognizeCardManager {static IdentifierIDCardManager *recognizeCardManager = nil;static dispatch_once_t onceToken;dispatch_once(&onceToken, ^{recognizeCardManager = [[IdentifierIDCardManager alloc] init];});return recognizeCardManager;
}- (void)recognizeCardWithImage:(UIImage *)cardImage compleate:(CompleateBlock)compleate {//扫描身份证图片,并进行预处理,定位号码区域图片并返回UIImage *numberImage = [self opencvScanCard:cardImage];if (numberImage == nil) {compleate(nil);}//利用TesseractOCR识别文字[self tesseractRecognizeImage:numberImage compleate:^(NSString *numbaerText) {compleate(numbaerText);}];
}//扫描身份证图片,并进行预处理,定位号码区域图片并返回
- (UIImage *)opencvScanCard:(UIImage *)image {//将UIImage转换成Matcv::Mat resultImage;UIImageToMat(image, resultImage);//转为灰度图cvtColor(resultImage, resultImage, cv::COLOR_BGR2GRAY);//利用阈值二值化cv::threshold(resultImage, resultImage, 100, 255, CV_THRESH_BINARY);//腐蚀,填充(腐蚀是让黑色点变大)cv::Mat erodeElement = getStructuringElement(cv::MORPH_RECT, cv::Size(26,26));cv::erode(resultImage, resultImage, erodeElement);//轮廊检测std::vector<std::vector<cv::Point>> contours;//定义一个容器来存储所有检测到的轮廊cv::findContours(resultImage, contours, CV_RETR_TREE, CV_CHAIN_APPROX_SIMPLE, cvPoint(0, 0));//取出身份证号码区域/*std::vector<cv::Rect> rects;cv::Rect numberRect = cv::Rect(0,0,0,0);std::vector<std::vector<cv::Point>>::const_iterator itContours = contours.begin();for ( ; itContours != contours.end(); ++itContours) {cv::Rect rect = cv::boundingRect(*itContours);rects.push_back(rect);//算法原理if (rect.width > numberRect.width && rect.width > rect.height * 5) {numberRect = rect;}}//身份证号码定位失败if (numberRect.width == 0 || numberRect.height == 0) {return nil;}*///不只取身份证 而是取整个照片区域cv::Rect numberRect = cv::Rect(0,0,image.size.width,image.size.height);//定位成功成功,去原图截取身份证号码区域,并转换成灰度图、进行二值化处理cv::Mat matImage;UIImageToMat(image, matImage);resultImage = matImage(numberRect);cvtColor(resultImage, resultImage, cv::COLOR_BGR2GRAY);cv::threshold(resultImage, resultImage, 80, 255, CV_THRESH_BINARY);//将Mat转换成UIImageUIImage *numberImage = MatToUIImage(resultImage);return numberImage;
}//利用TesseractOCR识别文字
- (void)tesseractRecognizeImage:(UIImage *)image compleate:(CompleateBlock)compleate {dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^{G8Tesseract *tesseract = [[G8Tesseract alloc] initWithLanguage:@"chi_sim"];tesseract.image = [image g8_blackAndWhite];tesseract.image = image;// Start the recognition[tesseract recognize];//执行回调compleate(tesseract.recognizedText);});
}@end

编辑好demo之后,我们编译运行:

我们在Demo中附上了一张辨识度很高的图片作为测试;

实际的测试中,我发现用原生的库识别黑体准确度较高,但是识别其他字体要差很多;

可以通过训练获得自己的字体库来提高识别的准确度,尤其类似对身份证这种具体识别需求的字体库训练;

【Tesseract-OCR的简单使用与训练】

Demo截图:

关于Demo:

由于导入的OpenCV很大,导致Demo实在是有点大,没能传到Github上,码云也不OK,有需要的留言吧。

补充:

有关图像进一步识别可以参考下面这篇文章,通过对图片的有效处理,最终的识别度很高;

《OpenCV项目实战日志——检测文字并对比识别》

iOS实践:OpenCV、Tesseract OCR结合 识别图片中文字相关推荐

  1. 深入学习使用ocr算法识别图片中文字的方法

    公司有个需求,简单点说需要从一张图片中识别出中文,通过python来实现,当然其他程序也行,只要能实现,而小编主要学习python,所以就提了python.一个小白在网上遨游了一天,终于找到一丝丝思绪 ...

  2. python 识别图片中的中文_Python中利用Tesseract软件来识别图片中的英文与中文

    OCR与Tesseract介绍 将图片翻译成文字一般被称为光学文字识别(Optical Character Recognition,OCR).可以实现OCR 的底层库并不多,目前很多库都是使用共同的几 ...

  3. python图片显示英文字符_Python中利用Tesseract软件来识别图片中的英文与中文

    OCR与Tesseract介绍 将图片翻译成文字一般被称为光学文字识别(Optical Character Recognition,OCR).可以实现OCR 的底层库并不多,目前很多库都是使用共同的几 ...

  4. OCR如何识别图片中的文字?

    生活处处可见OCR的身影,OCR如何识别图片中的文字?OCR文字识别技术其实很简单,但还是有很多人不会,这里分享一个方法给大家. 1.首先要在百度或者下载站去搜索捷速OCR文字识别软件,熟悉操作后接着 ...

  5. 怎样用ocr软件识别图片中的文字

    现在文件格式越来越多,一个个处理起来也是很麻烦,想要有效快速的完成工作任务,我们就必须要利用一些辅助工具的帮助,比如说怎样用ocr软件识别图片中的文字?这个问题我们该如何处理,其实只要使用一个文字识别 ...

  6. 单张、批量识别图片中文字(写入txt文件、窗口视图创建、打包.exe文件)(百度文字识别SDK+Python的GUI之tklinker+打包pyinstaller)

    昨天我姐问我有没有软件可以批量识别图片上的文字,她在帮客户做资料整理,但是用的方法只能一张一张上传识别,不仅效率低还浪费时间. ​我就找了找批量识别的软件,下载下来觉得:嗯?不错,界面也挺好,小东西做 ...

  7. python 识别图片中的中文_python识别图片中文字的方法

    Tesseract 文字识别是ORC的一部分内容,ORC的意思是光学字符识别,通俗讲就是文字识别.Tesseract是一个用于文字识别的工具,我们结合Python使用可以很快的实现文字识别.但是在此之 ...

  8. C#-调用OCR组件识别图片文字

    C#调用OCR组件识别图片文字 图片识别的技术到几天已经很成熟了,只是相关的资料很少,为了方便在此汇总一下(C#实现),方便需要的朋友查阅,也给自己做个记号. 图片识别的用途:很多人用它去破解网站的验 ...

  9. opencv+tesseract完成验证码识别(识别率99.99%)

    一.需要识别的内容 需要识别的验证码内容如下  验证码下载下载地址. 二.直接调用tesseract来完成识别(识别率很差) 识别的图片内容为: 在window系统钟打开cmd命令窗口,执行识别命令如 ...

最新文章

  1. flashpaper打印机没有被正确安装_没有正确保存与安装,可导致80%的轴承提早失效...
  2. 学习机器学习,究竟是理论重要,还是公式推导重要?
  3. 削减成本同时,多数企业仍计划增加云计算投入
  4. Go语言int类型绑定方法
  5. Qt qCompress和qUncompress 压缩和解压文件
  6. scrapy第一发——基础巩固
  7. 前端学习(3256):react中添加todolist
  8. void init(void) 分析 ! \linux-1.0\init\main.c
  9. 【OpenCV】OpenCV实战从入门到精通之 -- 基本图像绘制
  10. 字符集及其存储方式(解决乱码问题)
  11. java interface作用是什么_关于Java反射原理:
  12. Visio的安装教程
  13. 16 Cesium—矢量数据
  14. 《2019-2020中国开发者调查报告》发布了!
  15. #学习方法 linux的教程推荐
  16. DZone每日必读-news: 指导软件团队取得成功的 4 种方法
  17. H3C-2620AP配置日志
  18. PMBOK(第六版) PMP笔记——《十三》第十三章(项目干系人管理)
  19. 启动virtualbox虚拟机显示Attempted to kill the idle task错误
  20. 谷歌地图 图片保存_Google如何在地图上跟踪并保存您的一举一动

热门文章

  1. 快手爬票(爬取火车票信息)
  2. J2EE进阶(二十四)JBoss Web和 Tomcat的区别
  3. python列表元素求和_如何在python语言使用不同方法实现列表元素求和
  4. 【JavaWeb】jQuery WeUI框架 地址选择器 City-Picker 自定义demo
  5. 【题解】helloworldroom#4906. 摩尔斯电码
  6. OpenGl计算机图形学入门
  7. linux进阶40——futex
  8. 业务场景可以从哪方面考虑
  9. 有限内存BFGS以及非精确牛顿法
  10. 【Flutter】Flutter 照片墙 ( Center 组件 | Wrap 组件 | ClipRRect 组件 | Stack 组件 | Positioned 组件 | 按钮组合组件 )