一、準備工作
一、獲取百度的開發權鑑
百度AI開放平臺地址:https://console.bce.baidu.com/?_=1532076508921&fromai=1#/aip/overview
和其他平臺接口的使用一樣,首先要獲取相關的key值。登錄百度賬號之後進入控制檯,依次點擊:
創建應用。保存相關的Key。
二、準備一張身份證照片
我的是在網上找的,保存在本地。
三、下載百度提供的工具類
FileUtil,Base64Util,HttpUtil,GsonUtils,這幾個工具類都會用到,都需要下載。
- https://ai.baidu.com/file/658A35ABAB2D404FBF903F64D47C1F72
- https://ai.baidu.com/file/C8D81F3301E24D2892968F09AE1AD6E2
- https://ai.baidu.com/file/544D677F5D4E4F17B4122FBD60DB82B3
- https://ai.baidu.com/file/470B3ACCA3FE43788B5A963BF0B625F3
下載完成以後放在項目的util包下。
二、正式開發
一、獲取AccessToken
要正式的利用百度AI的身份證識別接口,必須要獲取一個access_token,相當於百度的祕鑰吧。獲取Access Token
我寫了一個工具類,專門用來獲取AccessToken。使用的時候只需要把之前在控制檯獲取到的兩個Key穿進去即可。其中API Key即clientId,Secret Key即clientSecret。我也不知道百度爲什麼要換參數的名字。
import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.SocketTimeoutException;
import java.net.URL;
import java.net.URLConnection;
import java.util.HashMap;
import java.util.Map;
import net.sf.json.JSONArray;
import net.sf.json.JSONObject;
import org.springframework.stereotype.Component;
/**
* @Author: bian
* @Date: 2018/7/16 15:47
* @Todo: 百度API要求每個月換一次Token,因此專門寫一個工具類用來更新token.
*/
public class AccessTokenUtil {
public static Map getToken(String clientId,String clientSecret){
Map token = new HashMap();
String str = "https://aip.baidubce.com/oauth/2.0/token?grant_type=client_credentials&client_id="+clientId+"&client_secret="+clientSecret;
try {
URL url = new URL(str);
URLConnection connectionData = url.openConnection();
connectionData.setConnectTimeout(2000);
BufferedReader br = new BufferedReader(new InputStreamReader(
connectionData.getInputStream(), "UTF-8"));
StringBuilder sb = new StringBuilder();
String line = null;
while ((line = br.readLine()) != null){
sb.append(line);
}
String datas = sb.toString();
JSONObject jsonData = JSONObject.fromObject(datas);
token.put("access_token", jsonData.getString("access_token").toString());
token.put("session_key", jsonData.getString("session_key").toString());
token.put("scope", jsonData.getString("scope").toString());
token.put("refresh_token", jsonData.getString("refresh_token").toString());
token.put("session_secret", jsonData.getString("session_secret").toString());
token.put("expires_in", jsonData.getString("expires_in").toString());
}catch (SocketTimeoutException e) {
System.out.println("連接超時");
} catch (FileNotFoundException e) {
System.out.println("加載文件出錯");
}catch (IOException e) {
System.out.println("IOException");
}
return token;
}
}
二、封裝實體類
爲了操作簡單,對身份證信息進行了封裝,此處封裝爲IDCardBlack和IDCardFront兩個類。其實後來發現使用Map結構更簡單。
import org.springframework.stereotype.Component;
/**
* @Description: 身份證背面的實體類
* @author:ykbian
* @date:2018/7/17 21:15
*/
@Component
public class IDCardBlack {
private String issuingDate;//簽發日期
private String issuingAuthority; //簽發機關
private String expiryDate; //失效日期
//省略set和get方法…………
}
import org.springframework.stereotype.Component;
/**
* @Description: 身份證人像面實體類
* @author:ykbian
* @date:2018/7/17 21:24
*/
@Component
public class IDCardFront {
private String IdNumber;
private String gender;
private String nation;
private String name;
private String address;
//省略get和set方法……………………………………
}
三、測試代碼
本來是寫了一個服務接口和實現類。在controller裏面調用。但是爲了測試方便,直接在實現類裏面測試。
import com.byk.characterrecognition.character_recognition.Service.IDCardRecognitionService;
import com.byk.characterrecognition.character_recognition.entity.IDCardBlack;
import com.byk.characterrecognition.character_recognition.entity.IDCardFront;
import com.byk.characterrecognition.character_recognition.util.AccessTokenUtil;
import com.byk.characterrecognition.character_recognition.util.Base64Util;
import com.byk.characterrecognition.character_recognition.util.FileUtil;
import com.byk.characterrecognition.character_recognition.util.HttpUtil;
import net.sf.json.JSONObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.net.URLEncoder;
import java.util.Map;
/**
* @Author: bian
* @Date: 2018/7/16 15:42
* @Todo: 身份證識別服務接口的實現類
*/
@Service
public class IDCardRecognitionServiceImpl{
// @Autowired
// private static IDCardFront idCardFront;
//
// @Autowired
// private static IDCardBlack idCardBlack;
public static IDCardFront IDCardRecognitionFront(String imageUrl, String clientId, String clientSecret) {
//爲了測試方便使用new的方式,正式環境裏面要用@Autowired標籤注入
IDCardFront idCardFront = new IDCardFront();
// 身份證識別url========百度提供
String idcardIdentificate = "https://aip.baidubce.com/rest/2.0/ocr/v1/idcard";
//圖片路徑=========這裏本來要寫圖片的路徑,我改爲從服務接口傳參
try {
byte[] imgData = FileUtil.readFileByBytes(imageUrl);
String imgStr = Base64Util.encode(imgData);
// 識別身份證正面id_card_side=front;識別身份證背面id_card_side=back;
String params = "id_card_side=front&" + URLEncoder.encode("image", "UTF-8") + "="
+ URLEncoder.encode(imgStr, "UTF-8");
/**
* 線上環境access_token有過期時間, 客戶端可自行緩存,過期後重新獲取。
*/
Map map = AccessTokenUtil.getToken(clientId,clientSecret);
String accessToken = map.get("access_token").toString();
JSONObject wordsResult = HttpUtil.post(idcardIdentificate, accessToken, params);
String IdNumber = wordsResult.getJSONObject("公民身份號碼").getString("words");
String gender = wordsResult.getJSONObject("性別").getString("words");
String nation = wordsResult.getJSONObject("民族").getString("words");
String name = wordsResult.getJSONObject("姓名").getString("words");
String address = wordsResult.getJSONObject("住址").getString("words");
idCardFront.setAddress(address);
idCardFront.setGender(gender);
idCardFront.setIdNumber(IdNumber);
idCardFront.setName(name);
idCardFront.setNation(nation);
} catch (Exception e) {
e.printStackTrace();
}
return idCardFront;
}
public static IDCardBlack IDCardRecognitionBlack(String imageUrl, String clientId, String clientSecret) {
// 身份證識別url
String idcardIdentificate = "https://aip.baidubce.com/rest/2.0/ocr/v1/idcard";
//爲了測試方便使用new的方式,正式環境裏面要用@Autowired標籤注入
IDCardBlack idCardBlack = new IDCardBlack();
try {
byte[] imgData = FileUtil.readFileByBytes(imageUrl);
String imgStr = Base64Util.encode(imgData);
// 識別身份證正面id_card_side=front;識別身份證背面id_card_side=back;
String params = "id_card_side=back&" + URLEncoder.encode("image", "UTF-8") + "="
+ URLEncoder.encode(imgStr, "UTF-8");
/**
* 線上環境access_token有過期時間, 客戶端可自行緩存,過期後重新獲取。
*/
Map map = AccessTokenUtil.getToken(clientId,clientSecret);
String accessToken = map.get("access_token").toString();
JSONObject wordsResult = HttpUtil.post(idcardIdentificate, accessToken, params);
String issuingAuthority = wordsResult.getJSONObject("簽發機關").getString("words");
String issuingDate = wordsResult.getJSONObject("簽發日期").getString("words");
String expiryDate = wordsResult.getJSONObject("失效日期").getString("words");
idCardBlack.setExpiryDate(expiryDate);
idCardBlack.setIssuingAuthority(issuingAuthority);
idCardBlack.setIssuingDate(issuingDate);
} catch (Exception e) {
e.printStackTrace();
}
return idCardBlack;
}
public static void main(String[] arg){
String image01 = "E:/test/front.png";
String image02 = "E:/test/black.png";
String clientId = "你的clientId";
String clientSecret = "你的clientSecret";
IDCardFront idCardFront = IDCardRecognitionServiceImpl.IDCardRecognitionFront(image01,clientId,clientSecret);
IDCardBlack idCardBlack = IDCardRecognitionServiceImpl.IDCardRecognitionBlack(image02,clientId,clientSecret);
System.out.println(idCardFront);
System.out.println(idCardBlack);
}
}
執行main方法,效果如下:
三、源碼獲取
點擊此處獲取源碼https://github.com/bian1234/studyNote/tree/master/APILearn/character_recognition
四、其他
網絡圖片文字識別和表格文字識別已經完善。其他的文字識別操作都差不多,有時間再補充。
另外,表格文字識別的效果實在不敢恭維。誰用誰知道。