当前位置: 首页 > news >正文

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,识别校验身份证。

http://www.lryc.cn/news/507168.html

相关文章:

  • SQL Server通过存储过程实现自定义邮件格式并定时发送
  • 【进阶编程】MVC和MVVM实现前后端分离的实现
  • HT81297 18W内置升压单声道D类音频功放
  • linux ipmitool配置机器的BMC(服务器管理后台)
  • 【项目实战】location.href 实现文件下载
  • 【Threejs】从零开始(十)--加载gltf模型和压缩后的模型
  • 国标GB28181平台EasyGBS在安防视频监控中的信号传输(电源/视频/音频)特性及差异
  • Day9 神经网络的偏导数基础
  • day4:tomcat—maven-jdk
  • apache-tomcat-6.0.44.exe Win10
  • Redis(2)常用命令
  • 【原生js案例】ajax的简易封装实现后端数据交互
  • 安卓环境配置及打开新项目教程,2024年12月20日最新版
  • Docker 安装 禅道-21.2版本-外部数据库模式
  • 写SQL太麻烦?免费搭建 Text2SQL 应用,智能写 SQL | OceanBase AI 实践
  • 数据分析实战—鸢尾花数据分类
  • 【专题】2024抖音电商母婴行业分析报告汇总PDF洞察(附原数据表)
  • 堆栈粉碎的原理与预防攻击措施
  • Flutter组件————AppBar
  • 请问深度学习直接缝了别的模型,在论文中这种创新点应该如何描述呢?
  • 微流控专题 | 微流体应用说明——藻酸盐微球生产简介
  • 【前后端】HTTP网络传输协议
  • Fastdfs V6.12.1集群部署(arm/x86均可用)
  • 【LeetCode每日一题】——434.字符串中的单词数
  • windows C#-使用构造函数
  • [react]redux异步处理和重写useDispatch
  • 基础数据结构---栈
  • 【HarmonyOS之旅】DevEco Studio的安装与环境配置
  • Liveweb视频融合共享平台在果园农场等项目中的视频监控系统搭建方案
  • Android4.4 在系统中添加自己的System Service