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决定是否自动添加返回按钮(如果页面不是…...
利用最小二乘法找圆心和半径
#include <iostream> #include <vector> #include <cmath> #include <Eigen/Dense> // 需安装Eigen库用于矩阵运算 // 定义点结构 struct Point { double x, y; Point(double x_, double y_) : x(x_), y(y_) {} }; // 最小二乘法求圆心和半径 …...
【OSG学习笔记】Day 18: 碰撞检测与物理交互
物理引擎(Physics Engine) 物理引擎 是一种通过计算机模拟物理规律(如力学、碰撞、重力、流体动力学等)的软件工具或库。 它的核心目标是在虚拟环境中逼真地模拟物体的运动和交互,广泛应用于 游戏开发、动画制作、虚…...
SCAU期末笔记 - 数据分析与数据挖掘题库解析
这门怎么题库答案不全啊日 来简单学一下子来 一、选择题(可多选) 将原始数据进行集成、变换、维度规约、数值规约是在以下哪个步骤的任务?(C) A. 频繁模式挖掘 B.分类和预测 C.数据预处理 D.数据流挖掘 A. 频繁模式挖掘:专注于发现数据中…...
Qt Widget类解析与代码注释
#include "widget.h" #include "ui_widget.h"Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget) {ui->setupUi(this); }Widget::~Widget() {delete ui; }//解释这串代码,写上注释 当然可以!这段代码是 Qt …...
渲染学进阶内容——模型
最近在写模组的时候发现渲染器里面离不开模型的定义,在渲染的第二篇文章中简单的讲解了一下关于模型部分的内容,其实不管是方块还是方块实体,都离不开模型的内容 🧱 一、CubeListBuilder 功能解析 CubeListBuilder 是 Minecraft Java 版模型系统的核心构建器,用于动态创…...
微服务商城-商品微服务
数据表 CREATE TABLE product (id bigint(20) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT 商品id,cateid smallint(6) UNSIGNED NOT NULL DEFAULT 0 COMMENT 类别Id,name varchar(100) NOT NULL DEFAULT COMMENT 商品名称,subtitle varchar(200) NOT NULL DEFAULT COMMENT 商…...
Device Mapper 机制
Device Mapper 机制详解 Device Mapper(简称 DM)是 Linux 内核中的一套通用块设备映射框架,为 LVM、加密磁盘、RAID 等提供底层支持。本文将详细介绍 Device Mapper 的原理、实现、内核配置、常用工具、操作测试流程,并配以详细的…...
GC1808高性能24位立体声音频ADC芯片解析
1. 芯片概述 GC1808是一款24位立体声音频模数转换器(ADC),支持8kHz~96kHz采样率,集成Δ-Σ调制器、数字抗混叠滤波器和高通滤波器,适用于高保真音频采集场景。 2. 核心特性 高精度:24位分辨率,…...
代理篇12|深入理解 Vite中的Proxy接口代理配置
在前端开发中,常常会遇到 跨域请求接口 的情况。为了解决这个问题,Vite 和 Webpack 都提供了 proxy 代理功能,用于将本地开发请求转发到后端服务器。 什么是代理(proxy)? 代理是在开发过程中,前端项目通过开发服务器,将指定的请求“转发”到真实的后端服务器,从而绕…...
USB Over IP专用硬件的5个特点
USB over IP技术通过将USB协议数据封装在标准TCP/IP网络数据包中,从根本上改变了USB连接。这允许客户端通过局域网或广域网远程访问和控制物理连接到服务器的USB设备(如专用硬件设备),从而消除了直接物理连接的需要。USB over IP的…...
