百度OCR文字识别-身份证识别
简介
一、介绍
身份证识别 API 接口文档地址:http://ai.baidu.com/docs#/OCR-API/top
接口描述
用户向服务请求识别身份证,身份证识别包括正面和背面。
请求说明
请求示例
HTTP 方法:POST
请求URL: https://aip.baidubce.com/rest/2.0/ocr/v1/idcard
备注:你需要 成为百度开发者,获取API key 和Secret Key
Access_Token 的获取
百度Access_token 有效期有时间限制,大概是30天左右,所以建议封装成功能方法每次调用最新的。
- access_token:要获取的Access Token;
- expires_in:Access Token的有效期(秒为单位,一般为1个月);
二、技术实现
百度 文字识别 有提供SDK。如果有支持的语言,可以直接用sdk。笔者自己用的Http 请求封装
对于图片大小有要求的,图像数据,base64编码后进行urlencode,要求base64编码和urlencode后大小不超过4M,最短边至少15px,最长边最大4096px,支持jpg/png/bmp格式
接口基础封装
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace BaiduAIAPI.Model { public class AccessTokenModel { public bool IsSuccess { get; set; } public SuccessAccessTokenModel SuccessModel { get; set; } public ErrorAccessTokenModel ErrorModel { get; set; } } /// <summary> /// 获取accesstoken,正常 的 百度接口返回的json 实体模型 /// </summary> public class SuccessAccessTokenModel { public string refresh_token { get; set; } public int expires_in { get; set; } public string scope { get; set; } public string session_key { get; set; } public string session_secret { get; set; } public string access_token { get; set; } } /// <summary> /// 获取accesstoken,失败的 百度接口返回的json 实体模型 /// </summary> public class ErrorAccessTokenModel { public string error { get; set; } public string error_description { get; set; } } }
using System; using System.IO; using System.Net; using System.Text; using System.Web; using AOP.Common; using AOP.Common.DataConversion; using BaiduAIAPI.Model; using BaiduAIAPI.Type; namespace BaiduAIAPI.ORC_Characterbase64 { /// <summary> /// 文字识别--身份证识别 应用(只是获取身份证图片 信息,没有和公安部联网,无法确认真假,只是单纯从图片上识别文字) /// </summary> public class IDCardRecognition { // 身份证识别 /// <summary> /// 身份证识别 /// </summary> /// <param name="token">Accesstoken</param> /// <param name="imagePath">图片路径</param> /// <param name="recognitionString">识别结果</param> /// <param name="errorMsg">错误信息</param> /// <param name="id_card_side"> front:身份证正面;back:身份证背面</param> /// <param name="detect_direction">是否检测图像朝向,默认不检测,即:false。朝向是指输入图像是正常方向、逆时针旋转90/180/270度。可选值包括:- true:检测朝向;- false:不检测朝向。</param> /// <param name="detect_risk"> string 类型 是否开启身份证风险类型(身份证复印件、临时身份证、身份证翻拍、修改过的身份证)功能,默认不开启,即:false。可选值:true-开启;false-不开启</param> /// <returns>结果状态</returns> public static IDCardRecognitionModel GetIdcardRecognitionString(string token, string imagePath, ref string recognitionString, out string errorMsg, string id_card_side="front", bool detect_direction=false, string detect_risk="false") { bool resultState = true; IDCardRecognitionModel tempModel = new IDCardRecognitionModel(); try { #region 基础校验 string verificationMsg = ""; errorMsg = ""; bool isVerification = ImageVerification.VerificationImage(imagePath, out verificationMsg); if (!isVerification) { errorMsg += verificationMsg; tempModel.state = false; tempModel.errorMsg = errorMsg; return tempModel; } string strbaser64 = ConvertDataFormatAndImage.ImageToByte64String(imagePath, System.Drawing.Imaging.ImageFormat.Jpeg); // 图片的base64编码 Encoding encoding = Encoding.Default; string urlEncodeImage = HttpUtility.UrlEncode(strbaser64); byte[] tempBuffer = encoding.GetBytes(urlEncodeImage); if (tempBuffer.Length > 1024 * 1024 * 4) { errorMsg += "图片加密 后的大小超过4MB!"; recognitionString = ""; tempModel.state = false; tempModel.errorMsg = errorMsg; return tempModel; } #endregion #region 请求接口 recognitionString = ""; string host = "https://aip.baidubce.com/rest/2.0/ocr/v1/idcard?access_token=" + token; String str = "id_card_side=" + id_card_side + "&detect_direction=" + detect_direction + "&detect_risk=" + detect_risk + "&image=" + HttpUtility.UrlEncode(strbaser64); var tempResult = HttpRequestHelper.Post(host, str); recognitionString = tempResult; if (recognitionString.Contains("\"error_code\""))//说明异常 { resultState = false; tempModel.state = false; tempModel.errorTypeModel = Json.ToObject<ErrorTypeModel>(tempResult); tempModel.errorTypeModel.error_discription = ORC_CharacterRecognitionErrorType.GetErrorCodeToDescription(tempModel.errorTypeModel.error_code); } else { tempModel.state = true; tempModel.successModel = Json.ToObject<IDCardRecognitionSuccessResultModel>(tempResult); } #endregion return tempModel; } catch (Exception ex)//接口外部异常,如网络异常 { resultState = false; errorMsg = ex.ToString(); tempModel.state = false; tempModel.errorMsg = ex.ToString(); return tempModel; } } } }
winform 调用核心部分
/// <summary> /// 识别操作 /// </summary> /// <param name="filePath"></param> /// <param name="id_card_side">身份证 正面还是背面</param> /// <param name="detect_direction"></param> /// <param name="detect_risk"></param> public void Distinguish(string filePath, string id_card_side = "front", bool detect_direction = false, string detect_risk = "false") { DoTime();//主线程执行进度条,子线程进行数据请求操作 t1 = new Thread(new ThreadStart(() => { var temp = BaiduAIAPI.Access_Token.GetAccessToken(); if (temp.IsSuccess) { string data = ""; string error = ""; var result = IDCardRecognition.GetIdcardRecognitionString(temp.SuccessModel.access_token, filePath, ref data, out error, id_card_side, detect_direction, detect_risk); this.Invoke(new Action(() => { tb_showInfo.AppendText("\r\n -----------------------------------------------------------------"); })); if (result.state) { this.Invoke(new Action(() => { tb_showInfo.AppendText("\r\n ---------------------------识别成功-------------------------------"); tb_showInfo.AppendText("\r\n" + result.successModel.ToJson() + "\r\n"); })); } else { this.Invoke(new Action(() => { tb_showInfo.AppendText("\r\n-----------------------------识别失败!--------------------------------"); tb_showInfo.AppendText("\r\n" + result.successModel.ToJson() + result.errorMsg + "\r\n"); })); } } else { this.Invoke(new Action(() => { AttrMessage.ErrorMsg(temp.ErrorModel.error); })); } this.Invoke(new Action(() => { progressBar_ToReadDistinguish.Value = 100; timer1.Enabled = false; progressBar_ToReadDistinguish.Value = 0; })); })); t1.IsBackground = true; t1.Start(); }
效果如图:图中的身份证是我百度贴吧搜索的,不知道真伪。
PS:这个只是文字识别,并不是真正公安部联网识别(身份有效性识别),要连接公安部识别需要 付费。
三、整合应用
笔者的应用是结合自己写的插件化热插拔模式写的,把每个接口封装成为一个插件,采用注入形式动态化结合
为了便于友好用户体验,在请求使用加入进度条,采用新的线程去进行接口请求,防止 界面卡住。
源码地址:https://github.com/linbin524/AI_Project/tree/master