1. 程式人生 > >C#百度OCR-身份證圖片識別提取資訊

C#百度OCR-身份證圖片識別提取資訊

之前寫了一篇利用百度OCR進行本地和網路圖片識別文字的文章,點選檢視。今天補充識別身份證圖片的文章及demo

原始碼地址:https://download.csdn.net/download/horseroll/10681214

效果圖展示:

呼叫的是百度的API介面。API文件:http://ai.baidu.com/docs#/OCR-API/top

請求的URL地址(post):https://aip.baidubce.com/rest/2.0/ocr/v1/idcard

請求引數:

返回引數:

1.首先先根據API key和Secret key得到token。API key和Secret key去百度雲的控制檯可以免費申請

string token=getAccessToken();
// 呼叫getAccessToken()獲取的 access_token建議根據expires_in 時間 設定快取
// 返回token示例
public static String TOKEN = "24.adda70c11b9786206253ddb70affdc46.2592000.1493524354.282335-1234567";

// 百度雲中開通對應服務應用的 API Key 建議開通應用的時候多選服務
private static String clientId = "cohIahxAt7HveHLYSHYK6G5N";
// 百度雲中開通對應服務應用的 Secret Key
private static String clientSecret = "e8SAsDIWSK9NPUKviYiPQNlfaVDXQSY5";

public static String getAccessToken()
{
    String authHost = "https://aip.baidubce.com/oauth/2.0/token";
    //string result = ToolData.HttpPost(authHost, "grant_type=client_credentials&client_id="+clientId+"&client_secret="+clientSecret);
    HttpClient client = new HttpClient();
    List<KeyValuePair<String, String>> paraList = new List<KeyValuePair<string, string>>();
    paraList.Add(new KeyValuePair<string, string>("grant_type", "client_credentials"));
    paraList.Add(new KeyValuePair<string, string>("client_id", clientId));
    paraList.Add(new KeyValuePair<string, string>("client_secret", clientSecret));

    HttpResponseMessage response = client.PostAsync(authHost, new FormUrlEncodedContent(paraList)).Result;
    String result = response.Content.ReadAsStringAsync().Result;
    Console.WriteLine(result);
    return result;
}

2.本地圖片進行上傳解析(POST提交)其實就是一句post程式碼

private void btnlocal_Click(object sender, EventArgs e)
{
    OpenFileDialog filename = new OpenFileDialog();
    filename.InitialDirectory = Application.StartupPath;
    filename.Filter = "All files(*.*)|*.*|image files|*.jpg;*.png;*.bmp";
    filename.FilterIndex = 2;
    filename.RestoreDirectory = true;
    if (filename.ShowDialog() == DialogResult.OK)
    {
        //本地圖片.解析影象資料,base64編碼後進行urlencode,要求base64編碼和urlencode後大小不超過4M,最短邊至少15px,最長邊最大4096px,支援jpg/png/bmp格式,當image欄位存在時url欄位失效
        bool cardjiaodu = cbjiaodu.Text == "true" ? true : false;
        string cardzhengfan= cbzhengfan.Text == "front" ? "front" : "back";
        bool cardfengxian = cbfengxian.Text == "true" ? true : false;
        string local = filename.FileName.ToString();//本地圖片的路徑地址
        tblocal.Text = local;
        string base64 = UrlEncode(ImgToBase64String(Image.FromFile(local)));
        string localpicure = ToolData.HttpPost("https://aip.baidubce.com/rest/2.0/ocr/v1/idcard", "access_token=" + token + "&detect_direction=" + cardjiaodu + "&id_card_side=" + cardzhengfan + "&image=" + base64 + "&detect_risk=" + cardfengxian);
        WriteTo(localpicure);
        pictureBox1.Image = Image.FromFile(local);
    }
}

附帶上圖片轉base64程式碼

public String ImgToBase64String(Image bmp)
{
    String strbaser64 = String.Empty;
    var btarr = convertByte(bmp);
    strbaser64 = Convert.ToBase64String(btarr);

    return strbaser64;
}
/// <summary>
/// Image轉byte[]
/// </summary>
/// <param name="img">Img格式資料</param>
/// <returns>byte[]格式資料</returns>
public static byte[] convertByte(Image img)
{
    MemoryStream ms = new MemoryStream();
    img.Save(ms, img.RawFormat);
    byte[] bytes = ms.ToArray();
    ms.Close();
    return bytes;
}
public static string UrlEncode(string str)
{
    StringBuilder sb = new StringBuilder();
    byte[] byStr = System.Text.Encoding.UTF8.GetBytes(str); //預設是System.Text.Encoding.Default.GetBytes(str)
    for (int i = 0; i < byStr.Length; i++)
    {
        sb.Append(@"%" + Convert.ToString(byStr[i], 16));
    }
    return (sb.ToString());
}

3.識別後的json內容進行輸出

/// <summary>
/// 在介面上顯示
/// </summary>
/// <param name="returnstr"></param>
public void WriteTo(string returnstr)
{
    try
    {
        ReturnJsonForCard rj = CYQ.Data.Tool.JsonHelper.ToEntity<ReturnJsonForCard>(returnstr);
        AReturnJsonForCard acj = CYQ.Data.Tool.JsonHelper.ToEntity<AReturnJsonForCard>(rj.words_result);
        string resultstr = "";
        resultstr += "姓名:"+acj.姓名.words + "\r\n"+ "性別:" + acj.性別.words + "\r\n"+ "民族:" + acj.民族.words + "\r\n"+ "出生:" + acj.出生.words + "\r\n"+ "住址:" + acj.住址.words + "\r\n"+ "公民身份號碼:" + acj.公民身份號碼.words + "\r\n";
        string card_direction = "";
        if(rj.direction=="-1")
        {
            card_direction = "未定義";
        }
        else if (rj.direction == "0")
        {
            card_direction = "正向";
        }
        else if (rj.direction == "1")
        {
            card_direction = "逆時針90度";
        }
        else if (rj.direction == "2")
        {
            card_direction = "逆時針180度";
        }
        else if (rj.direction == "3")
        {
            card_direction = "逆時針270度";
        }
        resultstr += "影象方向:" + card_direction + "\r\n";

        string card_image_status = "";
        if(rj.image_status=="normal")
        {
            card_image_status = "識別正常";
        }
        else if(rj.image_status == "reversed_side")
        {
            card_image_status = "身份證正反面顛倒";
        }
        else if (rj.image_status == "non_idcard")
        {
            card_image_status = "上傳的圖片中不包含身份證";
        }
        else if (rj.image_status == "blurred")
        {
            card_image_status = "身份證模糊";
        }
        else if (rj.image_status == "other_type_card")
        {
            card_image_status = "其他型別證照";
        }
        else if (rj.image_status == "over_exposure")
        {
            card_image_status = "身份證關鍵欄位反光或過曝";
        }
        else if (rj.image_status == "unknown")
        {
            card_image_status = "未知狀態";
        }

        resultstr += "識別狀態:" + card_image_status + "\r\n";

        string card_risk_type = "";
        if (rj.risk_type == "normal")
        {
            card_risk_type = "正常";
        }
        else if(rj.risk_type == "copy")
        {
            card_risk_type = "影印件";
        }
        else if (rj.risk_type == "temporary")
        {
            card_risk_type = "臨時身份證";
        }
        else if (rj.risk_type == "screen")
        {
            card_risk_type = "翻拍";
        }
        else if (rj.risk_type == "unknown")
        {
            card_risk_type = "其他未知情況";
        }
        resultstr += "識別身份證型別:" + card_risk_type + "\r\n";

        resultstr += "圖片編輯工具:" + rj.edit_tool + "\r\n";
        richTextBox1.Clear();
        richTextBox1.AppendText(resultstr);
    }
    catch (Exception ex)
    {
        MessageBox.Show("解析出錯,出錯原因:" + ex.Message);
    }
}

5.json字串的類

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace 百度OCR
{
    public class ReturnJsonForCard
    {
        public string log_id { get; set; }
        public string direction { get; set; }
        public string image_status { get; set; }
        public string risk_type { get; set; }
        public string edit_tool { get; set; }
        public string words_result_num { get; set; }
        public string words_result { get; set; }
    }
    public class AReturnJsonForCard
    {
        public BReturnJsonForCard 住址 { get; set; }
        public BReturnJsonForCard 出生 { get; set; }
        public BReturnJsonForCard 姓名 { get; set; }
        public BReturnJsonForCard 公民身份號碼 { get; set; }
        public BReturnJsonForCard 性別 { get; set; }
        public BReturnJsonForCard 民族 { get; set; }
    }
    public class BReturnJsonForCard
    {
        public string location { get; set; }
        public string words { get; set; }
    }
}

6.HttpPost方法。也可以自己用其他post方法

/// <summary>
/// HTTP POST方式請求資料
/// </summary>
/// <param name="url">URL.</param>
/// <param name="param">POST的資料</param>
/// <returns></returns>
public static string HttpPost(string url, string param)
{
    HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(url);
    request.Method = "POST";
    request.ContentType = "application/x-www-form-urlencoded";
    request.Accept = "*/*";
    request.Timeout = 15000;
    request.AllowAutoRedirect = false;
    StreamWriter requestStream = null;
    WebResponse response = null;
    string responseStr = null;
    try
    {
        requestStream = new StreamWriter(request.GetRequestStream());
        requestStream.Write(param);
        requestStream.Close();
        response = request.GetResponse();
        if (response != null)
        {
            StreamReader reader = new StreamReader(response.GetResponseStream(), Encoding.UTF8);
            responseStr = reader.ReadToEnd();
            reader.Close();
        }
    }
    catch (Exception)
    {
        throw;
    }
    finally
    {
        request = null;
        requestStream = null;
        response = null;
    }
    return responseStr;
}