置頂
AirOrange_qi
于 2021-01-02 16:21:01 發(fā)布
4178
收藏 45
分類專欄: java 文章標簽: paddlepaddle java ocr 百度
版權(quán)
java
專欄收錄該內(nèi)容
15 篇文章0 訂閱
訂閱專欄
OCR 識別文字項目
該項目 可以進行兩種方式進行身份證識別
1. 使用百度接口
1.1 application-dev.yml配置
ocr:
# 使用baiduOcr 需要有Ocr服務(wù)器 使用百度需要相應(yīng)的百度賬號即可
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 形式調(diào)用接口 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形式調(diào)用接口(通過百度賬號創(chuàng)建應(yīng)用獲?。?/p>
appId: XXXXXXXXXX
apiKey: XXXXXXXXXX
secretKey: XXXXXXXXXX
1.2 創(chuàng)建百度應(yīng)用
填入必填項即可
再次出來即有一個創(chuàng)建的應(yīng)用
以上配置的appId,apiKey,secretKey 三項在這里獲取
1.3 結(jié)果顯示
獲得結(jié)果會保存在這個文件夾
1.3 使用百度免費OCR 項目配置結(jié)束
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,線上環(huán)境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,線上環(huán)境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);
// 可選:設(shè)置網(wǎng)絡(luò)連接參數(shù)
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);
// 可選:設(shè)置網(wǎng)絡(luò)連接參數(shù)
client.setConnectionTimeoutInMillis(2000);
client.setSocketTimeoutInMillis(60000);
return client.idcard(filePath,"front", new HashMap<>());
}
}
2. 使用百度開源項目PaddleHub
PS: 識別通過paddle(python 運行) ,JAVA 進行結(jié)果處理
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
2.3 結(jié)果顯示
獲得結(jié)果會保存在這個文件夾
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("預(yù)估進行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 次數(shù)" + 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);
}
}
}
}
}
sJpg = imageName.endsWith(".jpg");
boolean isJPG = imageName.endsWith(".JPG");
boolean isPng = imageName.endsWith(".png");
if (isJPG || isPng || isJpg) {
//若是圖片加入列表
fileList.add(f);
}
}
}
}
}
————————————————
版權(quán)聲明:本文為CSDN博主「AirOrange_qi」的原創(chuàng)文章,遵循CC 4.0 BY-SA版權(quán)協(xié)議,轉(zhuǎn)載請附上原文出處鏈接及本聲明。
原文鏈接:https://blog.csdn.net/AirOrange_qi/article/details/112102739