通过百度API识别身份证图片
正文
通过百度API识别身份证图片,并返回信息
代码
BaiduAiTemplate
package cn.com.infox.core.ai;import cn.com.infox.core.ai.model.IdCardModel;
import cn.com.infox.core.ai.props.AiBaiduProperties;
import cn.com.infox.core.tool.jackson.JsonUtil;
import cn.com.infox.core.tool.utils.OkHttpUtil;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.json.JSONObject;import java.util.HashMap;
import java.util.Map;/*** Baidu AI Token Template** @author Daniel*/
@Slf4j
public class BaiduAiTemplate {private final AiBaiduProperties aiBaiduProperties;private String token;private long expiresTime = 0L;private static final int SECOND = 1000;private static final String ACCESS_TOKEN = "access_token";private static final String EXPIRES_IN = "expires_in";private static final String VERIFY_TOKEN = "verify_token";private static final String WORDS = "words";private static final String WORDS_RESULT = "words_result";private static final String RESULT = "result";private static final String VERIFY_RESULT = "verify_result";private static final String SCORE = "score";private static final String GRANT_TYPE = "grant_type";private static final String CLIENT_ID = "client_id";private static final String CLIENT_SECRET = "client_secret";private static final String CONTENT_TYPE = "Content-Type";private static final String CONTENT_TYPE_FORM = "application/x-www-form-urlencoded";private static final String CONTENT_TYPE_JSON = "application/json";private static final String ID_CARD_SIDE = "id_card_side";private static final String ID_CARD_SIDE_FRONT = "front";private static final String ID_CARD_SIDE_BACK = "back";private static final String IMAGE = "image";private static final String DETECT_RISK = "detect_risk";private static final String DETECT_PHOTO = "detect_photo";private static final String TRUE = "true";private static final String FALSE = "false";/*** 获取百度AI Token*/private static final String TOKEN_URL = "https://aip.baidubce.com/oauth/2.0/token";/*** 通过OCR获取证件信息*/private static final String ID_CARD_URL = "https://aip.baidubce.com/rest/2.0/ocr/v1/idcard";/*** 人脸实名认证(V4)接口*/private static final String FACE_V4_VERIFY_URL = "https://aip.baidubce.com/rest/2.0/face/v4/mingjing/verify";/*** 获取方案校验Token(H5)*/private static final String FACE_PRINT_VERIFY_TOKEN_GENERATE_URL = "https://aip.baidubce.com/rpc/2.0/brain/solution/faceprint/verifyToken/generate";/*** 指定用户信息上报接口(H5)*/private static final String FACE_PRINT_ID_CARD_SUBMIT_URL = "https://aip.baidubce.com/rpc/2.0/brain/solution/faceprint/idcard/submit";/*** 对比图片上传接口(H5)*/private static final String FACE_PRINT_UPLOAD_MATCH_IMAGE_URL = "https://aip.baidubce.com/rpc/2.0/brain/solution/faceprint/uploadMatchImage";/*** 查询认证结果接口(H5)*/private static final String FACE_PRINT_RESULT_DETAIL_URL = "https://aip.baidubce.com/rpc/2.0/brain/solution/faceprint/result/detail";public BaiduAiTemplate(AiBaiduProperties aiBaiduProperties) {this.aiBaiduProperties = aiBaiduProperties;}/*** 获取百度AI的接口Token** @return*/@SneakyThrowspublic String token() {if (this.token != null && (expiresTime < System.currentTimeMillis())) {return this.token;}return getToken();}private String getToken() {String result = "";try {long currentTime = System.currentTimeMillis();Map queries = new HashMap<>();queries.put(GRANT_TYPE, aiBaiduProperties.getGrantType());queries.put(CLIENT_ID, aiBaiduProperties.getClientId());queries.put(CLIENT_SECRET, aiBaiduProperties.getClientSecret());result = OkHttpUtil.get(TOKEN_URL, queries);JSONObject resultJson = new JSONObject(result);this.token = resultJson.getString(ACCESS_TOKEN);this.expiresTime = currentTime + (resultJson.getLong(EXPIRES_IN) * SECOND);} catch (Exception e) {log.error("获取百度AI token 失败:" + result, e);}return this.token;}/*** 获取H5方案验证Token** @return*/@SneakyThrowspublic String verifyToken() {return getVerifyToken();}private String getVerifyToken() {String verifyToken = "";String result = "";try {Map header = new HashMap();header.put(CONTENT_TYPE, CONTENT_TYPE_JSON);Map body = new HashMap();body.put("plan_id", aiBaiduProperties.getH5PlanId());String json = JsonUtil.toJson(body);result = OkHttpUtil.postJson(FACE_PRINT_VERIFY_TOKEN_GENERATE_URL + "?" + ACCESS_TOKEN + "=" + token(), header, json);JSONObject resultJson = new JSONObject(result);verifyToken = resultJson.getJSONObject(RESULT).getString(VERIFY_TOKEN);} catch (Exception e) {log.error("获取百度AI应用方案的 verify token 失败:" + result, e);}return verifyToken;}@SneakyThrowspublic IdCardModel getIdCardModel(String frontImg, String backImg) {IdCardModel idCardModel = new IdCardModel();String result = "";try {result = getIdCard(frontImg, ID_CARD_SIDE_FRONT);JSONObject resultJson = new JSONObject(result);idCardModel.setPhoto(resultJson.getString("photo"));JSONObject wordsResult = resultJson.getJSONObject(WORDS_RESULT);idCardModel.setName(wordsResult.getJSONObject("姓名").getString(WORDS));idCardModel.setNation(wordsResult.getJSONObject("民族").getString(WORDS));idCardModel.setAddress(wordsResult.getJSONObject("住址").getString(WORDS));idCardModel.setCardNo(wordsResult.getJSONObject("公民身份号码").getString(WORDS));idCardModel.setSex(wordsResult.getJSONObject("性别").getString(WORDS));idCardModel.setBirthday(wordsResult.getJSONObject("出生").getString(WORDS));result = getIdCard(backImg, ID_CARD_SIDE_BACK);resultJson = new JSONObject(result);wordsResult = resultJson.getJSONObject(WORDS_RESULT);idCardModel.setExpiryDate(wordsResult.getJSONObject("失效日期").getString(WORDS));idCardModel.setIssueOrg(wordsResult.getJSONObject("签发机关").getString(WORDS));idCardModel.setIssueDate(wordsResult.getJSONObject("签发日期").getString(WORDS));} catch (Exception e) {log.error("获取身份证信息失败:" + result, e);}return idCardModel;}@SneakyThrowspublic IdCardModel validateIdCardFrontImg(String frontImg) {IdCardModel idCardModel = new IdCardModel();String result = "";try {result = getIdCard(frontImg, ID_CARD_SIDE_FRONT);JSONObject resultJson = new JSONObject(result);idCardModel.setPhoto(resultJson.getString("photo"));JSONObject wordsResult = resultJson.getJSONObject(WORDS_RESULT);idCardModel.setName(wordsResult.getJSONObject("姓名").getString(WORDS));idCardModel.setNation(wordsResult.getJSONObject("民族").getString(WORDS));idCardModel.setAddress(wordsResult.getJSONObject("住址").getString(WORDS));idCardModel.setCardNo(wordsResult.getJSONObject("公民身份号码").getString(WORDS));idCardModel.setSex(wordsResult.getJSONObject("性别").getString(WORDS));idCardModel.setBirthday(wordsResult.getJSONObject("出生").getString(WORDS));} catch (Exception e) {log.error("获取身份证信息失败:" + result, e);}return idCardModel;}private String getIdCard(String img, String side) {String result = "";try {Map header = new HashMap();header.put(CONTENT_TYPE, CONTENT_TYPE_FORM);Map queries = new HashMap<>();queries.put(ACCESS_TOKEN, token());if (ID_CARD_SIDE_FRONT.equals(side)) {queries.put(DETECT_PHOTO, TRUE);queries.put(DETECT_RISK, FALSE);queries.put(ID_CARD_SIDE, ID_CARD_SIDE_FRONT);} else {queries.put(ID_CARD_SIDE, ID_CARD_SIDE_BACK);}Map params = new HashMap<>();params.put(IMAGE, img);result = OkHttpUtil.post(ID_CARD_URL, header, queries, params);} catch (Exception e) {log.error("获取百度AI ID Card 失败:" + result, e);}return result;}/*** 验证人脸(将人脸图片通过API对比后,看分值是否达标,默认分值80)** @param idCardNo* @param name* @param image* @return*/public boolean verifyFaceScore(String idCardNo, String name, String image) {String result = "";try {Map header = new HashMap();header.put(CONTENT_TYPE, CONTENT_TYPE_JSON);Map body = new HashMap();body.put("id_card_number", idCardNo);body.put("name", name);body.put(IMAGE, image);String json = JsonUtil.toJson(body);result = OkHttpUtil.postJson(FACE_V4_VERIFY_URL + "?" + ACCESS_TOKEN + "=" + token(), header, json);JSONObject resultJson = new JSONObject(result);double score = resultJson.getJSONObject(RESULT).getDouble(SCORE);return score > aiBaiduProperties.getFaceScore();} catch (Exception e) {log.error("人脸校验失败:" + result, e);}return false;}/*** 指定用户信息上报接口** @param idCardNo 证件号* @param name 证件姓名* @param verifyToken 验证码* @return 判断结果*/public boolean submitIdcardInfo(String idCardNo, String name, String verifyToken) {String result = "";try {Map header = new HashMap();header.put(CONTENT_TYPE, CONTENT_TYPE_JSON);Map body = new HashMap();body.put("id_no", idCardNo);body.put("id_name", name);body.put(VERIFY_TOKEN, verifyToken);String json = JsonUtil.toJson(body);result = OkHttpUtil.postJson(FACE_PRINT_ID_CARD_SUBMIT_URL + "?" + ACCESS_TOKEN + "=" + token(), header, json);JSONObject resultJson = new JSONObject(result);return resultJson.getBoolean("success");} catch (Exception e) {log.error("人脸校验失败:" + result, e);}return false;}public boolean uploadMatchImage(String image, String verifyToken) {String result = "";try {Map header = new HashMap();header.put(CONTENT_TYPE, CONTENT_TYPE_JSON);Map body = new HashMap();body.put(IMAGE, image);body.put(VERIFY_TOKEN, verifyToken);String json = JsonUtil.toJson(body);result = OkHttpUtil.postJson(FACE_PRINT_UPLOAD_MATCH_IMAGE_URL + "?" + ACCESS_TOKEN + "=" + token(), header, json);JSONObject resultJson = new JSONObject(result);return resultJson.getBoolean("success");} catch (Exception e) {log.error("人脸校验失败:" + result, e);}return false;}public boolean getFacePrintDetail(String verifyToken) {String result = "";try {Map header = new HashMap();header.put(CONTENT_TYPE, CONTENT_TYPE_JSON);Map body = new HashMap();body.put(VERIFY_TOKEN, verifyToken);String json = JsonUtil.toJson(body);result = OkHttpUtil.postJson(FACE_PRINT_RESULT_DETAIL_URL + "?" + ACCESS_TOKEN + "=" + token(), header, json);JSONObject resultJson = new JSONObject(result);double score = resultJson.getJSONObject(RESULT).getJSONObject(VERIFY_RESULT).getDouble(SCORE);return score > aiBaiduProperties.getFaceScore();} catch (Exception e) {log.error(".查询人脸认证结果失败:" + result, e);}return false;}}
AiBaiduProperties
package cn.com.infox.core.ai.props;import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;@Data
@ConfigurationProperties(prefix = "ai.baidu")
public class AiBaiduProperties {/*** 应用的API Key*/private String clientId;/*** 应用的Secret Key*/private String clientSecret;/*** 固定为client_credentials*/private String grantType = "client_credentials";/*** H5 方案ID*/private int h5PlanId = 1;/*** 人脸阀值*/private double faceScore = 80.00;
}
BaiduConfiguration
package cn.com.infox.core.ai.config;import cn.com.infox.core.ai.props.AiBaiduProperties;
import cn.com.infox.core.ai.BaiduAiTemplate;
import lombok.AllArgsConstructor;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;/*** Baidu AI 配置类** @author Admin*/
@Configuration
@AllArgsConstructor
@EnableConfigurationProperties(AiBaiduProperties.class)
@ConditionalOnProperty(value = "ai.baidu.client-id")
public class BaiduConfiguration {private AiBaiduProperties aiBaiduProperties;@Beanpublic BaiduAiTemplate baiduTokenTemplateTemplate() {return new BaiduAiTemplate(aiBaiduProperties);}}
IdCardModel
package cn.com.infox.core.ai.model;import lombok.Data;/*** 身份证信息** @author Daniel*/
@Data
public class IdCardModel {/*** 姓名*/private String name;/*** 民族*/private String nation;/*** 地址*/private String address;/*** 卡号*/private String cardNo;/*** 生日*/private String birthday;/*** 性别*/private String sex;/*** 图片*/private String photo;/*** 签发日期*/private String issueDate;/*** 签发机构*/private String issueOrg;/*** 失效日期*/private String expiryDate;}
Controller
@PostMapping("/validate-idCard-frontImg")@ApiOperationSupport(order = 21)@ApiOperation(value = "根据身份证正面获取用户信息", notes = "根据身份证正面获取用户信息")public R validateIdCardFrontImg(@Valid @RequestBody ValidateIdCardDTO validateIdCardDTO) {IdCardModel idCardModel = baiduAiTemplate.validateIdCardFrontImg(validateIdCardDTO.getFrontImg());R
配置文件
application-dev.yml
ai:baidu:client-id: 123456client-secret: 123456grant-type: client_credentialsh5-plan-id: 1face-score: 80
本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!
