1200字范文,内容丰富有趣,写作的好帮手!
1200字范文 > iOS实践:OpenCV Tesseract OCR结合 识别图片中文字

iOS实践:OpenCV Tesseract OCR结合 识别图片中文字

时间:2021-10-31 14:11:00

相关推荐

iOS实践:OpenCV Tesseract OCR结合 识别图片中文字

前言:

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

分析:

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

【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项目实战日志——检测文字并对比识别》

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。