Android端文字识别

实现的功能:
文字识别、网络图片文字识别、身份证识别、银行卡识别、驾驶证识别、行驶证识别、车牌识别、营业执照识别、护照识别、数字识别、二维码识别、名片识别、手写识别、速算识别。

其中速算识别是接入的讯飞开放平台的WebApi,其他的接入的是百度的SDK。手写识别还用了汉王的识别,测试的识别率没有百度的精准。

下面介绍一下表格识别和速算识别的接入方法,其他的百度都有SDK,可以直接按自己的需求接入。

百度表格识别

表格识别没有SDK,需要自己按官方给的API文档请求。返回的参数可以自定义:一种是返回的json数据,里面包含坐标信息、识别的内容。另一种是返回的表格文件的下载地址。下面贴两张图。

第一种

表格识别
result_data参数的值:

表格识别

第二种

在这里插入图片描述
result_data是一个表格文件下载地址

当扫描的图片不是表格(图片上的文字没有标线的时候),扫描结果如下:

在这里插入图片描述
可以看到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。有需要完整代码的可以留言

猜你喜欢

转载自blog.csdn.net/TLuffy/article/details/103008800