百度AI開放平臺文字之身份證識別的實現

一、準備工作

一、獲取百度的開發權鑑

百度AI開放平臺地址:https://console.bce.baidu.com/?_=1532076508921&fromai=1#/aip/overview

和其他平臺接口的使用一樣,首先要獲取相關的key值。登錄百度賬號之後進入控制檯,依次點擊:

 創建應用。保存相關的Key。

二、準備一張身份證照片

我的是在網上找的,保存在本地。

三、下載百度提供的工具類

FileUtil,Base64Util,HttpUtil,GsonUtils,這幾個工具類都會用到,都需要下載。

  1. https://ai.baidu.com/file/658A35ABAB2D404FBF903F64D47C1F72
  2. https://ai.baidu.com/file/C8D81F3301E24D2892968F09AE1AD6E2
  3. https://ai.baidu.com/file/544D677F5D4E4F17B4122FBD60DB82B3
  4. 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

四、其他

網絡圖片文字識別和表格文字識別已經完善。其他的文字識別操作都差不多,有時間再補充。

另外,表格文字識別的效果實在不敢恭維。誰用誰知道。

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章