工作中遇到一个需求是识别营业执照,看了阿里云的,腾讯云的,讯飞的,百度的。然后发现阿里云和腾讯云目前都是公测或者内测阶段,所以就去试了百度的,但是百度的只是普通的文字识别,就是识别文字中的图片,而讯飞的就比较专业了,单纯的识别营业执照。
先看一下使用百度的文字识别的步骤
百度AI开放平台的地址:营业执照识别,准确识别各样式关键字段,免费试用-百度AI开放平台
登录之后在右上角控制台创建一个应用,
创建完应用后点击管理应用
这里用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; } }
但是百度的这个文字识别识别的不太好,有的文字错了 有的文字缺了
--------------------------------------------------------------------------------------------------------------------------------------------------------------------
下面看讯飞的营业执照识别
链接:营业执照识别 intsig - 文字识别 - 讯飞开放平台
点击免费试用,需要实名认证就认证一下
创建一个应用
这里面只有一个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(); } }