OCR(Optical Character Recognition,光學字符識別)又稱文字識別,文字識別下面又可以分爲身份證識別、名片識別、行駛證識別、發票識別等等;車牌識別是OCR中的一種。百度雲、華爲雲、阿里雲都有提供這方面的應用。每家的服務都有其自己的特點,這裏記錄一下是如何調用華爲雲的車牌識別功能的,從應用的申請,到把代碼加入到自己的項目裏。
第一步,來到華爲雲文字識別OCR專欄;
文字識別OCR屬於EI企業智能下的子類目,在華爲雲官網,通過導航 EI企業智能 來到文字識別OCR專欄;
第二步,點擊SDK下載,來到下載頁面;
我們使用的是Java語言,下載Java語言對應的jar包即可;
第三步,解壓下載的架包,導入到開發工具裏;
選中其一,導入到自己的開發工具裏,這裏使用的maven,導入的也是maven版本的。
第四步,用自己擁有的華爲雲賬號,開啓車牌識別應用;
在對應的服務裏找到車牌識別點擊開啓;
第五步,查看文檔,看看車牌識別服務是如何調用的;
https://support.huaweicloud.com/api-ocr/ocr_03_0040.html
這個頁面裏面的文檔挺多,以下幾篇,建議多看一看,以便對對接有個全面的瞭解;
使用SDK(Java)
調用SDK有兩種方式:一種是通過Token,token有效期24小時;另一種是通過AK/SK,只能用於小於12M的請求體;
備註說明:這個很重要,你需要根據自己的應用權衡調用的方式;
第六步,加密參數的獲取及線上測試;
怎麼獲取token:https://support.huaweicloud.com/api-iam/iam_30_0001.html
申請方法:https://support.huaweicloud.com/iam_faq/iam_01_034.html
線上測試的地址,需要在登錄的情況下才能訪問;
https://apiexplorer.developer.huaweicloud.com/apiexplorer/debug?product=OCR&api=LicensePlate
這裏有個地方需要注意:
image的參數,必須填寫base64位加過密的纔可以測試成功,其他的參數token、AK/SK,系統默認獲取已經配置好的。
第七步,通過demo調用api,回到項目裏,看看如何調用;
在項目裏,有一個OCRdemo類,在這個類裏,有兩個demo,一個是通過token的方式調用身份證識別接口,另一個通過AK/SK的方式調用身份證識別接口。
沒有車牌識別的demo,把身份證識別的改寫一下,這裏使用AK/SK方式調用;
package com.test.huawei;
import java.io.IOException;
import java.net.URISyntaxException;
import org.apache.commons.io.IOUtils;
import org.apache.http.HttpResponse;
import com.alibaba.fastjson.JSONObject;
import com.test.huawei.ocr.HWOcrClientAKSK;
/**
*
* @author 程就人生
* @date 2020年9月23日
* @Description
*
*/
public class OCRDemo {
public static void main(String[] args) throws URISyntaxException, UnsupportedOperationException, IOException{
//需要識別的圖片路徑,可以是絕對路徑,也可以是相對路徑,還可以是url地址
String imgPath = "./data/aaa.jpg";
carAKSKDemo2(imgPath);
}
/**
* 車牌識別demo
* @throws URISyntaxException
* @throws UnsupportedOperationException
* @throws IOException
*/
public static void carAKSKDemo2(String imgPath) throws URISyntaxException, UnsupportedOperationException, IOException{
/*
* AK/SK demo code
* */
String AK="你的AK"; //AK from authentication
String SK="你的SK"; //SK from authentication
String regionName="cn-north-4"; //region name of the service
String httpUri = "/v1.0/ocr/license-plate";
JSONObject params = new JSONObject();
try {
HWOcrClientAKSK ocrClient=new HWOcrClientAKSK(regionName, AK, SK);
HttpResponse response=ocrClient.RequestOcrServiceBase64(httpUri, imgPath, params);
System.out.println(response);
String content = IOUtils.toString(response.getEntity().getContent(), "utf-8");
System.out.println(content);
}
catch (Exception e) {
e.printStackTrace();
}
}
}
在data文件夾里加入含有車牌號的圖片;
第八步,抽離代碼;
我們要把這個功能加到自己的項目裏,先看看這個demo裏引入了哪幾個文件,
pom.xml文件中需要添加華爲的鏡像,以便引入華爲的架包;
<!-- 華爲的鏡像 -->
<repositories>
<repository>
<id>huaweicloud</id> <url>https://mirrors.huaweicloud.com/repository/maven/huaweicloudsdk/</url>
</repository>
</repositories>
<!-- 文字識別所需架包 -->
<dependency>
<groupId>com.huawei.hwclouds.ais</groupId>
<artifactId>ais-java-client</artifactId>
<version>2.0.0</version>
</dependency>
工具類需要兩個,這裏不使用token,就把token的工具類忽略;
package com.test.huawei.ocr;
import com.alibaba.fastjson.JSONObject;
import com.huawei.ais.common.AuthInfo;
import com.huawei.ais.common.ProxyHostInfo;
import com.huawei.ais.sdk.AisAccess;
import com.huawei.ais.sdk.AisAccessWithProxy;
import com.huawei.ais.sdk.util.HttpClientUtils;
import org.apache.commons.codec.binary.Base64;
import org.apache.commons.io.FileUtils;
import org.apache.http.HttpResponse;
import org.apache.http.entity.StringEntity;
import java.io.File;
import java.io.IOException;
public class HWOcrClientAKSK {
private AuthInfo HEC_AUTH; //Authorization Information
private AisAccess HttpService; //access to ocr service on cloud
private ProxyHostInfo PROXYINFO; //proxy host info (optional)
static {
HttpClientUtils.DEFAULT_CONNECTION_TIMEOUT = 15000;
HttpClientUtils.DEFAULT_CONNECTION_REQUEST_TIMEOUT = 15000;
HttpClientUtils.DEFAULT_SOCKET_TIMEOUT = 15000;
}
/**
* Constructor for OcrClientAKSK without proxy
* @param Endpoint HTTPEndPoint for OCR Service
* @param Region The region info for OCR Service
* @param YourAK The Access Key from Authentication
* @param YourSK The Secret Key from Authentication
* */
public HWOcrClientAKSK(String Region,String YourAK,String YourSK) {
if (Region == null| Region == ""| YourAK == null| YourAK == ""| YourSK == null|
YourSK == "")
throw new IllegalArgumentException("the parameter for HWOcrClientAKSK's Constructor cannot be empty");
String endPoint = "https://ocr." + Region + ".myhuaweicloud.com";
HEC_AUTH= new AuthInfo(endPoint,Region,YourAK,YourSK);
HttpService=new AisAccess(HEC_AUTH);
}
/**
* Constructor for OcrClientAKSK with proxy
* @param Endpoint HTTPEndPoint for OCR Service
* @param Region The region info for OCR Service
* @param YourAK The Access Key from Authentication
* @param YourSK The Secret Key from Authentication
* @param ProxyHost The URL for the proxy server
* @param ProxyPort The Port number for the proxy service
* @param ProxyUsrName The Loggin user for the proxy server if authentication is required
* @param ProxyPwd The Loggin pwd for the proxy server if authentication is required
* */
public HWOcrClientAKSK(String Endpoint,String Region,String YourAK,String YourSK,String ProxyHost,int ProxyPort,String ProxyUsrName,String ProxyPwd) {
if (Endpoint== null|Endpoint == ""|Region == null| Region == ""| YourAK == null| YourAK == ""| YourSK == null|
YourSK == ""|ProxyHost == null | ProxyHost == "" | ProxyUsrName == null |ProxyUsrName == ""| ProxyPwd == null | ProxyPwd == "")
throw new IllegalArgumentException("the parameter for HWOcrClientAKSK's Constructor cannot be empty");
HEC_AUTH= new AuthInfo(Endpoint,Region,YourAK,YourSK);
PROXYINFO= new ProxyHostInfo(ProxyHost,ProxyPort,ProxyUsrName,ProxyPwd);
HttpService=new AisAccessWithProxy(HEC_AUTH,PROXYINFO);
}
/*
* Release the access service when the object is collected
* */
protected void finalize(){
HttpService.close();
}
/**
* Call the OCR API with a local picture file
* @param uri the uri for the http request to be called
* @param filepath the path for the picture file to be recognized
* */
public HttpResponse RequestOcrServiceBase64(String uri,String imgPath, JSONObject params) throws IOException {
if(uri == null | uri == "" | imgPath == null | imgPath == "")
throw new IllegalArgumentException("the parameter for requestOcrServiceBase64 cannot be empty");
try {
if (imgPath.indexOf("http://") != -1 || imgPath.indexOf("https://") != -1) {
params.put("url", imgPath);
} else {
byte[] fileData = FileUtils.readFileToByteArray(new File(imgPath));
String fileBase64Str = Base64.encodeBase64String(fileData);
params.put("image", fileBase64Str);
}
// Pass the parameters in JSON objects and invoke the service using POST.
StringEntity stringEntity = new StringEntity(params.toJSONString(), "utf-8");
HttpResponse response = HttpService.post(uri, stringEntity);
return response;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
}
package com.test.huawei.ocr;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
import org.apache.http.HttpResponse;
import com.huawei.ais.sdk.util.HttpClientUtils;
/**
* Tool used to verify the information returned from service access.
*/
public class ResponseProcessUtils {
/**
* Print the HTTP status code after the service access is complete.
*
* @param response Response object
*/
public static void ProcessResponseStatus(HttpResponse response) {
System.out.println(response.getStatusLine().getStatusCode());
}
/**
* Convert the service access result into a character stream, which is used for showing the JSON data.
*
* @param response Response object
* @throws UnsupportedOperationException
* @throws IOException
*/
public static void ProcessResponse(HttpResponse response) throws UnsupportedOperationException, IOException {
System.out.println(HttpClientUtils.convertStreamToString(response.getEntity().getContent()));
}
/**
* Write the byte array to the file to support generation of binary files (for example, images).
* @param fileName File name
* @param data Data
* @throws IOException
*/
public static void WriteBytesToFile(String fileName, byte[] data) throws IOException{
FileChannel fc = null;
try {
ByteBuffer bb = ByteBuffer.wrap(data);
fc = new FileOutputStream(fileName).getChannel();
fc.write(bb);
} catch (Exception e) {
e.printStackTrace();
System.out.println(e.getMessage());
}
finally {
fc.close();
}
}
}
整理過後,才發現使用起來並不難,就是剛開始使用時不知道使用的流程。到此爲止,車牌識別的就告一個段落。