IOS ID number identification

Recently, many friends said that the code downloaded from git was full of problems, because the libraries included were relatively large, so everyone waited patiently while pod was waiting. In addition, I have adapted the code to iOS10.

I. Preface

ID recognition, called the OCR technology. OCR is the abbreviation of optical character recognition, the various bills, newspapers, books, manuscripts and other printed text into the image information by scanning optical input method, using text recognition technology to image information into the computer input technology can be used.

Because of the need of the project, so these days, access to relevant information on the Internet, want to see if there is no God can use ready-made demo package. But no fruit, online OCR on this piece of information is very small, more reliable are charged, and the price is not cheap. But in China, the fees don’t feel right, so decide to study it yourself.

Take a and ultimately achieve the effect (if not MAC retain screen, the resolution will be affected, you need to debug in the real machine)

IOS ID number identification
final effect.Gif

Two, need to use the technology

Search a lot of information, and found that the identity card number identification, you need to use the following techniques:

  • Image processing techniques including gray processing, binarization, corrosion, contour detection and so on. Grayscale processing: grayscale processing, that is, each pixel of the specified image of the RGB three components, through a certain algorithm to calculate the gray value of the pixel, so that the image contains only brightness, without color information.
    IOS ID number identification
    .Png gray image binarization: binarization processing is converted through gray processing picture for image contains only black and white two colors, no other gray change between them. In the two value chart, 255 is white, and 0 is black.
    IOS ID number identification
    two value diagram.Png corrosion: the corrosion of pictures is the enlargement of black blocks in the resulting two value diagram. The element that connects the adjacent black pixels in the picture. By etching, the ID card numbers on the ID card can be linked together to form a rectangular area.
    IOS ID number identification
    .Png contour detection: corrosion map picture after corrosion after the operation of adjacent points will be connected together to form a large area, this time by contour detection could find out each large area, so you can locate the ID number of the above area.
    IOS ID number identification
  • Text recognition technology converts the image information into the computer input technology that can be used by recognizing images. For example, here is a picture containing a bunch of numbers. The OCR identification technique can output the digital information contained in the picture in string.
IOS ID number identification
contains pictures of numbers.Png

Three, open source framework, OpenCV and TesseractOCRiOS

  • OpenCV (image processing technology) OpenCV is a cross platform computer vision and machine learning library is an open source, the popular point said, is he to the computer provides a pair of eyes, a pair can obtain information from the picture of the glasses, so as to complete the function of image related to face recognition, identity recognition, to red eye, motion tracking and so on. Opencv official website
  • TesseractOCRiOS (complete text recognition) Tesseract is currently the most accurate available open-source OCR engine, you can read a variety of image formats and convert them to a variety of language text. TesseractOCRiOS is the Tesseract engine library encapsulated for the iOS platform.

Four, actual combat demonstration

  • Create a iOS project
  • Import the above two libraries with CocoPods because the OpenCV library files are large, so the time will be a little longer. Just wait patiently.
IOS ID number identification
podfile file.Png
  • When you run the project after the import completes, you will find the following error reported
IOS ID number identification
Bitode error.Png

Since the imported library does not support the Bitcode mechanism, it needs to be switched off; in engineering -> TARGETS-> Build Setting-> Enable Bitcode; set to NO; ok.

IOS ID number identification
to turn off Bitcode.png
  • The need to import the TesseractOCRiOS language pack TesseractOCRiOS library does not own the language pack, we need to manually import, our tesseract-ocr website directly to tessdata, is that we need to use the language pack. The downloaded language pack has about 400000000000000. Here we only need to use the English language package, so only import eng.traineddata, OK, and the other are deleted.

How many points should I pay attention to when importing language packages?:

  1. Language packages need to be placed under the tessdata directory. The lookup language package in TesseractOCRiOS is searched under the tessdata directory, so we can’t import eng.traineddata into our project separately, but we need to import it in the tessdata directory.
  2. To import tessdata into the Xcode project, you need to tick Create folder refrences. As mentioned above, the language package needs to be placed in the tessdata directory, so when you import the file to Xcode, you need to create a folder instead of creating a group. Following chart:
The way IOS ID number identification
imports the tessdata folder.Png
  • Create a RecogizeCardManager to manage ID identification related code. Since both the OpenCV and TesseractOCRiOS libraries are written in c++, you need to change the RecogizeCardManager.m suffix.M to.Mm
IOS ID number identification
  • The code in RecogizeCardManager
.h file
#import < Foundation/Foundation.h> @class UIImage; typedef void (^CompleateBlock) (NSString *text); @interface: RecogizeCardManager NSObject / * * * * * initialize a single case @return returns a RecogizeCardManager instance * + (instancetype) recognizeCardManager; / * * * according to the ID card photo ID number * * @param cardImage incoming ID * @param COMPLEATE photo recognition after the completion of the callback / - (void) recognizeCardWithImage: (UIImage *) cardImage compleate: (CompleateBlock) COMPLEATE; @end
.m file
#import "RecogizeCardManager.h" #import < opencv2/opencv.hpp> #import; < opencv2/imgproc/types_c.h> #import < opencv2/imgcodecs/ios.h> #import; < TesseractOCR/TesseractOCR.h> @implementation + RecogizeCardManager (instancetype) recognizeCardManager RecogizeCardManager *recognizeCardManager {static = nil; static dispatch_once_t onceToken; dispatch_once (& onceToken, recognizeCardManager = [[RecogizeCardManager ^{alloc] init]; return recognizeCardManager;});} - (void) recognizeCardWithImage: (UIImage *) cardImage compleate: (CompleateBlock COMPLEATE) {/ / ID card scanning images, and pretreatment, positioning number region of the image and return to UIImage *numberImage = [self opencvScanCard: cardImage] ; if (numberImage = = Nil) {COMPLEATE (NIL);} / / TesseractOCR [self tesseractRecognizeImage:numberImage compleate:^ using text recognition (NSString *numbaerText) {COMPLEATE (numbaerText);}]}; / / ID card scanning images, and pretreatment, positioning number region image and return - (UIImage *) opencvScanCard: (UIImage * image) {convert UIImage to Mat / cv:: Mat resultImage; UIImageToMat (image, resultImage); / / to the gray level of cvtColor (resultImage, resultImage, cv:, COLOR_BGR2GRAY); / / use threshold binarization cv:: threshold (resultImage, resultImage, 100, 255, CV_THRESH_BINARY); / / corrosion, corrosion is filled (black the point of change) cv:: Mat erodeElement = getStructuringElement (cv:: MORPH_RECT, Cv:: Size (26,26)); cv:: erode (resultImage, resultImage, erodeElement); / / contour detection of std:: vector< std:: vector< cv:: Point> > contours; / / define a container to store all the detected contour of cv:: findContours (resultImage, contours, CV_RETR_TREE, CV_CHAIN_APPROX_SIMPLE, cvPoint (0, 0)); / / remove the identity card number std:: vector< cv:: Rect> rects; cv:: Rect numberRect = cv:: Rect (0,0,0,0); std:: vector< std:: vector< cv:: Point> > itContours: const_iterator = contours.begin (for); (; itContours! = contours.end (); ++itContours) {cv:: Rect = rect cv:: boundingRect (*itContours); rects.push_back (rect); / / if rect.width > algorithm principle (numberRect.width; & & re Ct.width > rect.height * 5) {numberRect = rect;}} / / ID number location failure if (numberRect.width = = 0 || numberRect.height = = 0) {return nil;} / / positioning success, to intercept the original ID number area, and converted to grayscale, binarization processing for 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 will be converted into UIImage UIImage *numberImage = MatToUIImage (resultImage); return numberImage;} / / use TesseractOCR text recognition - (void) tesseractRecognizeImage: (UIImage * image compleate: (Co) MpleateBlock COMPLEATE (dispatch_get_global_queue) {dispatch_async (DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), G8Tesseract *tesseract [[G8Tesseract alloc] initWithLanguage:@ ^{= "eng"]; tesseract.image [image = g8_blackAndWhite]; tesseract.image = image; / / Start the recognition [tesseract recognize]; / / COMPLEATE callback (tesseract.recognizedText);}});
  • RecognizeCardViewController code
Story layout interface
IOS ID number identification
story layout interface.Png
.m file
#import "RecognizeCardViewController.h" #import "RecogizeCardManager.h" @interface (RecognizeCardViewController) < UINavigationControllerDelegate, UIImagePickerControllerDelegate> UIImagePickerController {*imgagePickController}; @property (weak, nonatomic) IBOutlet UIImageView *imgView; @property (weak, nonatomic) IBOutlet UILabel *textLabel; - (IBAction) cameraAction: (ID) sender; (IBAction) - photoAction: (ID) sender; @end @implementation RecognizeCardViewController - (void) viewDidLoad {[super viewDidLoad]; self.imgView.contentMode = UIViewContentModeScaleAspectFit; imgagePickController = [[UIImagePickerController alloc] init]; imgagePickController.delegate = self; imgagePickController.modalTransitionStyle = UIModalTransitionStyleFlipHorizontal; imgagePickController.allowsEditing = YES;} - {(void) didReceiveMemoryWarning [super didReceiveMemoryWarning] Dispose of any resources; / / that / / can be recreated.} - Camera (IBAction) cameraAction: (ID sender) {/ / determine whether can open the camera on the if ([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera]) {imgagePickController.sourceType = UIImagePickerControllerSourceTypeCamera; / / set the camera (camera, recording mode the video for the camera) imgagePickController.cameraCaptureMode = UIImagePickerControllerCameraCaptureModePhoto; [self presentViewController:imgagePickController animated:YES completion:nil] els;} E {UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@ "that" message:@ "equipment can not open the camera" delegate:self cancelButtonTitle:@ "know" otherButtonTitles: nil]; [alert show];}} / / album - (IBAction) photoAction: (ID sender) {imgagePickController.sourceType = UIImagePickerControllerSourceTypePhotoLibrary; [self presentViewController:imgagePickController animated:YES completion:nil] #pragma mark UIImagePickerControllerDelegate;} / / for access to all media resources that is only to judge the type of resources - (void) imagePickerController: (UIImagePickerController *) picker didFinishPickingMediaWithInfo: (NSDictionary< NSString *, id> * NSString *mediaType=[info objectForKey:UIImagePickerControllerMediaTy; info{) Pe] UIImage; *srcImage = nil; / / if ([mediaType isEqualToString:@ judge resource type "public.image") {srcImage = info[UIImagePickerControllerEditedImage]; self.imgView.image = srcImage; / / self.textLabel.text = @ "identity card is a picture into a successful recognition..."; [[RecogizeCardManager recognizeCardManager] recognizeCardWithImage:srcImage compleate:^ (NSString *text) {if (text! = Nil) {self.textLabel.text [NSString = stringWithFormat:@ "identification results:% @", text];} else {self.textLabel.text = @ "please select photos"; UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@ "that" message:@ "photo identification failed, please choose Choose clear, no complicated background ID photos to try again! "Delegate:self cancelButtonTitle:@" otherButtonTitles: "[alert know nil]; show];}}}]; [self dismissViewControllerAnimated:YES completion:nil];} / / shoot into the page by clicking the Cancel button - (void) imagePickerControllerDidCancel: (UIImagePickerController * picker) {[self dismissViewControllerAnimated:YES completion:nil]}; @end


Through the above experiment, the correct rate of the program on the ID card identification can reach almost 90% in the image preprocessing, the remaining 10% depends, preprocessing procedure is the key to the recognition system of. The principle of the system is also applicable to obtain other information on the identity card, and also can be applied to the identification of bank cards, license plate numbers and so on. Finally, a summary of the effect is achieved.

  • Depends on the rate of correct identification from corrosion, extraction region ID number (contour extraction) the key point of the algorithm. Corrosion: corrosion parameters is very important, some introduction about corrosion, corrosion and can refer to this article (Eroding and Dilating) remove the expansion area ID number (contour extraction algorithm): all the processes are in order to position the ID number of the region in the image, contour extraction is one such operation. The contour map selection algorithm is very important but also a difficult. I found the idea from this blog iOS ID number identification. To extract the contour area ID number, the principle of the algorithm is the width of the contour is all the most wide, the width and length must be greater than 5 times the height of the.
    but there are still a lot of problems with this algorithm. Sometimes may picture complex background will affect the contour detection, based on this problem: on the one hand through the pretreatment of the picture is to optimize the optimization algorithm to reduce the interference detection area ID number second aspects.
  • Recognition speed, using TesseractOCRiOS for relatively clear text identification, the speed is relatively fast, I tried to use an untreated digital picture to deal with, the recognition speed is less than 5S. But after the two value image processing after the recognition speed is reduced, I think we can further processing of binarization processing of images, such as the value of the two figure detailed trace skeleton, and then in the framework do uniform expansion processing, thus obtained the identity card number may clear a lot.

Here are a few learning websites on OpenCV,
OpenCV, official learning documents,
OpenCV guide,
, OPEN, CV, for, iOS

The project has been open source on the GitHub RecognizeCard, and if you like, you can point to a praise. What are the problems, you can leave a message, I am also the first contact, together with progress, everyone refueling.