iOS之身份證號碼識別
阿新 • • 發佈:2019-02-03
##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]);