百度OCR文字识别开发平台接口调试和切图

百度文字识别(OCR)开放平台接口调试

本篇不介绍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

调试过程记录
  1. 刚开始使用apiexplorer在线调试的时候会因为参数格式问题会报一些奇怪的错误,即使API文档是给出了很详细的错误码信息对照,但还是建议直接使用POSTMAN或者代码直接调用。
  2. 对于各种类型的识别接口,在识别率和调用的可配参数上,都大致相同,可以根据实际的需求场景选择并进行API的调用和调试。官方文档对于参数的说明很详细,可以自己实际调用之前体验其中的区别。
代码调试结果
方式一(集成使用):

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为原图的宽高;
方式二(初步调试使用): apiexplorer代码集成(按照官方提供的demo即可前提是先引入以下maven依赖)

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

你可能感兴趣的:(JAVA,工具使用,百度,人工智能)