IOS自带的OCR识别功能
一、识别身份证
@interface IDCardScanViewController () <AVCaptureMetadataOutputObjectsDelegate>
@property (nonatomic, strong) AVCaptureSession *captureSession;
@end
@implementation IDCardScanViewController
- (void)viewDidLoad {
[super viewDidLoad];
// 创建视频预览层
AVCaptureVideoPreviewLayer *previewLayer = [[AVCaptureVideoPreviewLayer alloc] initWithSession:self.captureSession];
previewLayer.videoGravity = AVLayerVideoGravityResizeAspectFill;
previewLayer.frame = self.scanView.bounds;
[self.scanView.layer addSublayer:previewLayer];
// 创建数据输出
AVCaptureMetadataOutput *output = [[AVCaptureMetadataOutput alloc] init];
[self.captureSession addOutput:output];
[output setMetadataObjectsDelegate:self queue:dispatch_get_main_queue()];
// 设置扫描支持的码类型
if ([output.availableMetadataObjectTypes containsObject:AVMetadataObjectTypeIDCard]) {
output.metadataObjectTypes = @[AVMetadataObjectTypeIDCard];
}
// 启动扫描
[self.captureSession startRunning];
}
- (AVCaptureSession *)captureSession {
if (!_captureSession) {
_captureSession = [[AVCaptureSession alloc] init];
// 配置摄像头输入
AVCaptureDevice *device = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
AVCaptureDeviceInput *input = [AVCaptureDeviceInput deviceInputWithDevice:device error:nil];
[_captureSession addInput:input];
}
return _captureSession;
}
- (void)captureOutput:(AVCaptureOutput *)captureOutput didOutputMetadataObjects:(NSArray<__kindof AVMetadataObject *> *)metadataObjects fromConnection:(AVCaptureConnection *)connection {
for (AVMetadataObject *metadata in metadataObjects) {
if ([metadata isKindOfClass:[AVMetadataMachineReadableCodeObject class]]) {
AVMetadataMachineReadableCodeObject *code = (AVMetadataMachineReadableCodeObject *)metadata;
if ([code.type isEqualToString:AVMetadataObjectTypeIDCard]) {
NSString *result = code.stringValue;
// 对扫描结果进行处理
NSLog(@"扫描结果:%@", result);
}
}
}
}
下面的方法需要iOS13以上才能支持
#import <Vision/Vision.h>
#import <VisionKit/VisionKit.h>
@interface ViewController () <VNDocumentCameraViewControllerDelegate>
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
// 在需要的地方调用此方法启动身份证扫描
[self startDocumentCapture];
}
- (void)startDocumentCapture {
VNDocumentCameraViewController *documentCameraViewController = [[VNDocumentCameraViewController alloc] init];
documentCameraViewController.delegate = self;
[self presentViewController:documentCameraViewController animated:YES completion:nil];
}
#pragma mark - VNDocumentCameraViewControllerDelegate
- (void)documentCameraViewController:(VNDocumentCameraViewController *)controller didFinishWithScan:(VNDocumentCameraScan *)scan {
// 遍历扫描结果
for (NSUInteger pageIndex = 0; pageIndex < scan.pageCount; pageIndex++) {
VNPage *page = [scan pageAtIndex:pageIndex];
// 检查扫描结果是否为身份证
if ([self isIdentityCard:page]) {
// 获取身份证号码和姓名
NSString *number = [self identityCardNumberFromPage:page];
NSString *name = [self identityCardNameFromPage:page];
NSLog(@"身份证号码:%@", number);
NSLog(@"姓名:%@", name);
// 在这里进行身份证识别后的处理
}
}
// 关闭扫描视图控制器
[controller dismissViewControllerAnimated:YES completion:nil];
}
- (void)documentCameraViewControllerDidCancel:(VNDocumentCameraViewController *)controller {
// 用户取消了扫描,关闭扫描视图控制器
[controller dismissViewControllerAnimated:YES completion:nil];
}
- (void)documentCameraViewController:(VNDocumentCameraViewController *)controller didFailWithError:(NSError *)error {
// 扫描失败,处理错误信息
NSLog(@"扫描身份证发生错误:%@", error);
[controller dismissViewControllerAnimated:YES completion:nil];
}
#pragma mark - Helper Methods
- (BOOL)isIdentityCard:(VNPage *)page {
// 获取页面文本内容
NSString *text = page.recognizedText.string;
// 判断是否包含“公民身份号码”和“姓名”关键字
if ([text containsString:@"公民身份号码"] && [text containsString:@"姓名"]) {
return YES;
}
return NO;
}
- (NSString *)identityCardNumberFromPage:(VNPage *)page {
// 获取页面文本内容
NSString *text = page.recognizedText.string;
// 查找身份证号码
NSRange range = [text rangeOfString:@"公民身份号码"];
if (range.location != NSNotFound) {
NSString *number = [text substringFromIndex:range.location + range.length];
number = [number stringByReplacingOccurrencesOfString:@" " withString:@""];
return number;
}
return nil;
}
- (NSString *)identityCardNameFromPage:(VNPage *)page {
// 获取页面文本内容
NSString *text = page.recognizedText.string;
// 查找姓名
NSRange range = [text rangeOfString:@"姓名"];
if (range.location != NSNotFound) {
NSString *name = [text substringFromIndex:range.location + range.length];
name = [name stringByReplacingOccurrencesOfString:@" " withString:@""];
return name;
}
return nil;
}
@end
二、识别图片上的文字
#import <Vision/Vision.h>
@interface ViewController ()
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
UIImage *image = [UIImage imageNamed:@"test_image.jpg"];
[self recognizeTextInImage:image];
}
- (void)recognizeTextInImage:(UIImage *)image {
// 创建VNImageRequestHandler对象
VNImageRequestHandler *requestHandler = [[VNImageRequestHandler alloc] initWithCGImage:image.CGImage options:@{}];
// 创建VNRecognizeTextRequest对象
VNRecognizeTextRequest *textRequest = [[VNRecognizeTextRequest alloc] initWithCompletionHandler:^(VNRequest * _Nonnull request, NSError * _Nullable error) {
// 处理识别结果
if (error == nil) {
NSArray *results = request.results;
NSMutableString *recognizedText = [NSMutableString string];
for (VNRecognizedTextObservation *observation in results) {
for (VNRecognizedText *text in observation.topCandidates(1)) {
[recognizedText appendString:text.string];
[recognizedText appendString:@"\n"];
}
}
NSLog(@"识别结果:%@", recognizedText);
// 在这里进行识别后的处理
} else {
NSLog(@"识别出错:%@", error);
}
}];
// 设置识别方式和语种
textRequest.recognitionLevel = VNRequestTextRecognitionLevelAccurate;
textRequest.usesLanguageCorrection = YES;
// 发送识别请求
NSError *requestError = nil;
[requestHandler performRequests:@[textRequest] error:&requestError];
if (requestError != nil) {
NSLog(@"发送识别请求出错:%@", requestError);
}
}
@end
相关文章:
IOS自带的OCR识别功能
一、识别身份证 interface IDCardScanViewController () <AVCaptureMetadataOutputObjectsDelegate> property (nonatomic, strong) AVCaptureSession *captureSession; end implementation IDCardScanViewController - (void)viewDidLoad { [super viewDidLoad…...
1300*C. Product of Three Numbers(质数数学)
Problem - 1294C - Codeforces 解析: 首先这个数肯定不是质数,然后找到第一个因子p,对于n/p再判断质数,然后找到另外两个因子即可。 注意三个因子不能相同。 #include<bits/stdc.h> using namespace std; #define int long…...
【网络】五中IO模型介绍 + 多路转接中select和poll服务器的简单编写
高级IO 前言正式开始前面的IO函数简单过一遍什么叫做低效的IO钓鱼的例子同步IO和异步IO五种IO模型阻塞IO非阻塞IO信号驱动多路转接异步IO 小结 代码演示非阻塞IO多路转接select介绍简易select服务器timeout 为 nullptrtimeout 为 {0, 0}timeout 为 {5, 0}调用accept select编写…...
Camtasia2024破解版电脑屏幕录制剪辑软件
屏幕录制剪辑 TechSmith Camtasia for Mac v2021是 TechSmith 公司所开发出一款专业屏幕录像和编辑, Camtasia Studio2024版是由TechSmith公司官方进行汉化推出的最新版本,除2023版以下版本均没有官方汉化。 同时TechSmith公司打击第三方贩卖Camtasia Studio汉化的…...
c语言进阶部分详解(《高质量C-C++编程》经典例题讲解及柔性数组)
上篇文章我介绍了介绍动态内存管理 的相关内容:c语言进阶部分详解(详细解析动态内存管理)-CSDN博客 各种源码大家可以去我的github主页进行查找:唔姆/比特学习过程2 (gitee.com) 今天便接“上回书所言”,来介绍《高质…...
Unreal PythonScriptPlugin
Unreal PythonScriptPlugin 文章目录 Unreal PythonScriptPluginPython vs UnLua官方文档PyStubDoString 示例代码,引擎里有很多插件已经用 py 写编辑器脚本了 unreal.get_editor_subsystem(unreal.LevelEditorSubsystem).load_level("/Game/maps/UVlayoutTes…...
什么是数据可视化,为什么数据可视化很重要?
数据可视化是数据的图形表示,可以帮助人们更轻松地理解和解释复杂的信息。它涉及创建数据的视觉表示,例如图表、图形、地图和其他视觉元素,以传达数据中的见解、模式和趋势。数据可视化是将原始数据转化为可操作知识的关键工具。 以下是数据…...
chatgpt相关问题解答
1. openAI的chatgpt的收费方式有哪几种? 根据OpenAI官方的信息,ChatGPT的收费方式包括两种: 1.订阅计划(Subscription Plan):OpenAI提供了ChatGPT Plus订阅计划,每月收费20美元。订阅计划的用…...
nssm将exe应用封装成windows服务
一、简介 NSSM(Non-Sucking Service Manager)是一个用于在Windows操作系统上管理和运行应用程序作为服务的工具。它提供了一种简单的方法来将任意可执行文件转换为Windows服务,并提供了一些额外的功能和配置选项。 优点: 简单易…...
golang实现极简todolist
ToDoList 最近跟着qimi老师做了一个ToDoList,我做的GitHub地址贴在这里,但由于前端出了点问题,所以都是用postman进行测试 原项目地址 部分功能展示 删除代办 查找代办 下面给出思路 思路 其实这是一个很简单的增删改查的实现ÿ…...
C# Onnx Dense Face 3D人脸重建,人脸Mesh
效果 项目 代码 using OpenCvSharp; using System; using System.Collections.Generic; using System.Drawing; using System.Windows.Forms;namespace Onnx_Demo {public partial class frmMain : Form{public frmMain(){InitializeComponent();}string fileFilter "*.…...
Java 8 新特性 Stream 的使用场景(不定期更新)
方便在写代码的过程中直接使用,好记性不如好文章,直接 CV 改了直接用。提高 办(摸)公(鱼)效(时)率(间), 不然就直接问 GPT 也不是说不行。 只符合…...
公开IP属地信息如何保护用户的隐私?
公开IP属地信息通常涉及与用户或组织的隐私有关,因此在公开此类信息时需要非常小心,以避免侵犯他人的隐私权。以下是触碰底线的几种情况以及如何保护网络安全和用户隐私: 个人隐私保护: 公开IP属地信息可能泄露用户的物理位置&…...
大桌子初步使用
大桌子安装成功后进入应用市场首推安装首页和网盘 一键安装的时候如果出现这样的错误,只要你能保证服务器是正常联网的就再试一次,十有八九就是网络不稳定 安装成功后,要到已安装里去启用一下 然后回到这个页面 http://服务器ip/dzzoffice/h…...
初步了解ORM框架之一Mybatis
ORM(对象关系映射)框架是现代软件开发中不可或缺的一部分。它们简化了将对象模型映射到关系数据库的过程,提供了更加便捷和高效的数据库操作方式,常见有:Hibernate、JPA(Java Persistence API)、…...
2023 electron最新最简版windows、mac打包、自动升级详解
这里我将讲解一下从0搭建一个electron最简版架子,以及如何实现打包自动化更新 之前我有写过两篇文章关于electron框架概述以及 常用api的使用,感兴趣的同学可以看看 Electron桌面应用开发 Electron桌面应用开发2 搭建electron 官方文档:ht…...
Ubuntu18.04安装pcl-1.12.1,make时报错:/usr/bin/ld: cannot find -lvtkIOMPIImage
解决方案: 在vtk安装包中,重新打开cmake-gui,然后勾选上VTK_Group_MPI和VTK_Group_Imaging。 cd VTK-8.2.0 cd build cmake-gui然后重新编译生成。 make -j8 # 或者j4,量力而行。 sudo make install 就可以解决了。 然后重新回到pcl安装…...
表单验证不通过的一个点form中未定义这个字段
这个坑就是犯了好几次了,一直记不住,尤其是加了字段后的时候,总是忘记,然后导致验证不通过。 以前我认为,只要表单绑定的内容中的属性有这个值就在ruler里面就可以验证他,,以至于我总是不在dat…...
最新、最全、最详细的 K8S 学习笔记总结
Kubernetes就是一个编排容器的工具,一个可以管理应用全生命周期的工具,从创建应用,应用的部署,应用提供服务,扩容缩容应用,应用更新,都非常的方便,而且可以做到故障自愈。 K8S的前景…...
Emacs之高亮显示超过80个字符部分(一百三十)
简介: CSDN博客专家,专注Android/Linux系统,分享多mic语音方案、音视频、编解码等技术,与大家一起成长! 优质专栏:Audio工程师进阶系列【原创干货持续更新中……】🚀 人生格言: 人生…...
设计模式和设计原则回顾
设计模式和设计原则回顾 23种设计模式是设计原则的完美体现,设计原则设计原则是设计模式的理论基石, 设计模式 在经典的设计模式分类中(如《设计模式:可复用面向对象软件的基础》一书中),总共有23种设计模式,分为三大类: 一、创建型模式(5种) 1. 单例模式(Sing…...
练习(含atoi的模拟实现,自定义类型等练习)
一、结构体大小的计算及位段 (结构体大小计算及位段 详解请看:自定义类型:结构体进阶-CSDN博客) 1.在32位系统环境,编译选项为4字节对齐,那么sizeof(A)和sizeof(B)是多少? #pragma pack(4)st…...
多场景 OkHttpClient 管理器 - Android 网络通信解决方案
下面是一个完整的 Android 实现,展示如何创建和管理多个 OkHttpClient 实例,分别用于长连接、普通 HTTP 请求和文件下载场景。 <?xml version"1.0" encoding"utf-8"?> <LinearLayout xmlns:android"http://schemas…...
[ICLR 2022]How Much Can CLIP Benefit Vision-and-Language Tasks?
论文网址:pdf 英文是纯手打的!论文原文的summarizing and paraphrasing。可能会出现难以避免的拼写错误和语法错误,若有发现欢迎评论指正!文章偏向于笔记,谨慎食用 目录 1. 心得 2. 论文逐段精读 2.1. Abstract 2…...
MODBUS TCP转CANopen 技术赋能高效协同作业
在现代工业自动化领域,MODBUS TCP和CANopen两种通讯协议因其稳定性和高效性被广泛应用于各种设备和系统中。而随着科技的不断进步,这两种通讯协议也正在被逐步融合,形成了一种新型的通讯方式——开疆智能MODBUS TCP转CANopen网关KJ-TCPC-CANP…...
【Go】3、Go语言进阶与依赖管理
前言 本系列文章参考自稀土掘金上的 【字节内部课】公开课,做自我学习总结整理。 Go语言并发编程 Go语言原生支持并发编程,它的核心机制是 Goroutine 协程、Channel 通道,并基于CSP(Communicating Sequential Processes࿰…...
【2025年】解决Burpsuite抓不到https包的问题
环境:windows11 burpsuite:2025.5 在抓取https网站时,burpsuite抓取不到https数据包,只显示: 解决该问题只需如下三个步骤: 1、浏览器中访问 http://burp 2、下载 CA certificate 证书 3、在设置--隐私与安全--…...
论文浅尝 | 基于判别指令微调生成式大语言模型的知识图谱补全方法(ISWC2024)
笔记整理:刘治强,浙江大学硕士生,研究方向为知识图谱表示学习,大语言模型 论文链接:http://arxiv.org/abs/2407.16127 发表会议:ISWC 2024 1. 动机 传统的知识图谱补全(KGC)模型通过…...
VTK如何让部分单位不可见
最近遇到一个需求,需要让一个vtkDataSet中的部分单元不可见,查阅了一些资料大概有以下几种方式 1.通过颜色映射表来进行,是最正规的做法 vtkNew<vtkLookupTable> lut; //值为0不显示,主要是最后一个参数,透明度…...
Linux 内存管理实战精讲:核心原理与面试常考点全解析
Linux 内存管理实战精讲:核心原理与面试常考点全解析 Linux 内核内存管理是系统设计中最复杂但也最核心的模块之一。它不仅支撑着虚拟内存机制、物理内存分配、进程隔离与资源复用,还直接决定系统运行的性能与稳定性。无论你是嵌入式开发者、内核调试工…...
