OCR 识别文字项目

该项目 可以进行两种方式进行身份证识别

1. 使用百度接口

1.1 application-dev.yml配置

ocr:
# 使用baiduOcr 需要有Ocr服务器 使用百度需要相应的百度账号即可
useOcrType: baiduOcr
# 需要OCR 的文件夹
ocrFolderPath: E:\ocr-wait-image\16210910333-8e2fa7f52db04a538ed584c919ce33b1
# 需要OCR 的文件
ocrFile: H:\Desktop\test\14.jpg
# 百度OCR 配置 https://cloud.baidu.com/doc/OCR/s/Nkibizxlf
baiduOcr:
# 使用token 形式
useToken: false
# 使用卡证识别接口 卡证识别一天500次免费(识别率高推荐) 通用识别50000次免费(识别率较低)
useIdCard: true
# 使用token 形式调用接口 token 通过接口获取(推荐使用sdk模式)
token: XXXXXXXX
idCardUrl: https://aip.baidubce.com/rest/2.0/ocr/v1/idcard
idCardPrefix: id_card_side=front&image=
generalBasicUrl: https://aip.baidubce.com/rest/2.0/ocr/v1/general_basic
generalBasicPrefix: image=
# 不使用token sak形式调用接口(通过百度账号创建应用获取)
appId: XXXXXXXXXX
apiKey: XXXXXXXXXX
secretKey: XXXXXXXXXX
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23

1.2 创建百度应用

填入必填项即可

再次出来即有一个创建的应用

以上配置的appId,apiKey,secretKey 三项在这里获取

1.3 结果显示

获得结果会保存在这个文件夹

1.3 使用百度免费OCR 项目配置结束

1.4 主要代码展示

package com.ocr.baidu;

import com.baidu.aip.ocr.AipOcr;
import com.framework.config.OcrConfig;
import com.utils.Base64Util;
import com.utils.FileUtil;
import com.utils.HttpUtil;
import lombok.extern.slf4j.Slf4j;
import org.json.JSONObject; import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.HashMap; @Slf4j
public class BaiduOCRUtils {
/**
* 卡证识别
*/
public static String idCardByToken(OcrConfig.BaiduOcr baiduOcr,String filePath) {
String idCardPrefix = baiduOcr.getIdCardPrefix();
String idCardUrl = baiduOcr.getIdCardUrl();
String token = baiduOcr.getToken();
// 请求url
try {
// 本地文件路径 byte[] imgData = FileUtil.readFileByBytes(filePath);
String imgStr = Base64Util.encode(imgData);
String imgParam = URLEncoder.encode(imgStr, StandardCharsets.UTF_8.name()); String param = idCardPrefix + imgParam;
// 注意这里仅为了简化编码每一次请求都去获取access_token,线上环境access_token有过期时间, 客户端可自行缓存,过期后重新获取。
return HttpUtil.post(idCardUrl, token, param);
} catch (Exception e) {
log.error(e.getMessage());
e.printStackTrace();
}
return null;
} /**
* 通用文字识别
*/
public static String generalBasicByToken(OcrConfig.BaiduOcr baiduOcr,String filePath) {
String generalBasicPrefix = baiduOcr.getGeneralBasicPrefix();
String generalBasicUrl = baiduOcr.getGeneralBasicUrl();
String token = baiduOcr.getToken();
// 请求url
try {
// 本地文件路径
byte[] imgData = FileUtil.readFileByBytes(filePath);
String imgStr = Base64Util.encode(imgData);
String imgParam = URLEncoder.encode(imgStr, StandardCharsets.UTF_8.name()); String param = generalBasicPrefix + imgParam;
// 注意这里仅为了简化编码每一次请求都去获取access_token,线上环境access_token有过期时间, 客户端可自行缓存,过期后重新获取。
return HttpUtil.post(generalBasicUrl, token, param);
} catch (Exception e) {
log.error(e.getMessage());
e.printStackTrace();
}
return null;
} /**
* 通用文字识别 sdk
*/
public static JSONObject generalBasicBySdk(OcrConfig.BaiduOcr baiduOcr,String filePath) {
String appId = baiduOcr.getAppId();
String apiKey = baiduOcr.getApiKey();
String secredKey = baiduOcr.getSecretKey();
AipOcr client = new AipOcr(appId, apiKey, secredKey);
// 可选:设置网络连接参数
client.setConnectionTimeoutInMillis(2000);
client.setSocketTimeoutInMillis(60000);
return client.basicGeneral(filePath, new HashMap<>());
}
/**
* 身份证文字识别 sdk
*/
public static JSONObject idCardBySdk(OcrConfig.BaiduOcr baiduOcr,String filePath) {
String appId = baiduOcr.getAppId();
String apiKey = baiduOcr.getApiKey();
String secredKey = baiduOcr.getSecretKey();
AipOcr client = new AipOcr(appId, apiKey, secredKey);
// 可选:设置网络连接参数
client.setConnectionTimeoutInMillis(2000);
client.setSocketTimeoutInMillis(60000);
return client.idcard(filePath,"front", new HashMap<>());
}
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93

2. 使用百度开源项目PaddleHub

PS: 识别通过paddle(python 运行) ,JAVA 进行结果处理

2.1 按照教程安装PaddleHub

2.2 application-dev.yml配置

ocr:
paddleOcr:
# 使用本地
url: 192.168.0.106
port: 8866
moduleMap:
# 文字识别OCR 安装 https://www.paddlepaddle.org.cn/hubdetail?name=chinese_ocr_db_crnn_mobile&en_category=TextRecognition
chinese_ocr_db_crnn_mobile: 1.1.1
# 人脸识别OCR(识别身份证正面或手持身份证) 安装 https://www.paddlepaddle.org.cn/hubdetail?name=pyramidbox_lite_server&en_category=FaceDetection
pyramidbox_lite_server: 1.2.0
# 是否分析
analysis: false
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

2.3 结果显示

获得结果会保存在这个文件夹

2.4 主要代码展示

package com.ocr.paddle;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.google.common.collect.Lists;
import com.ocr.paddle.domain.LocalHubOcrResultDTO;
import com.ocr.paddle.domain.OCRHubResultDTO;
import com.utils.Base64Util;
import com.utils.FileUtil;
import com.utils.HttpClientUtils;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils; import java.io.File;
import java.io.IOException;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors; @Slf4j
public class LocalHubOcrUtils { public static List<LocalHubOcrResultDTO> localAllOcr(String textUrl, String faceUrl, List<File> allFiles) {
long l = System.currentTimeMillis();
List<LocalHubOcrResultDTO> localOcrResultDTOList = Lists.newArrayList();
int urlCount = 0;
boolean useTextUrl = false;
boolean useFaceUrl = false;
if (StringUtils.isEmpty(textUrl)) {
log.info("不进行文字识别");
} else {
urlCount++;
useTextUrl = true;
log.info("需要进行文字识别");
}
if (StringUtils.isEmpty(faceUrl)) {
log.info("不进行人脸识别");
} else {
urlCount++;
useFaceUrl = true;
log.info("需要进行人脸识别");
}
int ocrCount = allFiles.size() * urlCount;
log.info("预估进行OCR" + ocrCount + "次");
if (ocrCount == 0) {
return localOcrResultDTOList;
} int textIndex = 0;
int faceIndex = 0;
// 本地文件路径
Map<String, String> partentFile = allFiles.stream().collect(Collectors.toMap(File::getName, File::getParent, (e1, e2) -> e1));
for (File imageFile : allFiles) {
List<OCRHubResultDTO> ocrHubResultDTOS = Lists.newArrayList(); byte[] imgData = new byte[0];
try {
imgData = FileUtil.readFileByBytes(imageFile);
} catch (IOException e) {
log.error("图片读取错误");
continue;
}
String imgStr = Base64Util.encode(imgData);
JSONObject jsonObject = new JSONObject();
List<String> imageParams = Lists.newArrayList();
imageParams.add(imgStr);
jsonObject.put("images", imageParams); String textResult = "";
if (useTextUrl) {
textResult = HttpClientUtils.sendJsonStr(textUrl, jsonObject.toJSONString());
textIndex++;
log.info("已进行文字OCR" + textIndex + "次");
if (StringUtils.isEmpty(textResult)) {
log.error("获取文字接口失败");
log.info("还需进行" + (ocrCount - faceIndex - textIndex) + "次");
continue;
}
JSONObject resultTest = (JSONObject) JSONObject.parse(textResult);
JSONArray textResultsArray = resultTest.getJSONArray("results");
if (textResultsArray == null){
log.error("返回值错误,错误信息为:" + textResult);
} for (Object o : textResultsArray) {
JSONObject j = (JSONObject) o;
JSONArray data = j.getJSONArray("data");
for (Object datum : data) {
JSONObject jo = (JSONObject) datum;
jo.remove("text_box_position");
OCRHubResultDTO ocrHubResultDTO = jo.toJavaObject(OCRHubResultDTO.class);
ocrHubResultDTOS.add(ocrHubResultDTO);
}
} }
int faceCount = 0;
String faceResult = "";
if (useFaceUrl) {
faceResult = HttpClientUtils.sendJsonStr(faceUrl, jsonObject.toJSONString());
faceIndex++;
log.info("已进行人脸OCR" + faceIndex + "次");
if (StringUtils.isEmpty(faceResult)) {
log.error("获取人脸识别接口失败");
log.info("还需进行" + (ocrCount - faceIndex - textIndex) + "次");
continue;
}
JSONObject resultFace = (JSONObject) JSONObject.parse(faceResult);
JSONArray faceResultsArray = resultFace.getJSONArray("results");
for (Object o : faceResultsArray) {
JSONObject j = (JSONObject) o;
JSONArray data = j.getJSONArray("data");
faceCount = data.size();
}
} log.info("还需进行" + (ocrCount - faceIndex - textIndex) + "次");
localOcrResultDTOList.add(new LocalHubOcrResultDTO(imageFile.getAbsolutePath(), imageFile.getParent(), ocrHubResultDTOS, faceCount));
}
log.info("OCR 总耗时" + (System.currentTimeMillis() - l) / 1000 + "S");
log.info("OCR 次数" + ocrCount + "次");
log.info("OCR 平均耗时" + (System.currentTimeMillis() - l) / 1000 / ocrCount + "s");
return localOcrResultDTOList;
} private static void func(File file, List<File> fileList) {
File[] fs = file.listFiles();
for (File f : fs) {
if (f.isDirectory()) {
//若是目录,则递归打印该目录下的文件
func(f, fileList);
}
if (f.isFile()) {
String imageName = f.getName();
boolean isJpg = imageName.endsWith(".jpg");
boolean isJPG = imageName.endsWith(".JPG");
boolean isPng = imageName.endsWith(".png");
if (isJPG || isPng || isJpg) {
//若是图片加入列表
fileList.add(f);
}
}
}
}
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
  • 109
  • 110
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146

sJpg = imageName.endsWith(".jpg");
boolean isJPG = imageName.endsWith(".JPG");
boolean isPng = imageName.endsWith(".png");
if (isJPG || isPng || isJpg) {
//若是图片加入列表
fileList.add(f);
}
}
}
}
}

原文章:https://blog.csdn.net/AirOrange_qi/article/details/112102739

JAVA 进行图片中文字识别(准确度高)!!!的更多相关文章

  1. JAVA的图片文字识别技术

    从2013年的记录看,JAVA中图片文字识别技术大部分采用ORC的tesseract的软件功能,后来渐渐开放了java-api调用接口. 图片文字识别技术,还是采用训练的方法.并未从根本上解决图片与文 ...

  2. java实现图片文字识别的两种方法

    一.使用tesseract-ocr 1.    https://github.com/tesseract-ocr/tesseract/wiki上下载安装包安装和简体中文训练文件 window64位安装 ...

  3. 识别率很高的java文字识别技术

    java文字识别程序的关键是寻找一个可以调用的OCR引擎.tesseract-ocr就是一个这样的OCR引擎,在1985年到1995年由HP实验室开发,现在在Google.tesseract-ocr ...

  4. 【图片识别】java 图片文字识别 ocr (转)

    http://www.cnblogs.com/inkflower/p/6642264.html 最近在开发的时候需要识别图片中的一些文字,网上找了相关资料之后,发现google有一个离线的工具,以下为 ...

  5. java 图片文字识别 ocr

    最近在开发的时候需要识别图片中的一些文字,网上找了相关资料之后,发现google有一个离线的工具,以下为java使用的demo 在此之前,使用这个工具需要在本地安装OCR工具: 下面一个是一定要安装的 ...

  6. Java文字识别软件-调用百度ocr实现文字识别

    java_baidu_ocr Java调用百度OCR文字识别API实现图片文字识别软件 这是一款小巧方便,强大的文字识别软件,由Java编写,配上了窗口界面 调用了百度ocr文字识别API 识别精度高 ...

  7. 识别图片中文字(百度AI)

     这个是百度官方的文档         https://ai.baidu.com/docs#/OCR-API/top    通用的文字识别,如果是其他的含生僻字/含位置信息的版本,请参考官方的文档,只 ...

  8. Android OCR文字识别 实时扫描手机号(极速扫描单行文本方案)

    身份证识别:https://github.com/wenchaosong/OCR_identify 遇到一个需求,要用手机扫描纸质面单,获取面单上的手机号,最后决定用tesseract这个开源OCR库 ...

  9. 借@阿里巴巴 耍了个帅——HTML5 JavaScript实现图片文字识别与提取

    写在前面 8月底的时候,@阿里巴巴 推出了一款名为“拯救斯诺克”的闯关游戏,作为前端校园招聘的热身,做的相当不错,让我非常喜欢.后来又传出了一条消息,阿里推出了A-star(阿里星)计划,入职阿里的技 ...

随机推荐

  1. poj2112 二分最大流+Floyd

    题意:      一个农场主有一些奶牛,和一些机器,每台机器有自己的服务上限,就是一天最多能给多少头奶牛挤奶,给你任意两点的距离,问你让所有的奶牛都被挤奶时,奶牛于机器最远距离的最近是多少. 思路: ...

  2. Portswigger web security academy:DOM-based vulnerabilities

    DOM-based vulnerabilities 目录 DOM-based vulnerabilities 1 - DOM XSS using web messages 2 - DOM XSS us ...

  3. Cauchy-Binet 公式的应用

    Binet-Cauchy 公式 我们知道,方阵的行列式不是方阵的线性函数,即对 \(\forall \lambda\in F,A,B\in F^{n\times n}\),有 \(det(A+B)\n ...

  4. jdk8-stream-api

    1.stream简介 stream 是一个用来处理集合个数组的api jdk 8 引入strream的原因:1.去掉for循环,使编程变的更加简单(实际运行效率可能没有for循环高)2.paralle ...

  5. 前端用网址生成二维码(jquery)

    1.加载jquery.qrcode.min.js 2.html部分: 3.js部分:url为生成二维码的网址 附: jquery.qrcode.min.js下载 链接:https://pan.baid ...

  6. Newtonsoft.Json的使用整理

    关于我 我的博客 | 欢迎关注 引言 json是我们在工作中经常用到的一种数据传输格式,开始过程中解析json是我们经常面对的问题.NewtonsoftJson是c#的一套json处理封装类,它可以高 ...

  7. C++ scanf_s()函数的用法以及注意事项

    前身--scanf() 有的教材里用的scanf(),其实在目前Visual Studio版本中已经弃用了,用scanf_s()函数代替了. 为什么现在要用scanf_s() scanf_s()函数是 ...

  8. 依赖倒置原则(Dependence Inversion Principle)

    目录 背景 说明 例子 "倒置"的解释 总结 参考资料 背景 这几天组内的人一起学习DDD,里面再次提到了依赖倒置原则,在这学习过程中,大家又讨论了一下依赖倒置原则. 说明 采用依 ...

  9. 联想ThinkServer服务器安装CentOS7 Redhat7系统 驱动R110i RAID卡

    1.下载对应版本的驱动(因为联想没有CentOS的驱动用redhat的驱动就可以). 2.进入BIOS里,在高级设置里找到SATA设置,把SATA模式改成RAID(重启后配置raid),sSATA模式 ...

  10. 安装SpecCPU2006 on Linux of CentOS6.3, gcc4.4.7

    安装SpecCPU2006 on Linux of CentOS6.3, gcc4.4.7 由于在tools/bin目录中只有ia64-linux,所以在直接运行./install.sh脚本时,系统会 ...