OCR:文字识别
使用场景:
远程身份认证
自动识别录入用户身份/企业资质信息,应用于金融、政务、保险、电商、直播等场景,对用户、商家、主播进行实名身份认证,有效降低用户输入成本,控制业务风险
文档电子化
识别提取各类办公文档、合同文件、企业年报、法律卷宗等纸质文档中的文字信息,并基于位置信息进行比对、结构化处理,提高信息录入、存档、检索效率
交通出行
实现卡证、车辆信息的快速录入,提升比对效率,适用于司机身份核验、车主信息管理、智慧停车、卡口通行、车辆维修保养等场景
快递物流
实现快递分发全链路智能化升级,满足身份核验、智能寄件下单,运输车辆管理、快递单识别等不同场景需求。同时助力大宗货运物流过磅提效
财税报销
对10 余种常见税务发票、差旅票据自动分类、识别、录入,可快速对接国税平台进行增值税发票验真,适用于企业税务核算及内部报销场景,释放企业人力,简化业务流程
医疗保险
识别患者身份信息/各类医疗票据/医疗仪器盘数据,提升信息录入效率,助力提高保险理赔整体时效,并辅助病患管理、健康监测、处方单电子化等
识别实战
身份证验证
使用百度智能云的OCR身份证识别
鉴权认证机制
获取到access_token
通过API Key和Secret Key获取的access_token,参考“Access Token获取”
鉴权的主要目的是获取Access_token。Access_token是用户的访问令牌,承载了用户的身份、权限等信息。
1.获取AK/SK
创建应用


2.添加到nacos配置中

3.在业务层使用@Value获取

4.获取Access_token
使用下面编写好的工具类BaiduOcrApi 。
5.controller层
@Operation(summary = "识别身份证")@Parameters({@Parameter(name = "type", description = "back:国徽面;front:照片面", required = true, in = ParameterIn.QUERY)})@PostMapping("/idCard")public SimpleResponse<OCRIdCardResponse> recognizeIdCardBack(@RequestPart(name = "file") MultipartFile file,@RequestParam("type") String type) {return SimpleResponse.success(ocrService.recognizeIdCard(file, type));}
6.service层
@Value("${ocr.apiKey}")private String apiKey;@Value("${ocr.secretKey}")private String secretKey;@Resourceprivate ObjectMapper objectMapper;@Resourceprivate RedissonClientTemplate redissonClientTemplate;/*** 识别身份证** @param file 文件* @param type 类型* @return {@link OCRIdCardResponse}*/@Override@SneakyThrowspublic OCRIdCardResponse recognizeIdCard(MultipartFile file, String type) {if (file == null || file.isEmpty()) {log.info("---------- 文件内容为空 ----------");throw new AppRuntimeException(ResponseCode.OPERATION_FAILED);}InputStream inputStream = file.getInputStream();// 获取access_tokenString accessToken = redissonClientTemplate.get(RedisKeyConstants.OCR_ACCESS_TOKEN);if (StringUtils.isEmpty(accessToken)) {accessToken = BaiduOcrApi.getAccessToken(apiKey, secretKey);// 保存accessToken到redis,有效时间为29天redissonClientTemplate.setex(RedisKeyConstants.OCR_ACCESS_TOKEN, accessToken, 29L, TimeUnit.DAYS);}// ocr识别String result = BaiduOcrApi.recognizeIDCardResult(inputStream, accessToken, type);OCRResult orcIdCardResult = objectMapper.readValue(result, OCRResult.class);if (orcIdCardResult == null || !"normal".equals(orcIdCardResult.getImage_status()) || orcIdCardResult.getWords_result_num() <= 0) {throw new AppRuntimeException(ResponseCode.OCR_API_ERROR);}OCRIdCardResponse orcIdCardResponse = new OCRIdCardResponse();Map<String, OCRResult.wordsModel> wordsResult = orcIdCardResult.getWords_result();// 获取结果if ("back".equals(type)) {// 身份证国徽面OCRResult.wordsModel wordsModel = wordsResult.get(OcrConstant.EXPIRATION_DATE);if (wordsModel == null) {throw new AppRuntimeException(ResponseCode.OCR_API_ERROR);}orcIdCardResponse.setExpirationDate(wordsModel.getWords());} else {// 身份证头像面OCRResult.wordsModel wordsModel1 = wordsResult.get(OcrConstant.NAME);if (wordsModel1 == null) {throw new AppRuntimeException(ResponseCode.OCR_API_ERROR);}orcIdCardResponse.setName(wordsModel1.getWords());OCRResult.wordsModel wordsModel2 = wordsResult.get(OcrConstant.ID_NUMBER);if (wordsModel2 == null) {throw new AppRuntimeException(ResponseCode.OCR_API_ERROR);}orcIdCardResponse.setIdNumber(wordsModel2.getWords());}// TODO 保存照片到OSSreturn orcIdCardResponse;
6.百度ocr请求工具类
import cn.hutool.json.JSONObject;
import okhttp3.*;import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.Base64;/*** @ClassName: BaiduOcrApi* @Author: wujiada* @Date: 2024/12/16 10:21* @Description: 使用API Key和Secret Key获取Access Token,获取识别结果*/
public class BaiduOcrApi {private static final OkHttpClient HTTP_CLIENT = new OkHttpClient().newBuilder().build();/*** 从用户的AK,SK生成鉴权签名(Access Token)** @return 鉴权签名(Access Token)* @throws IOException IO异常*/public static String getAccessToken(String apiKey, String secretKey) throws Exception {MediaType mediaType = MediaType.parse("application/x-www-form-urlencoded");RequestBody body = RequestBody.create(mediaType, "grant_type=client_credentials&client_id=" + apiKey+ "&client_secret=" + secretKey);Request request = new Request.Builder().url("https://aip.baidubce.com/oauth/2.0/token").method("POST", body).addHeader("Content-Type", "application/x-www-form-urlencoded").build();Response response = HTTP_CLIENT.newCall(request).execute();assert response.body() != null;return new JSONObject(response.body().string()).get("access_token", String.class);}/*** <p>请求百度OCR识别身份证</p>** @param inputStream 文件输入流* @param accessToken 访问百度云API的token* @param type: back:国徽面;front:照片面* @return {@link String}* @author wujiada* @since 2024/12/16 11:35*/public static String recognizeIDCardResult(InputStream inputStream, String accessToken, String type) throws Exception {// 读取图片文件并转换为Base64编码// 将输入流转换为字节数组byte[] imageBytes = readInputStream(inputStream);// 使用Base64编码字节数组String base64EncodedImage = Base64.getEncoder().encodeToString(imageBytes);MediaType mediaType = MediaType.parse("application/x-www-form-urlencoded");// front:身份证含照片的一面// back:身份证带国徽的一面RequestBody body = RequestBody.create(mediaType, "image=" + URLEncoder.encode(base64EncodedImage, StandardCharsets.UTF_8)+ "&id_card_side=" + type + "&detect_ps=false&detect_risk=false&detect_quality=false&detect_photo=false&detect_card=false&detect_direction=false");Request request = new Request.Builder().url("https://aip.baidubce.com/rest/2.0/ocr/v1/idcard?access_token=" + accessToken).method("POST", body).addHeader("Content-Type", "application/x-www-form-urlencoded").addHeader("Accept", "application/json").build();Response response = HTTP_CLIENT.newCall(request).execute();assert response.body() != null;return response.body().string();}/*** <p>请求百度OCR识别营业执照</p>** @param inputStream 文件输入流* @param accessToken 访问百度云API的token* @return {@link String}* @author wujiada* @since 2024/12/16 11:35*/public static String recognizeBusinessLicenseResult(InputStream inputStream, String accessToken) throws Exception {// 读取图片文件并转换为Base64编码// 将输入流转换为字节数组byte[] imageBytes = readInputStream(inputStream);// 使用Base64编码字节数组String base64EncodedImage = Base64.getEncoder().encodeToString(imageBytes);MediaType mediaType = MediaType.parse("application/x-www-form-urlencoded");RequestBody body = RequestBody.create(mediaType, "image=" + URLEncoder.encode(base64EncodedImage, StandardCharsets.UTF_8));Request request = new Request.Builder().url("https://aip.baidubce.com/rest/2.0/ocr/v1/business_license?access_token=" + accessToken).method("POST", body).addHeader("Content-Type", "application/x-www-form-urlencoded").addHeader("Accept", "application/json").build();Response response = HTTP_CLIENT.newCall(request).execute();assert response.body() != null;return response.body().string();}/*** <p>从输入流中读取所有字节并将它们存储在ByteArrayOutputStream</p>** @param inputStream 文件输入流* @return {@link byte[]}* @author wujiada* @since 2024/12/16 11:37*/private static byte[] readInputStream(InputStream inputStream) throws IOException {// 使用ByteArrayOutputStream收集字节ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();byte[] buffer = new byte[1024];int bytesRead;// 从输入流中读取数据直到EOFwhile ((bytesRead = inputStream.read(buffer)) != -1) {byteArrayOutputStream.write(buffer, 0, bytesRead);}// 将收集的字节转换为字节数组return byteArrayOutputStream.toByteArray();}}
7.ocrAPI接收结果实体类
/*** @ClassName: OCRResult* @Author: wujiada* @Date: 2024/12/16 11:45* @Description: 请求百度OCRAPI识别返回结果*/
@Data
@Schema(description = "请求百度ORC识别API身份证返回结果")
public class OCRResult implements Serializable {@Schema(description = "唯一的log id,用于问题定位")private Long log_id;@Schema(description = "识别结果数,表示words_result的元素个数")private Long words_result_num;@Schema(description = "定位和识别结果数组")private Map<String, wordsModel> words_result;/* normal-识别正常reversed_side-身份证正反面颠倒non_idcard-上传的图片中不包含身份证blurred-身份证模糊other_type_card-其他类型证照over_exposure-身份证关键字段反光或过曝over_dark-身份证欠曝(亮度过低)unknown-未知状态*/@Schema(description = "识别状态")private String image_status;@Datapublic static class wordsModel {private Object location;private String words;}
}
总结
通过以上操作,就可以实现前端上传身份证文件,然后发送到百度云OCR,识别校验身份证。
相关文章:
OCR:文字识别
使用场景: 远程身份认证 自动识别录入用户身份/企业资质信息,应用于金融、政务、保险、电商、直播等场景,对用户、商家、主播进行实名身份认证,有效降低用户输入成本,控制业务风险 文档电子化 识别提取各类办公文档、合同文件、企…...
SQL Server通过存储过程实现自定义邮件格式并定时发送
在 SQL Server 中,可以通过存储过程实现自定义邮件格式并定时发送。这通常涉及以下几个步骤: 1. 配置 Database Mail:首先需要配置 SQL Server 的 Database Mail 功能。 2. 创建存储过程:编写存储过程来生成自定义邮件格式并发送邮件。 3. 设置 SQL Server 代理作…...
【进阶编程】MVC和MVVM实现前后端分离的实现
在 WPF 开发中,通常使用 MVVM(Model-View-ViewModel)架构来分离视图和业务逻辑,但在某些情况下,你可能希望将 MVC(Model-View-Controller)模式与 MVVM 结合使用。这种结合有时是为了兼顾不同的架…...
HT81297 18W内置升压单声道D类音频功放
1、特征 扩频技术 输出功率 18W(VBAT3.7V, RL4Ω, THDN10%, fN 1kHz) 16W(VBAT3.7V,RL-4Ω,THDN1%,fN1kHz) 8W(VBAT3.3V,RL-8Ω,THDN1%, fN1kHz) VBAr供电范围:3.0V至12V 高效H类升压功能 -自适应功放功率的升压轨,延长电池播放时间 (HT81297A) -可调节最大限流值&…...
linux ipmitool配置机器的BMC(服务器管理后台)
前置:mgnt口和网卡1连接入内网,并分配静态ip 1. 安装 ipmitool Debian/Ubuntu: sudo apt-get update sudo apt-get install ipmitool CentOS/RHEL: sudo yum install ipmitool2. 配置 BMC 的 IP 地址 #打印当前ipmi 地址配置信息。 ipmitool lan p…...
【项目实战】location.href 实现文件下载
应用场景 最近在项目中看到一种新的文件下载方式,原理是将[后台地址接口地址请求参数]拼接成一个url,直接将下载任务丢给浏览器去执行.但是在需要校验token的项目中,需要后台单独给这个接口放开token校验 location.href 相关内容 window.location.protocol: 返回当前 URL 的…...
【Threejs】从零开始(十)--加载gltf模型和压缩后的模型
一.加载普通的gltf模型 glTF(gl传输格式)是一种开放格式的规范 (open format specification), 用于更高效地传输、加载3D内容。该类文件以JSON(.gltf)格式或二进制(.glb)…...
国标GB28181平台EasyGBS在安防视频监控中的信号传输(电源/视频/音频)特性及差异
在现代安防视频监控系统中,国标GB28181协议作为公共安全视频监控联网系统的国家标准,该协议不仅规范了视频监控系统的信息传输、交换和控制技术要求,还为不同厂商设备之间的互联互通提供了统一的框架。EasyGBS平台基于GB28181协议,…...
Day9 神经网络的偏导数基础
多变量函数与神经网络 在神经网络中,我们经常遇到多变量函数。这些函数通常描述了网络的输入、权重、偏置与输出之间的关系。例如,一个简单的神经元输出可以表示为: z f ( w 1 x 1 w 2 x 2 … w n x n b ) z f(w_1x_1 w_2x_2 \ldots…...
day4:tomcat—maven-jdk
一,java项目部署过程 编译:使用javac命令将.java源文件编译成.class宇节码文件打包:使用工具如maven或Gradle将项目的依赖、资源和编译后的字节码打包成一个分发格式,如.jar文件,或者.war文件(用于web应用)…...
apache-tomcat-6.0.44.exe Win10
apache-tomcat-6.0.44.exe Win10...
Redis(2)常用命令
安装Redis 现在我们安装Redis 5,Redis安装在Linux上面安装,如果想在本机上面安装多个Redis的话,就要使用Docker。 在Ubuntu上面安装: 切换到root用户使用apt命令搜索相关的软件包(apt search redis)apt …...
【原生js案例】ajax的简易封装实现后端数据交互
ajax是前端与后端数据库进行交互的最基础的工具,第三方的工具库比如jquery,axios都有对ajax进行第二次的封装,fecth是浏览器原生自带的功能,但是它与ajax还是有区别的,总结如下: ajax与fetch对比 实现效果 代码实现 …...
安卓环境配置及打开新项目教程,2024年12月20日最新版
1.去官网下载最新的Android Studio,网址:https://developer.android.com/studio?hlzh-cn 2.下载加速器,注册账号,开启加速器。网址:放在文末。 3.下载安卓代码,项目的路径上不能有中文,特别是…...
Docker 安装 禅道-21.2版本-外部数据库模式
Docker 安装系列 1、拉取最新版本(zentao 21.2) [rootTseng ~]# docker pull hub.zentao.net/app/zentao Using default tag: latest latest: Pulling from app/zentao 55ab1b300d4b: Pull complete 6b5749e5ef1d: Pull complete bdccb03403c1: Pul…...
写SQL太麻烦?免费搭建 Text2SQL 应用,智能写 SQL | OceanBase AI 实践
自OceanBase 4.3.3版本推出以来,向量检索的能力受到了很多客户的关注,也纷纷表达希望OB能拓展更多 多模数据库大模型 的AI应用实践。 在上篇文章 👉 OceanBase LLM,免费构建你的专属 AI 助手 ,我们介绍了如何去搭建一…...
数据分析实战—鸢尾花数据分类
1.实战内容 (1) 加载鸢尾花数据集(iris.txt)并存到iris_df中,使用seaborn.lmplot寻找class(种类)项中的异常值,其他异常值也同时处理 。 import pandas as pd from sklearn.datasets import load_iris pd.set_option(display.max_columns, N…...
【专题】2024抖音电商母婴行业分析报告汇总PDF洞察(附原数据表)
原文链接:https://tecdat.cn/?p38651 在数字化浪潮的席卷下,抖音电商母婴行业正经历着深刻变革。当下,年轻一代父母崛起,特别是 24 至 30 岁以及 18 至 23 岁的群体成为抖音母婴行业兴趣人群的主力军。他们带来全新育儿理念&…...
堆栈粉碎的原理与预防攻击措施
1、堆栈粉碎的原理 “堆栈粉碎”(stack smashing)指的是在计算机程序中利用缓冲区溢出漏洞来修改或破坏函数调用栈的过程。以下是其基本原理: 缓冲区溢出:当程序接收输入数据时,如果没有适当的边界检查和验证&#x…...
Flutter组件————AppBar
AppBar 是 Flutter 中用于创建应用程序顶部栏的组件,它遵循 Material Design 规范。 参数: 参数名称类型描述titleWidget设置 AppBar 中的标题文本或自定义标题小部件。automaticallyImplyLeadingbool决定是否自动添加返回按钮(如果页面不是…...
全志V853双核开发实战:RISC-V E907小核启动与Linux-RTOS通信详解
1. 项目概述:在V853-PRO上启动RISC-V E907小核最近在折腾100ASK_V853-PRO这块开发板,它搭载的全志V853芯片有个挺有意思的特性:集成了Arm Cortex-A7大核和RISC-V E907小核的双CPU架构。这颗玄铁E907小核,本质上是一个完全可综合的…...
Cursor智能体工具包:从AI编程助手到自主规划开发伙伴
1. 项目概述:一个为AI编程助手赋能的智能工具包如果你和我一样,日常重度依赖Cursor这类AI编程助手,那你肯定也经历过这样的时刻:面对一个复杂的重构任务,你不得不把需求拆成十几条指令,一条条喂给AI&#x…...
数据库查询语句的封装思路
import yamldef yamlread(path): # 打开并读取YAML文件with open(path, r, encodingutf-8) as file:config yaml.safe_load(file)return configc创建一个文件操作方法读取文件信息class dboperations:def __init__(self, config_pathrD:\PycharmProjects\PythonProject\config…...
信息熵计算库entroly:从原理到实践,量化数据不确定性的利器
1. 项目概述:一个被低估的熵工具库如果你在数据处理、信息论或者机器学习领域摸爬滚打过一段时间,大概率会和我一样,对“熵”这个概念又爱又恨。爱的是,它作为衡量不确定性、信息量乃至系统混乱度的核心指标,在特征选择…...
ARM GICv3中断控制器架构与ICC_CTLR_EL3寄存器解析
1. ARM GICv3中断控制器架构概述在现代处理器架构中,中断控制器是连接外设与CPU核心的关键枢纽。ARM的通用中断控制器(Generic Interrupt Controller, GIC)经过多代演进,GICv3架构在虚拟化支持、多安全域管理和扩展性方面实现了显著提升。作为GICv3的核心…...
Java——文件和目录操作
文件和目录操作1、构造方法2、文件元数据3、文件操作4、目录操作1、构造方法 File既可以表示文件,也可以表示目录,它的主要构造方法有: //pathname表示完整路径,该路径可以是相对路径,也可以是绝对路径 public File(…...
从编码到网络:GLM模型在图论分析中的实战指南
1. GLM模型与图论分析的完美结合 第一次接触GLM模型是在分析脑网络数据时,当时手头有一批健康人和患者的脑功能连接数据,需要找出两组间的差异。传统方法只能逐个节点比较,效率低下且容易漏掉整体网络特征。直到发现GLM模型可以完美融入图论分…...
copy4ai:专为AI工作流设计的智能复制工具,解决网页内容格式粘贴难题
1. 项目概述:一个为AI工作流设计的智能复制工具最近在折腾各种AI工具链的时候,我经常遇到一个挺烦人的问题:想把网页上的一段代码、一个表格,或者是一段带有特殊格式的文本,原封不动地喂给ChatGPT或者Claude࿰…...
GBase 8s 之 dbschema 导出数据库对象定义介绍
在数据库管理和开发过程中,经常需要导出数据库对象的定义,以便进行备份、迁移或分析。GBase 8s 提供了 dbschema 工具,能够方便地导出各种数据库对象的定义。本文将详细介绍 dbschema 的使用方法,帮助你快速掌握这一实用工具。…...
第十一篇:《性能压测基础:JMeter线程模型与压测策略设计》
完成了接口功能测试后,我们将正式进入性能压测领域。性能压测的核心是模拟真实用户并发访问,评估系统在不同负载下的响应能力。本文将从 JMeter 的线程模型出发,讲解如何设计合理的压测策略(基准测试、负载测试、稳定性测试&#…...
