实现的功能:
文字识别、网络图片文字识别、身份证识别、银行卡识别、驾驶证识别、行驶证识别、车牌识别、营业执照识别、护照识别、数字识别、二维码识别、名片识别、手写识别、速算识别。
其中速算识别是接入的讯飞开放平台的WebApi,其他的接入的是百度的SDK。手写识别还用了汉王的识别,测试的识别率没有百度的精准。
下面介绍一下表格识别和速算识别的接入方法,其他的百度都有SDK,可以直接按自己的需求接入。
表格识别没有SDK,需要自己按官方给的API文档请求。返回的参数可以自定义:一种是返回的json数据,里面包含坐标信息、识别的内容。另一种是返回的表格文件的下载地址。下面贴两张图。
当扫描的图片不是表格(图片上的文字没有标线的时候),扫描结果如下:
可以看到result_data字段里面就一串数字了,不会拆分出来多个数组。
关键代码如下:
OkHttpClient client = new OkHttpClient();
client.newBuilder().connectTimeout(10, TimeUnit.SECONDS).readTimeout(10, TimeUnit.SECONDS).build();
// 请求的百度api地址 后面拼的百度生成的token
String url = "https://aip.baidubce.com/rest/2.0/solution/v1/form_ocr/request?access_token="+Token;
/**
* 图像数据,base64编码后进行urlencode,要求base64编码和urlencode后大小不超过4M,最短边至少15px,最长边最大4096px,支持jpg/jpeg/png/bmp格式
*/
String path= BitmapToString(img_path);
/**
* 参数:
* image 图像数据
* is_sync 是否同步返回识别结果。取值为“false”,需通过获取结果接口获取识别结果;取值为“true”,同步返回识别结果,无需调用获取结果接口。默认取值为“false”
* request_type 当 is_sync=true 时,需在提交请求时即传入此参数指定获取结果的类型,取值为“excel”时返回xls文件的地址,
* 取值为“json”时返回json格式的字符串。当 is_sync=false 时,需在获取结果时指定此参数
*/
RequestBody body = new FormBody.Builder().add("image",path).add("is_sync", String.valueOf(true)).add("request_type","json").build();
final Request request = new Request.Builder()
.url(url)
.addHeader("Content-Type","application/x-www-form-urlencoded")
.post(body)
.build();
Call call = client.newCall(request);
call.enqueue(new Callback() {
@Override
public void onFailure(@NonNull Call call, @NonNull IOException e) {
}
@Override
public void onResponse(@NonNull Call call, @NonNull final Response response) throws IOException {
String bean = response.body().string();
Log.e("返回的结果",bean);
}
});
Api文档地址:https://ai.baidu.com/docs#/OCR-API-TableAsyn/top
接口文档地址:https://www.xfyun.cn/doc/words/photo-calculate-recg/API.html
讯飞速算识别基于深度学习的端到端识别技术,自动识别图片中的速算题并智能批改,返回标准LaTeX公式及批改结果。覆盖K12教育范围内15种题型,支持口算、竖式、方程、脱式计算等,详细请参照 速算题型 (如下图)。支持的场景有印刷体、手写体、拍照场景。支持的图片类型JPG、PNG、BMP。
讯飞速算识别目前处于测试阶段,每天有10万次免费额度,只支持python、java、nodejs、php等语言,没有Android SDK,仿照java的demo在Android里面进行api请求。
imp_line_info.total_score 表示该速算题判决正误信息【1(正确)/0(错误)】
line_word_result.word_content 表示该行公式识别结果 Latex公式
具体返回参数可以参考api文档说明。
代码如下:
public void PostData() throws Exception {
if (APPID.equals("") || API_KEY.equals("") || API_SECRET.equals("")) {
System.out.println("Appid 或APIKey 或APISecret 为空!请打开demo代码,填写相关信息。");
return;
}
body = buildHttpBody();
header = buildHttpHeader(body);
new Thread(runnable).start();
}
Runnable runnable = new Runnable(){
@Override
public void run(){
//进行访问网络操作
Log.e("dbj","6666666666666666666666666666666666");
resultMap = HttpUtil.doPost2(WebITR_URL, header, body);
if (resultMap != null) {
String resultStr = resultMap.get("body").toString();
// System.out.println("【ITR WebAPI 接口调用结果】\n" + resultStr);
Log.e("dbj","【ITR WebAPI 接口调用结果】\n" + resultStr);
//以下仅用于调试
Gson json = new Gson();
ResponseData resultData = json.fromJson(resultStr, ResponseData.class);
int code = resultData.getCode();
if (resultData.getCode() != 0) {
System.out.println("请前往https://www.xfyun.cn/document/error-code?code=" + code + "查询解决办法");
}
} else {
System.out.println("调用失败!请根据错误信息检查代码,接口文档:https://www.xfyun.cn/doc/words/photo-calculate-recg/API.html");
}
}
};
/**
* 组装http请求头
*/
public static Map<String, String> buildHttpHeader(String body) throws Exception {
Map<String, String> header = new HashMap<String, String>();
URL url = new URL(WebITR_URL);
//时间戳
SimpleDateFormat format = new SimpleDateFormat("EEE, dd MMM yyyy HH:mm:ss z", Locale.US);
format.setTimeZone(TimeZone.getTimeZone("GMT"));
Date dateD = new Date();
String date = format.format(dateD);
//System.out.println("【ITR WebAPI date】\n" + date);
//对body进行sha256签名,生成digest头部,POST请求必须对body验证
String digestBase64 = "SHA-256=" + signBody(body);
//System.out.println("【ITR WebAPI digestBase64】\n" + digestBase64);
//hmacsha256加密原始字符串
StringBuilder builder = new StringBuilder("host: ").append(url.getHost()).append("\n").//
append("date: ").append(date).append("\n").//
append("POST ").append(url.getPath()).append(" HTTP/1.1").append("\n").//
append("digest: ").append(digestBase64);
//System.out.println("【ITR WebAPI builder】\n" + builder);
String sha = hmacsign(builder.toString(), API_SECRET);
//System.out.println("【ITR WebAPI sha】\n" + sha);
//组装authorization
String authorization = String.format("api_key=\"%s\", algorithm=\"%s\", headers=\"%s\", signature=\"%s\"", API_KEY, "hmac-sha256", "host date request-line digest", sha);
//System.out.println("【ITR WebAPI authorization】\n" + authorization);
header.put("Authorization", authorization);
header.put("Content-Type", "application/json");
header.put("Accept", "application/json,version=1.0");
header.put("Host", url.getHost());
header.put("Date", date);
header.put("Digest", digestBase64);
//System.out.println("【ITR WebAPI header】\n" + header);
return header;
}
/**
* 组装http请求体
*/
public static String buildHttpBody() throws Exception {
JsonObject body = new JsonObject();
JsonObject business = new JsonObject();
JsonObject common = new JsonObject();
JsonObject data = new JsonObject();
//填充common
common.addProperty("app_id", APPID);
//填充business
business.addProperty("ent", "math-arith");
business.addProperty("aue", "raw");
//填充data
byte[] imageByteArray = FileUtil.read(AUDIO_PATH);
String imageBase64 = new String(Base64.getEncoder().encodeToString(imageByteArray));
data.addProperty("image", imageBase64);
//填充body
body.add("common", common);
body.add("business", business);
body.add("data", data);
return body.toString();
}
/**
* 对body进行SHA-256加密
*/
private static String signBody(String body) throws Exception {
MessageDigest messageDigest;
String encodestr = "";
try {
messageDigest = MessageDigest.getInstance("SHA-256");
messageDigest.update(body.getBytes("UTF-8"));
encodestr = Base64.getEncoder().encodeToString(messageDigest.digest());
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
return encodestr;
}
/**
* hmacsha256加密
*/
private static String hmacsign(String signature, String apiSecret) throws Exception {
Charset charset = Charset.forName("UTF-8");
Mac mac = Mac.getInstance("hmacsha256");
SecretKeySpec spec = new SecretKeySpec(apiSecret.getBytes(charset), "hmacsha256");
mac.init(spec);
byte[] hexDigits = mac.doFinal(signature.getBytes(charset));
return Base64.getEncoder().encodeToString(hexDigits);
}
public static class ResponseData {
private int code;
private String message;
private String sid;
private Object data;
public int getCode() {
return code;
}
public String getMessage() {
return this.message;
}
public String getSid() {
return sid;
}
public Object getData() {
return data;
}
}
Over。有需要完整代码的可以留言