工作中遇到一个需求是识别营业执照,看了阿里云的,腾讯云的,讯飞的,百度的。然后发现阿里云和腾讯云目前都是公测或者内测阶段,所以就去试了百度的,但是百度的只是普通的文字识别,就是识别文字中的图片,而讯飞的就比较专业了,单纯的识别营业执照。
先看一下使用百度的文字识别的步骤
百度AI开放平台的地址:https://ai.baidu.com/tech/ocr_cards/business
登录之后在右上角控制台创建一个应用,
创建完应用后点击管理应用
这里用AppId和两个key,后面代码里用到
需要引入的包
<dependency>
<groupId>com.baidu.aip</groupId>
<artifactId>java-sdk</artifactId>
<version>4.15.1</version>
</dependency>
<dependency>
<groupId>commons-codec</groupId>
<artifactId>commons-codec</artifactId>
<version>1.13</version>
</dependency>
代码实现:
把刚才的AppID和两个key放在对应的地方就行
package com.vhukze.utils;
import com.baidu.aip.ocr.AipOcr;
import org.json.JSONObject;
import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.util.HashMap;
/**
* 百度文字识别
*/
public class BaiDuDiscern {
//设置APPID/AK/SK
public static final String APP_ID = "";
public static final String API_KEY = "";
public static final String SECRET_KEY = "";
private static AipOcr client = null;
public static void main(String[] args) {
disPro();
}
public static void init(){
// 初始化一个AipOcr
if(client == null){
client = new AipOcr(APP_ID, API_KEY, SECRET_KEY);
}
// 可选:设置代理服务器地址, http和socket二选一,或者均不设置
// client.setHttpProxy("proxy_host", proxy_port); // 设置http代理
// client.setSocketProxy("proxy_host", proxy_port); // 设置socket代理
// 可选:设置log4j日志输出格式,若不设置,则使用默认配置
// 也可以直接通过jvm启动参数设置此环境变量
// System.setProperty("aip.log4j.conf", "path/to/your/log4j.properties");
// 调用接口
// String path = "test.jpg";
// JSONObject res = client.basicGeneral(path, new HashMap<String, String>());
// System.out.println(res.toString(2));
// 可选:设置网络连接参数
client.setConnectionTimeoutInMillis(2000);
client.setSocketTimeoutInMillis(60000);
}
//普通文字识别
public static void dis(){
init();
// 传入可选参数调用接口
HashMap<String, String> options = new HashMap<String, String>();
options.put("language_type", "CHN_ENG");
options.put("detect_direction", "true");
options.put("detect_language", "true");
options.put("probability", "true");
// 参数为本地图片路径
// String image = "C:\\Users\\zsz\\Desktop\\yyzz1.jfif";
// JSONObject res = client.basicGeneral(image, options);
// System.out.println(res.toString(2));
// 参数为本地图片二进制数组
byte[] file = getImageBinary("C:\\Users\\zsz\\Desktop\\yyzz1.jfif");
JSONObject res = client.basicGeneral(file, options);
System.out.println(res.toString(2));
// 通用文字识别, 图片参数为远程url图片
// JSONObject res = client.basicGeneralUrl("https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1604469311212&di=c0d7b582c196c8dba2061d920ed3bb28&imgtype=0&src=http%3A%2F%2F5b0988e595225.cdn.sohucs.com%2Fimages%2F20171119%2F97ecd36d67b24e34b850c61d744148e3.jpeg", options);
// System.out.println(res.toString(2));
}
//高精度版文字识别
public static void disPro(){
init();
// 传入可选参数调用接口
HashMap<String, String> options = new HashMap<String, String>();
options.put("detect_direction", "true");
options.put("probability", "true");
// 参数为本地图片路径
String image = "C:\\Users\\zsz\\Desktop\\yyzz1.jfif";
JSONObject res = client.basicAccurateGeneral(image, options);
System.out.println(res.toString(2));
// 参数为本地图片二进制数组
// byte[] file = getImageBinary(image);
// res = client.basicAccurateGeneral(file, options);
// System.out.println(res.toString(2));
}
private static byte[] getImageBinary(String path){
File f = new File(path);
BufferedImage bi;
try {
bi = ImageIO.read(f);
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ImageIO.write(bi, "jpg", baos);
byte[] bytes = baos.toByteArray();
return bytes;
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
}
但是百度的这个文字识别识别的不太好,有的文字错了 有的文字缺了
--------------------------------------------------------------------------------------------------------------------------------------------------------------------
下面看讯飞的营业执照识别
链接:https://www.xfyun.cn/services/businessLicenseRecg
点击免费试用,需要实名认证就认证一下
创建一个应用
这里面只有一个AppID和一个APIKey,这两个代码里面用到
直接上代码
package com.vhukze.utils;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.HashMap;
import java.util.Map;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.codec.digest.DigestUtils;
/**
* 讯飞营业执照识别
*/
public class XfDiscern {
// OCR webapi 接口地址
private static final String WEBOCR_URL = "http://webapi.xfyun.cn/v1/service/v1/ocr/business_license";
// 应用APPID(必须为webapi类型应用,并开通营业执照识别服务,参考帖子如何创建一个webapi应用:http://bbs.xfyun.cn/forum.php?mod=viewthread&tid=36481)
private static final String APPID = "";
// 接口密钥(webapi类型应用开通营业执照识别服务后,控制台--我的应用---营业执照识别---相应服务的apikey)
private static final String API_KEY = "";
// 引擎类型
private static final String ENGINE_TYPE = "business_license";
// 图片地址
private static final String AUDIO_PATH = "C:\\Users\\zsz\\Desktop\\yyzz1.jfif";
/**
* OCR WebAPI 调用示例程序
*
* @param args
* @throws IOException
*/
public static void main(String[] args) throws IOException {
dis();
}
public static void dis() throws IOException{
Map<String, String> header = buildHttpHeader();
byte[] imageByteArray = FileUtil.read(AUDIO_PATH);
String imageBase64 = new String(Base64.encodeBase64(imageByteArray), "UTF-8");
String result = HttpUtil.doPost1(WEBOCR_URL, header, "image=" + URLEncoder.encode(imageBase64, "UTF-8"));
System.out.println("WEB card 接口调用结果:" + result);//错误码链接:https://www.xfyun.cn/document/error-code (code返回错误码时必看)400开头错误码请在接口文档底部查看
}
/**
* 组装http请求头
*/
private static Map<String, String> buildHttpHeader() throws UnsupportedEncodingException {
String curTime = System.currentTimeMillis() / 1000L + "";
String param = "{\"engine_type\":\"" + ENGINE_TYPE + "\"}";
String paramBase64 = new String(Base64.encodeBase64(param.getBytes("UTF-8")));
String checkSum = DigestUtils.md5Hex(API_KEY + curTime + paramBase64);
Map<String, String> header = new HashMap<String, String>();
header.put("Content-Type", "application/x-www-form-urlencoded; charset=utf-8");
header.put("X-Param", paramBase64);
header.put("X-CurTime", curTime);
header.put("X-CheckSum", checkSum);
header.put("X-Appid", APPID);
return header;
}
}
里面还用到了两个工具类
FileUtil
package com.vhukze.utils;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
/**
* 文件操作工具类
*/
public class FileUtil {
/**
* 读取文件内容为二进制数组
*
* @param filePath
* @return
* @throws IOException
*/
public static byte[] read(String filePath) throws IOException {
InputStream in = new FileInputStream(filePath);
byte[] data = inputStream2ByteArray(in);
in.close();
return data;
}
/**
* 流转二进制数组
*
* @param in
* @return
* @throws IOException
*/
private static byte[] inputStream2ByteArray(InputStream in) throws IOException {
ByteArrayOutputStream out = new ByteArrayOutputStream();
byte[] buffer = new byte[1024 * 4];
int n = 0;
while ((n = in.read(buffer)) != -1) {
out.write(buffer, 0, n);
}
return out.toByteArray();
}
/**
* 保存文件
*
* @param filePath
* @param fileName
* @param content
*/
public static void save(String filePath, String fileName, byte[] content) {
try {
File filedir = new File(filePath);
if (!filedir.exists()) {
filedir.mkdirs();
}
File file = new File(filedir, fileName);
OutputStream os = new FileOutputStream(file);
os.write(content, 0, content.length);
os.flush();
os.close();
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
}
}
HttpUtil
package com.vhukze.utils;
import java.io.BufferedReader;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLConnection;
import java.util.HashMap;
import java.util.Map;
/**
* Http Client 工具类
*/
public class HttpUtil {
/**
* 发送post请求,根据 Content-Type 返回不同的返回值
*
* @param url
* @param header
* @param body
* @return
*/
public static Map<String, Object> doPost2(String url, Map<String, String> header, String body) {
Map<String, Object> resultMap = new HashMap<String, Object>();
PrintWriter out = null;
try {
// 设置 url
URL realUrl = new URL(url);
URLConnection connection = realUrl.openConnection();
HttpURLConnection httpURLConnection = (HttpURLConnection) connection;
// 设置 header
for (String key : header.keySet()) {
httpURLConnection.setRequestProperty(key, header.get(key));
}
// 设置请求 body
httpURLConnection.setDoOutput(true);
httpURLConnection.setDoInput(true);
out = new PrintWriter(httpURLConnection.getOutputStream());
// 保存body
out.print(body);
// 发送body
out.flush();
if (HttpURLConnection.HTTP_OK != httpURLConnection.getResponseCode()) {
System.out.println("Http 请求失败,状态码:" + httpURLConnection.getResponseCode());
return null;
}
// 获取响应header
String responseContentType = httpURLConnection.getHeaderField("Content-Type");
if ("audio/mpeg".equals(responseContentType)) {
// 获取响应body
byte[] bytes = toByteArray(httpURLConnection.getInputStream());
resultMap.put("Content-Type", "audio/mpeg");
resultMap.put("sid", httpURLConnection.getHeaderField("sid"));
resultMap.put("body", bytes);
return resultMap;
} else {
// 设置请求 body
BufferedReader in = new BufferedReader(new InputStreamReader(httpURLConnection.getInputStream()));
String line;
String result = "";
while ((line = in.readLine()) != null) {
result += line;
}
resultMap.put("Content-Type", "text/plain");
resultMap.put("body", result);
return resultMap;
}
} catch (Exception e) {
return null;
}
}
/**
* 发送post请求
*
* @param url
* @param header
* @param body
* @return
*/
public static String doPost1(String url, Map<String, String> header, String body) {
String result = "";
BufferedReader in = null;
PrintWriter out = null;
try {
// 设置 url
URL realUrl = new URL(url);
URLConnection connection = realUrl.openConnection();
HttpURLConnection httpURLConnection = (HttpURLConnection) connection;
// 设置 header
for (String key : header.keySet()) {
httpURLConnection.setRequestProperty(key, header.get(key));
}
// 设置请求 body
httpURLConnection.setDoOutput(true);
httpURLConnection.setDoInput(true);
out = new PrintWriter(httpURLConnection.getOutputStream());
// 保存body
out.print(body);
// 发送body
out.flush();
if (HttpURLConnection.HTTP_OK != httpURLConnection.getResponseCode()) {
System.out.println("Http 请求失败,状态码:" + httpURLConnection.getResponseCode());
return null;
}
// 获取响应body
in = new BufferedReader(new InputStreamReader(httpURLConnection.getInputStream()));
String line;
while ((line = in.readLine()) != null) {
result += line;
}
} catch (Exception e) {
return null;
}
return result;
}
/**
* 流转二进制数组
*
* @param in
* @return
* @throws IOException
*/
private static byte[] toByteArray(InputStream in) throws IOException {
ByteArrayOutputStream out = new ByteArrayOutputStream();
byte[] buffer = new byte[1024 * 4];
int n = 0;
while ((n = in.read(buffer)) != -1) {
out.write(buffer, 0, n);
}
return out.toByteArray();
}
}