iOS小技能:OCR的使用(身份证/营业执照/车牌/银行卡识别)

4,670 阅读6分钟

「这是我参与2022首次更文挑战的第33天,活动详情查看:2022首次更文挑战」。

引言

智能识别范围:

营业执照识别,银行卡识别,护照识别,行驶证识别,印刷文字识别,图像内容识别

应用场景举例:

1、银行卡绑定 2、自动填充身份证号码:信用卡网申、商户进件、实名认证

原理:自定义相机采集银行卡图片,调用SDK/API进行OCTR识别

在这里插入图片描述

相关文章:

iOS13扫描证件&文字识别;身份证识别 (正反) ;矩形边缘识别 ;自定义相机: 加一个长方形的框框并裁剪身份证照片 (含demo源码)

kunnan.blog.csdn.net/article/det…

iOS自定义相机(带拍摄区域边框、半透明遮罩层、点击屏幕对焦、自动裁剪): 1、身份证正反面相机(加一个长方形的框框并裁剪身份证照片) 2、手持证件照相机(含demo源码)

———————————————— 版权声明:本文为CSDN博主「#公众号:iOS逆向」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。 原文链接:blog.csdn.net/z929118967/…

I 封装OCR接口(付费)

market.aliyun.com/products/57…

调用地址:http(s)://ocrcard.market.alicloudapi.com/textread

请求方式:POST 返回类型:JSON

名称类型是否必须描述
sideSTRING可选front:正面,front:反面,行驶证识别可选参数
srcSTRING必选图片base64编码
tidSTRING可选行驶证:xsz,驾驶证:jsz,营业执照:yyzz;银行卡:yhk;默认识别所有:simple; 营业执照:yyzzb;

1.1 官方的iOS版本

可将tid参数对外开放来适配各个应用场景

NSString *appcode = @"你自己的AppCode";
NSString *host = @"https://ocrcard.market.alicloudapi.com";
NSString *path = @"/textread";
NSString *method = @"POST";
NSString *querys = @"";
NSString *url = [NSString stringWithFormat:@"%@%@%@",  host,  path , querys];
NSString *bodys = @"side=front&src=%E5%9B%BE%E7%89%87base64%E7%BC%96%E7%A0%81&tid=simple";

NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString: url]  cachePolicy:1  timeoutInterval:  5];
request.HTTPMethod  =  method;
[request addValue:  [NSString  stringWithFormat:@"APPCODE %@" ,  appcode]  forHTTPHeaderField:  @"Authorization"];
[request addValue: @"application/x-www-form-urlencoded; charset=UTF-8" forHTTPHeaderField: @"Content-Type"];
NSData *data = [bodys dataUsingEncoding: NSUTF8StringEncoding];
[request setHTTPBody: data];
NSURLSession *requestSession = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration]];
NSURLSessionDataTask *task = [requestSession dataTaskWithRequest:request
    completionHandler:^(NSData * _Nullable body , NSURLResponse * _Nullable response, NSError * _Nullable error) {
    NSLog(@"Response object: %@" , response);
    NSString *bodyString = [[NSString alloc] initWithData:body encoding:NSUTF8StringEncoding];

    //打印应答中的body
    NSLog(@"Response body: %@" , bodyString);
    }];

[task resume];

1.2 自己封装的iOS版本

推荐 使用 type = @"simple"; 进行身份证正反面的识别 头文件

@interface OcrIdentify : NSObject

+ (void)OCRIdentifyType:(NSString *)type Image:(UIImage *)image success:(void(^)(id responseObj))success failure:(void(^)(NSError *error))failure;
/**
处理营业执照的特殊情况
*/
+ (BOOL)isover_a_long_period_of_time:(NSString*)str;


实现代码


/**
 if ([str isEqualToString:@"营业期限"]) {//           "营业期限" : "\/长期",

 if ([responseObj[@"msg"][str] isEqualToString:@"长期"] ) {

 */
+ (BOOL)isover_a_long_period_of_time:(NSString*)str{
    
    if ([str isEqualToString:@"长期"]) {//           "营业期限" : "\/长期",
        
        return YES;

    }
    
    
     if([str containsString:@"长期"] && !([str containsString:@"至"])){
        
        return YES;

        
        
        
        
    }
    
    
    
    
    return NO;
}
/**
 
 http(s)://ocrphoto.market.alicloudapi.com/ocr/photo
 */
+ (void)OCRIdentifyType:(NSString *)type Image:(UIImage *)image success:(void(^)(id responseObj))success failure:(void(^)(NSError *error))failure
{
    NSString *appcode = @"";
    NSString *host = @"http://ocrcard.market.alicloudapi.com";
    NSString *path = @"/textread";
    NSString *method = @"POST";
    NSString *querys = @"";
    NSString *url = [NSString stringWithFormat:@"%@%@%@",  host,  path , querys];

    NSData *imgData = UIImageJPEGRepresentation(image, 0.1f);
    NSString *base64 = [imgData base64EncodedStringWithOptions:NSDataBase64Encoding64CharacterLineLength];
    base64 = [self encodeString:base64];

    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:[NSURL URLWithString: url]  cachePolicy:1  timeoutInterval:  5];
    request.HTTPMethod  =  method;
    [request addValue:  [NSString  stringWithFormat:@"APPCODE %@" ,  appcode]  forHTTPHeaderField:  @"Authorization"];
    [request addValue: @"application/x-www-form-urlencoded; charset=UTF-8" forHTTPHeaderField: @"Content-Type"];
    NSString *bodys = [NSString stringWithFormat:@"src=%@&tid=%@",base64,type];
    NSData *data = [bodys dataUsingEncoding: NSUTF8StringEncoding];
    [request setHTTPBody: data];
    
    NSURLSession *requestSession = [NSURLSession sessionWithConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration]];
    NSURLSessionDataTask *task = [requestSession dataTaskWithRequest:request
                                                   completionHandler:^(NSData * _Nullable body , NSURLResponse * _Nullable response, NSError * _Nullable error) {
                                                       
                                                       if (!error) {
                                                           NSError * _Nonnull error;
                                                           NSString *jsonStr = [[NSString alloc] initWithData:body encoding:NSUTF8StringEncoding];
                                                           NSData *JSONData = [jsonStr dataUsingEncoding:NSUTF8StringEncoding];
                                                           NSDictionary *responseJSON = [NSJSONSerialization JSONObjectWithData:JSONData options:NSJSONReadingMutableLeaves error:&error];
                                                           if (error)
                                                           {
                                                               if(failure)
                                                               {
                                                                   NSLog(@"%@",error.userInfo);
                                                                   failure(error);
                                                               }
                                                           }
                                                           if (success)
                                                           {
                                                               if (responseJSON != nil) {
                                                                   NSLog(@"body:%@  url:%@",[[NSString alloc] initWithData: [NSJSONSerialization dataWithJSONObject:responseJSON options:NSJSONWritingPrettyPrinted error:nil] encoding:NSUTF8StringEncoding],url);
                                                               }

                                                               if ([responseJSON[@"status"] intValue] == 200) {
                                                                   success(responseJSON);
                                                               } else {
//                                                                   [SVProgressHUD showInfoWithStatus:responseJSON[@"msg"]];
                                                                   [SVProgressHUD showInfoWithStatus:@"识别错误!"];

                                                               }
                                                           }
                                                       }
                                                   }];
    
    [task resume];
}

+ (NSString*)encodeString:(NSString*)unencodedString{
    
    NSString *encodedString = (NSString *)
    CFBridgingRelease(CFURLCreateStringByAddingPercentEscapes(kCFAllocatorDefault,
                                                              (CFStringRef)unencodedString,
                                                              NULL,
                                                              (CFStringRef)@"!*'();:@&=+$,/?%#[]",
                                                              kCFStringEncodingUTF8));
    
    return encodedString;
}

1.3 用法



        
        
        type = @"simple";

        [OcrIdentify OCRIdentifyType:type Image:photo success:^(id  _Nonnull responseObj) {
            
            
            
            NSArray *array = [responseObj[@"msg"] componentsSeparatedByString:@"\n"];
            for (int i = 0; i < array.count; i++) {
                if (weakSelf.photoSelectTag == 0) {
                    if ([array[i] containsString:@"公民身份号码"]) {
                        if ([array[i]length] > 6) {
                            dispatch_async(dispatch_get_main_queue(), ^{
                                NSString *idCard = [array[i] substringFromIndex:6];
                                weakSelf.frCardTextF.text = [idCard stringByReplacingOccurrencesOfString:@" " withString:@""];
                            });
                        }
                    } else if ([array[i] containsString:@"姓名"]) {
                        if ([array[i]length] > 2) {
                            dispatch_async(dispatch_get_main_queue(), ^{
                                
                                NSString *tmpcardNameTextFT = [array[i] substringFromIndex:2];
                                
                                tmpcardNameTextFT = [tmpcardNameTextFT stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]];

                                
                                weakSelf.frNameTextF.text = tmpcardNameTextFT;
                            });
                        }
                    }
                } else if (weakSelf.photoSelectTag == 1) {
                    //身份证反面起始日期
                    NSString *date = @"";
                    for (int i = 0; i < array.count; i++) {
                        if ([array[i] containsString:@"有效期限"]) {
                            date = [array[i] substringFromIndex:4];
                            date = [date stringByReplacingOccurrencesOfString:@" " withString:@""];
                        }
                    }
                    NSArray *dateArr = [date componentsSeparatedByString:@"-"];
                    if (dateArr.count == 2) {
                        for (int i = 0; i < dateArr.count; i++) {
                            if (i == 0) {
                                dispatch_async(dispatch_get_main_queue(), ^{
                                    self->frsta = [dateArr[0] stringByReplacingOccurrencesOfString:@"." withString:@"-"];
                                });
                            } else if (i == 1) {
                                dispatch_async(dispatch_get_main_queue(), ^{
                                    if ([dateArr[1]containsString:@"长期"]) {
                                        self->frend = @"";
                                        [weakSelf.frDateBtn setTitle:[NSString stringWithFormat:@"%@~长期",self->frsta] forState:UIControlStateNormal];
                                        
                                    } else {
                                        self->frend = [dateArr[1] stringByReplacingOccurrencesOfString:@"." withString:@"-"];
                                        [weakSelf.frDateBtn setTitle:[NSString stringWithFormat:@"%@~%@",self->frsta,self->frend] forState:UIControlStateNormal];
                                    }
                                    
                                });
                                
                            }
                        }
                        
                    } else {
                        [SVProgressHUD showErrorWithStatus:@"证件识别错误!"];
                    }
                }
            }
        } failure:^(NSError * _Nonnull error) {
            [SVProgressHUD showErrorWithStatus:@"证件识别错误!"];
        }];

1.4 常见问题

  1. AppCode:控制台-云市场-已购买服务

在这里插入图片描述

  1. 有问题就直接提交工单:

ticket.console.aliyun.com/?spm=5176.1…

车牌调用地址:

[http(s)://ocrcp.market.alicloudapi.com/rest/160601/ocr/ocr_vehicle_plate.json

请求方式:POST  
返回类型:JSON  
请求参数(Body):  
{  
    "image": "图片二进制数据的base64编码或者图片url"      #图片以base64编码的string  
}

II 免费的SDK请到CSDN下载:

2.1 扫描银行卡识别信息Demo源码

从CSDN下载Demo源码:download.csdn.net/download/u0…

  1. 功能:扫描银行卡识别信息( 银行名称、 银行卡号)并截取银行卡图像

  2. 应用场景:快速填充银行卡号的场景,比如商户进件、实名认证

  3. 原理:

3.1、自定义相机并利用第三方库SDK libexbankcardios.a 、libbexbankcard.a进行识别(识别次数无限,免费)

3.2、添加自定义的扫描界面(中间有一个镂空窗口和来回移动的扫描线)

  1. 原理文章:kunnan.blog.csdn.net/article/det…

  2. 如果无法下载Demo,请关注公众号:【iOS逆向】,进行获取在这里插入图片描述

2.2 识别身份证信息

从CSDN下载Demo源码:https://download.csdn.net/download/u011018979/19265912

  1. 功能:可自动快速读出二代身份证上的信息(姓名、性别、民族、住址、身份证号码)并截取到身份证图像
  2. 应用场景:身份证号码采集:信用卡网申、商户进件、实名认证 3、
  3. 原理:

3.1、自定义相机并利用第三方库SDK libexidcardios 进行识别

3.2、添加自定义的扫描界面(中间有一个镂空窗口和来回移动的扫描线)

3.3、人脸小框检测:人脸区域是否在这个人脸小框内,若在,说明用户的确将身份证头像放在了这个框里,那么此时这一帧身份证图像大小正好合适且完整,接下来才捕获该帧,就获得了完整的身份证截图。

  1. 原理文章:kunnan.blog.csdn.net/article/det…

2.3 自定义相机进行银行卡识别

原理:自定义相机采集银行卡图片,调用SDK/API进行OCTR识别

iOS自定义相机(带拍摄区域边框、半透明遮罩层、点击屏幕对焦、自动裁剪):

  1. 身份证正反面相机(加一个长方形的框框并裁剪身份证照片)

  2. 手持证件照相机(含demo源码)

———————————————— 版权声明:本文为CSDN博主「#公众号:iOS逆向」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。 原文链接:blog.csdn.net/z929118967/…

2.4 通用文字识别

从CSDN下载Demo源码:https://download.csdn.net/download/u011018979/19262418

1、应用场景:证件扫描、文字识别

2、原理:利用iOS13 VNDocumentCameraViewController的证件扫描和VNRecognizeTextRequest文字识别功能进行实现

3、原理文章:kunnan.blog.csdn.net/article/det…

see also

🍅 联系作者: iOS逆向(公号:iosrev)


🍅 作者简介:CSDN 博客专家认证🏆丨全站 Top 50、华为云云享专家认证🏆、iOS逆向公号号主


🍅 简历模板、技术互助。关注我,都给你。