##Begin
这里使用到两个C++的库
- OpenCV
- Tesseract
OpenCV
在这里实现图像处理,Tesseract
在这里实现数字识别
先上效果图:隐私打码谢谢
###0x00 获取视频流
iOS里获取视频流比较简单,当然OpenCV里也有这功能,这里只说前一种。大家可以直接搜 AVCaptureSession
,这里我就直接上代码了。
在回调里获取到图片,并且转化为UIImage
-(void)captureOutput:(AVCaptureOutput *)captureOutput didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer fromConnection:(AVCaptureConnection *)connection{
CVImageBufferRef ref = CMSampleBufferGetImageBuffer(sampleBuffer);
CIImage* ciImage = [[CIImage alloc]initWithCVPixelBuffer:ref];
CIContext *context = [CIContext contextWithOptions:nil];
CGImageRef cgImage = [context createCGImage:ciImage fromRect:[ciImage extent]];
UIImage * image = [[UIImage alloc]initWithCGImage:cgImage];
CGImageRelease(cgImage);
}
###0x01 OpenCV处理图片
集成OpenCV的方法很简单,直接使用Cocospod就可以了。
pod 'OpenCV', '~> 3.0.0'
这里说下主要的对身份证的处理
灰度图
cvtColor(dst, dst, COLOR_BGR2GRAY);
二值化
threshold(dst, dst, 80, 255, THRESH_BINARY);
腐蚀
erode(dst,dst,Mat(27,27,CV_8U),Point(-1,-1),2);
轮廓检测
Mat c = dst.clone(); vector<vector<Point>> contours; findContours(c, contours, CV_RETR_TREE, CV_CHAIN_APPROX_SIMPLE,cvPoint(0, 0)); //除去太长或者太短的轮廓 int cmin = 35; int cmax = 800; vector<std::vector<cv::Point>>::iterator itc = contours.begin(); while(itc != contours.end()) { Rect rect = boundingRect(*itc); if(itc->size() < cmin || itc->size() > cmax || rect.width < 40 || rect.height < 40){ //std::cout << "EraseSize: " << itc->size() << std::endl; itc = contours.erase(itc); } else{ ++itc;}; }
取出身份证号码区域
vector<Rect> rects; Rect rr = Rect(0,0,0,0); std::vector<std::vector<cv::Point>>::const_iterator itContours = contours.begin(); for ( ; itContours!=contours.end(); ++itContours){ Rect rect = boundingRect(*itContours); rects.push_back(rect); //std::cout << "Size: " << rect << std::endl; if (rect.width > rr.width && rect.width > rect.height * 5) { rr = rect; } }
###0x02 Tesseract进行数字识别
集成OpenCV的方法也很简单,直接使用了别人封装好的一个库,当然也可以自己编译直接使用C++的。
pod 'TesseractOCRiOS', '~> 4.0.0'
直接识别
self.tesseract = [[G8Tesseract alloc] initWithLanguage:@"chi_sim"];
tesseract.charWhitelist = @"0123456789";
self.tesseract.image = [i g8_blackAndWhite];
// Optional: Limit the area of the image Tesseract should recognize on to a rectangle
self.tesseract.rect = CGRectMake(0, 0, i.size.width, i.size.height);
// Optional: Limit recognition time with a few seconds
self.tesseract.maximumRecognitionTime = 2.0;
// Start the recognition
[self.tesseract recognize];
// Retrieve the recognized text
NSLog(@"识别:%@", [self.tesseract recognizedText]);