引言


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


iOS小技能:iOS13 证件扫描 & 文字识别API_ios

iOS小技能:iOS13 证件扫描 & 文字识别API_.net_02

I 、 iOS13 证件扫描API

VisionKit的VNDocumentCameraViewController

API_AVAILABLE(ios(13.0)) API_UNAVAILABLE(macos, tvos, watchos)
@interface VNDocumentCameraViewController : UIViewController

iOS小技能:iOS13 证件扫描 & 文字识别API_.net_03

II、iOS13 文字识别API

Vision的 VNRecognizeTextRequest

API_AVAILABLE(macos(10.15), ios(13.0), tvos(13.0))
@interface VNRecognizeTextRequest : VNImageBasedRequest <VNRequestProgressProviding>

效果图:

iOS小技能:iOS13 证件扫描 & 文字识别API_ios_04

III 案例

#import "ViewController.h"

@interface ViewController ()

@end



@implementation ViewController

NSArray<VNRequest *> *requests;
dispatch_queue_t textRecognitionWorkQueue;

NSString *resultingText;

- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.


// Parar e esconder o Indicador de atividade do OCR
[self->activityIndicator stopAnimating];
self->activityIndicator.hidden = YES;

// Solicitar que o Vision seja executado em cada página do documento digitalizado.
requests = [[NSArray<VNRequest *> alloc] init];

// Cria a fila de expedição para executar solicitações do Vision.
dispatch_queue_attr_t qos = dispatch_queue_attr_make_with_qos_class(DISPATCH_QUEUE_SERIAL, QOS_CLASS_USER_INITIATED, -1);
textRecognitionWorkQueue = dispatch_queue_create("TextRecognitionQueue", qos);

resultingText = @"";



[self setupVision];
}

// Solicita o Setup do Vision, pois a solicitação pode ser reutilizada
- (void)setupVision {
VNRecognizeTextRequest *textRecognitionRequest = [[VNRecognizeTextRequest alloc] initWithCompletionHandler:^(VNRequest * _Nonnull request, NSError * _Nullable error) {

NSMutableArray *observations;
@try {
observations = [[NSMutableArray alloc] init];
for (VNRecognizedTextObservation *obs in request.results) {
[observations addObject:(VNRecognizedTextObservation *)obs];
}
}
@catch (NSException *exception) {
NSLog(@"As observações são de um tipo inesperado.");
}
@finally {
//NSLog(@"Condição final");
}

// Concatena o texto reconhecido de todas as observações.
NSInteger maximumCandidates = 1;
for (VNRecognizedTextObservation *observation in observations) {
VNRecognizedText *candidate = [observation topCandidates:maximumCandidates].firstObject;
resultingText = [NSString stringWithFormat:@"%@%@",
resultingText,
candidate.string];
}
}];
// Especifica o nível de reconhecimento
textRecognitionRequest.recognitionLevel = VNRequestTextRecognitionLevelAccurate;
requests = @[textRecognitionRequest];
}

- (IBAction)scanReceipts:(id)sender {
//Cria uma instancia da Classe de Leitura de Docs da Vision, e abre ela
VNDocumentCameraViewController *documentCameraViewController = [[VNDocumentCameraViewController alloc] init];
documentCameraViewController.delegate = self;

[self presentModalViewController:documentCameraViewController animated:YES];
}


// MARK: VNDocumentCameraViewControllerDelegate


- (void)documentCameraViewController:(VNDocumentCameraViewController *)controller didFinishWithScan:(VNDocumentCameraScan *)scan {
// Limpe qualquer texto existente.
self->textView.text = @"";
// Descartar a câmera de documentos
[controller dismissModalViewControllerAnimated:YES];

self->activityIndicator.hidden = NO;
[self->activityIndicator startAnimating];

dispatch_async(textRecognitionWorkQueue, ^{
resultingText = @"";
for (int pageIndex=0; pageIndex<scan.pageCount; pageIndex++) {
struct CGImage *image = [scan imageOfPageAtIndex:pageIndex].CGImage;
NSDictionary *d = [[NSDictionary alloc] init];
VNImageRequestHandler *requestHandler = [[VNImageRequestHandler alloc] initWithCGImage:image options:d];
NSError *error = nil;
@try {
[requestHandler performRequests:requests error:&error];
}
@catch (NSException *exception) {
NSLog(@"%@", exception);
}
@finally {
NSLog(@"Condição final");
}
}
dispatch_async(dispatch_get_main_queue(), ^{
self->textView.text = resultingText;
[self->activityIndicator stopAnimating];
self->activityIndicator.hidden = YES;
});
});
}


@end

see also

iOS13扫描证件&银行卡信息识别;身份证识别 (正反) ;矩形边缘识别 ;自定义证件相机 (含demo源码)