本篇不介绍OCR的基本概念和底层原理,专注于使用第三方识别接口 百度OCR的使用。学习笔记来源于项目需求前期,场景验证。现有的开放平台集成已经非常简单和便捷。
需求场景:识别word文档图片,根据识别内容进行图片切图,然后根据识别的文字进行业务处理和内容校验。
百度OCR文字识别接口服务 ,根据识别场景的分类,将接口分为了几大行业领域的几十个开发接口。都是百度设置不同的场景将识别进行AI识别训练的接口,继而区分出了众多的识别接口,也支持各种主流开发语言集成。主要包含以下领域:通用场景文字识别、卡证文字识别、交通场景文字识别、财务票据文字识别、医疗票据文字识别、防疫场景文字识别、教育场景文字识别、其他场景文字识别、文档图像处理
具体内容可以移步官网进行了解: https://ai.baidu.com/ai-doc/OCR/Ek3h7xypm
在线体验地址: https://ai.baidu.com/tech/ocr/doc_analysis_office
在线请求详情体验地址:https://cloud.baidu.com/apiexplorer/index.html?Product=GWSE-DJAQ8YwekkQ&Api=GWAI-vYe93owiBj5
开放平台账号登录,开通OCR文字识别服务应用(不用充钱,对于个人或者企业提供一定数量的识别次数)
获取权限(获取API Key、Secret Key 密钥),具体步骤参考: https://ai.baidu.com/ai-doc/REFERENCE/Ck3dwjhhu
选择想要使用的识别接口,按照API文档进行调试。
以上三个步骤重点在于第三步,详细步骤可参照这篇文章: https://ai.baidu.com/forum/topic/show/867951
maven:(具体版本可以在官方找到想要使用的版本)
<dependency>
<groupId>com.baidu.aipgroupId>
<artifactId>java-sdkartifactId>
<version>4.16.9version>
dependency>
官方文档说明,参考如下代码新建一个AipOcr,初始化完成后建议单例使用,避免重复获取access_token: 。
import com.baidu.aip.ocr.AipOcr;
/**
* @Description
* @Date 2022-08-10
*/
public class AipOcrSingleton {
public static volatile AipOcr aipOcr = null;
//设置APPID/AK/SK
public static final String APP_ID = "26970013";
public static final String API_KEY = "OoF9qweE2eRGkKVwTUlSfXzA";
public static final String SECRET_KEY = "nxBrToFnBBkGrlpzjsT5BfqxsI0BGocN";
public static final int CONNECTION_TIME_OUT = 2000;//建立连接的超时时间(单位:毫秒)
public static final int SOCKET_TIME_OUT = 6000;//通过打开的连接传输数据的超时时间(单位:毫秒)
private AipOcrSingleton(){}
public static AipOcr getAipOcr(){
if(aipOcr == null){
synchronized (AipOcrSingleton.class){
if(aipOcr == null){
aipOcr = new AipOcr(APP_ID, API_KEY, SECRET_KEY);
// 可选:设置网络连接参数
aipOcr.setConnectionTimeoutInMillis(CONNECTION_TIME_OUT);
aipOcr.setSocketTimeoutInMillis(SOCKET_TIME_OUT);
//setHttpProxy 设置http代理服务器
//setSocketProxy 设置socket代理服务器 (http和socket类型代理服务器只能二选一)
}
}
}
return aipOcr;
}
}
demo代码:
import com.baidu.aip.ocr.AipOcr;
import org.apache.commons.collections4.MapUtils;
import org.json.JSONObject;
import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* @Description
* @Date 2022-08-10
*/
public class BaiduOcrOffice {
public static void main(String[] args) throws IOException {
// 初始化一个AipOcr
AipOcr client = AipOcrSingleton.getAipOcr();
// 可选:设置代理服务器地址, http和socket二选一,或者均不设置
//client.setHttpProxy("proxy_host", proxy_port); // 设置http代理
//client.setSocketProxy("proxy_host", proxy_port); // 设置socket代理
// 传入可选参数调用接口
HashMap<String, Object> options = new HashMap<String, Object>();
options.put("access_token","申请的access_token(必填)");
//options.put("language_type", "CHN_ENG");
//options.put("detect_direction", "true");
//options.put("detect_language", "true");
options.put("probability", "true");
//调用接口: 办公文档文字识别, 图片参数为本地图片的全路径,client可以选择不同的接口调用
String url = "G:\\work\\学习\\百度ocr\\测试图片2.jpg";
JSONObject resObj = client.docAnalysisOffice(url, options);
System.out.println(resObj.toString(2));
int results_num = resObj.getInt("results_num");
List<Object> resultsList = resObj.getJSONArray("results").toList();
//-------------以上内容基本调用就已经结束了,以下部分为本人实际业务需求验证-------------
//根据识别的文字图片坐标进行数据的进行图片切分
BufferedImage imgs[] = new BufferedImage[results_num];
FileInputStream fis = new FileInputStream(url);
BufferedImage image = ImageIO.read(fis);
int imageWidth = image.getWidth();
int imageHeight = image.getHeight();
System.out.println("图片的宽度为:" + imageWidth + "图片的高度为:" + imageHeight);
System.out.println(results_num);
int count = 0;
for (Object o : resultsList) {
Map wordMap = (Map) o;
//print 机打体, handwriting 手写
String type = MapUtils.getString(wordMap, "words_type", "");
Map words = MapUtils.getMap(wordMap, "words");
Map wordsLocationMap = MapUtils.getMap(words, "words_location");
String word = MapUtils.getString(words, "word", "");
int top = MapUtils.getIntValue(wordsLocationMap, "top");
int left = MapUtils.getIntValue(wordsLocationMap, "left");
int width = MapUtils.getIntValue(wordsLocationMap, "width");
int height = MapUtils.getIntValue(wordsLocationMap, "height");
//设置小图的大小和类型
imgs[count] = new BufferedImage(width, height, image.getType());
System.out.println("宽度:" + width + ", 高度:" + height);
System.out.println("文字内容: " + word);
//写入图像内容
Graphics2D gr = imgs[count++].createGraphics();
//此处的参数以下有详解
gr.drawImage(image, - left, - top, imageWidth, imageHeight, 0, 0, imageWidth, imageHeight, null);
gr.dispose();
}
// 输出小图
for (int i = 0; i < imgs.length; i++) {
ImageIO.write(imgs[i], "jpg", new File("G:\\work\\学习\\百度识别\\word2\\" + i + ".jpg"));
}
System.out.println("完成分割!");
}
}
drawImage参数详解:
public abstract boolean drawImage(Image img,
int dx1, int dy1, int dx2, int dy2,
int sx1, int sy1, int sx2, int sy2,
ImageObserver observer);
img: 为原图
dx1,dy1,dx2,dy2: 为目标切图的坐标和宽高信息,
dx1和dy1为切图相对于原图的左上角的起始坐标;
dx2和dy2为应该为切图的宽高(但是在实际调试的过程中, 设置为 原图的宽高才有效);
sx1,sy1,sx2,sy2: 为原图的坐标和宽高信息(按照原理来说,原图的作为参考源,坐标应该为(0,0))
sx1和sy1为原图的原图七点(0,0)
sx2和sy2为原图的宽高;
maven:
<dependency>
<groupId>com.baidubcegroupId>
<artifactId>api-explorer-sdkartifactId>
<version>1.0.3.1version>
dependency>
demo代码:
import com.baidubce.http.ApiExplorerClient;
import com.baidubce.http.HttpMethodName;
import com.baidubce.model.ApiExplorerRequest;
import com.baidubce.model.ApiExplorerResponse;
// 通用文字识别-高精度含位置版 示例代码
public class RequestDemo {
public static void main(String[] args) {
//具体识别接口路径
String path = "https://aip.baidubce.com/rest/2.0/ocr/v1/accurate";
ApiExplorerRequest request = new ApiExplorerRequest(HttpMethodName.POST, path);
// 设置header参数
request.addHeaderParameter("Content-Type", "application/x-www-form-urlencoded;charset=UTF-8");
// 设置query参数
request.addQueryParameter("access_token", "自己申请的access_token");
// 设置jsonBody参数
String jsonBody = "url=https:\/\/baidu-ai.bj.bcebos.com\/ocr\/ocr.jpg&language_type=CHN_ENG&detect_direction=false¶graph=false&probability=false";
request.setJsonBody(jsonBody);
ApiExplorerClient client = new ApiExplorerClient();
try {
ApiExplorerResponse response = client.sendRequest(request);
// 返回结果格式为Json字符串
System.out.println(response.getResult());
} catch (Exception e) {
e.printStackTrace();
}
}
}
主要参数说明:
参数名称 | 参数类型 | 是否必须 | 描述 | 示例值 |
---|---|---|---|---|
image | String | 否 | 图像数据,base64编码后进行urlencode,要求base64编码和urlencode后大小不超过10M,最短边至少15px,最长边最大8192px,支持jpg/jpeg/png/bmp格式 优先级:image > url > pdf_file,当image字段存在时,url、pdf_file字段失效 | null |
url | String | 否 | 图片完整url,url长度不超过1024字节,url对应的图片base64编码后大小不超过10M,最短边至少15px,最长边最大8192px,支持jpg/jpeg/png/bmp格式 优先级:image > url > pdf_file,当image字段存在时,url字段失效 请注意关闭URL防盗链 | null |
pdf_file | String | 否 | PDF文件,base64编码后进行urlencode,要求base64编码和urlencode后大小不超过10M,最短边至少15px,最长边最大8192px 优先级:image > url > pdf_file,当image、url字段存在时,pdf_file字段失效 | null |
pdf_file_num | String | 否 | 需要识别的PDF文件的对应页码,当 pdf_file 参数有效时,识别传入页码的对应页面内容,若不传入,则默认识别第 1 页 | null |
本文参考文档:
https://blog.csdn.net/qq_33333654/article/details/102720273
https://ai.baidu.com/forum/topic/show/956849
https://ai.baidu.com/forum/topic/show/867951
https://blog.csdn.net/zxx862309181/article/details/124254093