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工程师进阶系列【原创干货持续更新中……】🚀 人生格言: 人生…...

日语AI面试高效通关秘籍:专业解读与青柚面试智能助攻
在如今就业市场竞争日益激烈的背景下,越来越多的求职者将目光投向了日本及中日双语岗位。但是,一场日语面试往往让许多人感到步履维艰。你是否也曾因为面试官抛出的“刁钻问题”而心生畏惧?面对生疏的日语交流环境,即便提前恶补了…...

el-switch文字内置
el-switch文字内置 效果 vue <div style"color:#ffffff;font-size:14px;float:left;margin-bottom:5px;margin-right:5px;">自动加载</div> <el-switch v-model"value" active-color"#3E99FB" inactive-color"#DCDFE6"…...
Spring Boot+Neo4j知识图谱实战:3步搭建智能关系网络!
一、引言 在数据驱动的背景下,知识图谱凭借其高效的信息组织能力,正逐步成为各行业应用的关键技术。本文聚焦 Spring Boot与Neo4j图数据库的技术结合,探讨知识图谱开发的实现细节,帮助读者掌握该技术栈在实际项目中的落地方法。 …...
实现弹窗随键盘上移居中
实现弹窗随键盘上移的核心思路 在Android中,可以通过监听键盘的显示和隐藏事件,动态调整弹窗的位置。关键点在于获取键盘高度,并计算剩余屏幕空间以重新定位弹窗。 // 在Activity或Fragment中设置键盘监听 val rootView findViewById<V…...

ios苹果系统,js 滑动屏幕、锚定无效
现象:window.addEventListener监听touch无效,划不动屏幕,但是代码逻辑都有执行到。 scrollIntoView也无效。 原因:这是因为 iOS 的触摸事件处理机制和 touch-action: none 的设置有关。ios有太多得交互动作,从而会影响…...
鸿蒙DevEco Studio HarmonyOS 5跑酷小游戏实现指南
1. 项目概述 本跑酷小游戏基于鸿蒙HarmonyOS 5开发,使用DevEco Studio作为开发工具,采用Java语言实现,包含角色控制、障碍物生成和分数计算系统。 2. 项目结构 /src/main/java/com/example/runner/├── MainAbilitySlice.java // 主界…...
Java 二维码
Java 二维码 **技术:**谷歌 ZXing 实现 首先添加依赖 <!-- 二维码依赖 --><dependency><groupId>com.google.zxing</groupId><artifactId>core</artifactId><version>3.5.1</version></dependency><de…...

Yolov8 目标检测蒸馏学习记录
yolov8系列模型蒸馏基本流程,代码下载:这里本人提交了一个demo:djdll/Yolov8_Distillation: Yolov8轻量化_蒸馏代码实现 在轻量化模型设计中,**知识蒸馏(Knowledge Distillation)**被广泛应用,作为提升模型…...

视觉slam十四讲实践部分记录——ch2、ch3
ch2 一、使用g++编译.cpp为可执行文件并运行(P30) g++ helloSLAM.cpp ./a.out运行 二、使用cmake编译 mkdir build cd build cmake .. makeCMakeCache.txt 文件仍然指向旧的目录。这表明在源代码目录中可能还存在旧的 CMakeCache.txt 文件,或者在构建过程中仍然引用了旧的路…...

MFC 抛体运动模拟:常见问题解决与界面美化
在 MFC 中开发抛体运动模拟程序时,我们常遇到 轨迹残留、无效刷新、视觉单调、物理逻辑瑕疵 等问题。本文将针对这些痛点,详细解析原因并提供解决方案,同时兼顾界面美化,让模拟效果更专业、更高效。 问题一:历史轨迹与小球残影残留 现象 小球运动后,历史位置的 “残影”…...