/ocr/mask_idcard

优质
小牛编辑
156浏览
2023-12-01

1.接口描述

该 API 的功能为识别静态身份证图像上的文字信息,并输出一张关键信息打码后的身份证图片。

算法主要针对第二代居民身份证,其他类型身份证检测结果准确率较低,仅供参考。

  • 图片要求
    1. 格式为 JPG(JPEG),BMP,PNG,GIF,TIFF
    2. 宽和高大于 8px,小于等于4000px
    3. 小于等于 5 MB
  • 支持自动识别人脸方向
    1. 上传的图片中包含有 exif 方向信息,先按此信息旋转、翻转后再做识别人脸方向并调整,并在返回结果中给出 exif_orientation 字段(如果没有则不输出)
    2. 如果照片方向混乱且 exif 方向信息不存在或不正确,自动识别人脸方向并调整

请求方式

POST

请求 URL

https://cloudapi.linkface.cn/ocr/mask_idcard

2.请求参数

字段类型必需描述
api_idstringAPI 账户
api_secretstringAPI 密钥
filefile见下方注释需上传的图片文件,上传本地图片进行检测时选取此参数
urlstring见下方注释图片网络地址,采用抓取网络图片方式时需选取此参数
image_idstring见下方注释图片的id,在云端上传过图片可采用
auto_rotateboolean开启图片自动旋转功能。开通:true,不开通:false。默认值为 true
mask_nameboolean遮盖名字(不包含姓)。遮盖:true,不遮盖:false。默认值为 true
mask_birthdayboolean遮盖生日(不包含出生年份)。遮盖:true,不遮盖:false。默认值为 true
mask_addressboolean遮盖遮盖市/区/县之后的详细住址,省市不遮盖 。遮盖:true,不遮盖:false。默认值为 true
mask_numberboolean遮盖身份证号码(不包前六位)。遮盖:true,不遮盖:false。默认值为 true
mask_eyeboolean遮盖人眼 。遮盖:true,不遮盖:false。默认值为 true
mask_authorityboolean遮盖签发机关中的省市信息 。遮盖:true,不遮盖:false。默认值为 true
sidestring身份证朝向。身份证正面(有照片的一面): front ,身份证反面:back ,系统自动识别auto 。默认值为 auto

请求参数 file,urlimage_id 三选一。

url 中含有不少特殊字符,若将 URL 放入 Query String 中则需要对这些字符进行转义,所有中文和特殊字符必需以UTF-8编码转义。 目前支持 http/https 等协议的网络地址。下载限时 5s,超时后仍未下载完成则属于失败。 参数 file 需把图片文件的内容以 multipart/form-data 的形式放到 POST 消息体中。

打开自动旋转功能会增加运算时间,请酌情考虑是否开通此功能

3.返回参数

字段类型说明
request_idstring本次请求的id
statusstring状态,正常为 OK,其他值表示失败,详见错误码
image_idstring图片上传云端后的id 。使用file、url方式提交图片会返回此参数
exif_orientationintegerexif 信息。若图片含有exif信息返回此参数,返回值范围为 1~8 。返回值的具体含义请参考 http://jpegclub.org/exif_orientation.html
sidestring身份证方向信息。front代表身份证正面,back` 代表身份证反面
rotatestring旋转角度。开启自动旋转功,返回旋转的角度值,可能的值为 cw90,cw180,cw270,表明顺时针旋转的角度。如果没有发生旋转,则不返回此字段
infoobject身份证文字信息,详见 info数组中字段的结构
validityobject各项信息有效性,详见validity数组中字段的结构
text_regionobject各项信息在输出图片的坐标位置,详见text_region数组中字段的结构
masked_idcardstring经base64编码的打码后的照片

info数组中字段的结构:

字段类型说明
namestring姓名
sexstring性别
nationstring民族
yearstring出生年
monthstring出生月
daystring出生日
addressstring地址
numberstring身份证号
authoritystring签发机关
timelimitstring身份证有效期

validity数组中字段的结构:

字段类型说明
nameboolean如果小于两个字符,或者包含数字,为 false,反之为 true
sexboolean当检测出的性别与身份证号所表示的性别匹配,则为 true,反之为 false
birthdayboolean当检测出的出生日期与身份证号中的生日字段匹配,则值为 true,反之为 false
addressboolean身份证号码前6位为地区码,当其在预设的码表内,则值为 true,否则为 false
numberboolean当身份证号码符合校验规则,则值为 true,反之,为 false
authorityboolean检测出签发机构后两字是“分局”或“安局”,则为 true,否则为 false
timelimitboolean身份证有效期长度为 17 位,第八位为 -,年份大于等于 2000 年且小于等于 2050 年时,该值为 true,否则为 false

text_region数组中字段的结构:

字段类型说明
namearray of int姓名在输出图片中的位置(矩形的左上角和右下角坐标), [left, top, right, bottom]
sexarray of int性别在输出图片中的位置(矩形的左上角和右下角坐标), [left, top, right, bottom]
nationarray of int民族在输出图片中的位置(矩形的左上角和右下角坐标), [left, top, right, bottom]
yeararray of int出生年在输出图片中的位置(矩形的左上角和右下角坐标), [left, top, right, bottom]
montharray of int出生月在输出图片中的位置(矩形的左上角和右下角坐标), [left, top, right, bottom]
dayarray of int出生日在输出图片中的位置(矩形的左上角和右下角坐标), [left, top, right, bottom]
addressarray of int地址在输出图片中的位置(矩形的左上角和右下角坐标), [left, top, right, bottom]
numberarray of int身份证号在输出图片中的位置(矩形的左上角和右下角坐标), [left, top, right, bottom]
authorityarray of int签发机关在输出图片中的位置(矩形的左上角和右下角坐标), [left, top, right, bottom]
timelimitarray of int身份证有效期在输出图片中的位置(矩形的左上角和右下角坐标), [left, top, right, bottom]

infovalidity 结构中 authoritytimelimit 字段为身份证反面内容, 其余为身份证正面内容。

当上传的图片是非身份证图片时,系统不会报错,但这种情况下 validity 中所有字段都会为 false,请参考 validity 字段进行判断。

  • 身份证正面
{
  "request_id": "TID8bf47ab6eda64476973cc5f5b6ebf57e",
  "status": "OK",
  "exif_orientation": 1,
  "side": "front",
  "rotate": "cw270",
  "image_id":"xxxxx",
  "info": {
    "name": "小红",
    "sex": "女",
    "nation": "汉",
    "year": "1990",
    "month": "2",
    "day": "14",
    "address": "北京市海淀区xx路xx号",
    "number": "360722199002148230"
  },
  "validity": {
    "name": true,
    "sex": true,
    "birthday": true,
    "address": true,
    "number": true
  },
  "text_region": {
    "name": [215, 94, 425, 152],
    "sex": [225,208,290,255],
    "nation": [480,209,552,255],
    "year": [225,311,355,352],
    "month": [428,312,480,352],
    "day": [550,312,603,352],
    "address": [212,411,779,531],
    "number": [425,670,1141,723]
  },
 "masked_idcard": "/9j/2wBDAAgGBgcGBQgHBwcJCQgKDBQNDAsLDBkSEw8UHRofHh0aHBwgJC4n........"
}
  • 身份证反面
{
  "request_id": "TID8bf47ab6eda64476973cc5f5b6ebf57e",
  "status": "OK",
  "side": "back",
  "image_id":"xxxxx",
  "info": {
    "authority": "宜昌市公安局西陵分局",
    "timelimit": "20060529-20260529"
  },
  "validity": {
    "authority": true,
    "timelimit": true
  },
  "text_region": {
    "authority": [215, 94, 425, 152],
    "timelimit": [225,208,290,255]
  },
  "masked_idcard": "/9j/2wBDAAgGBgcGBQgHBwcJCQgKDBQNDAsLDBkSEw8UHRofHh0aHBwgJC4n........"
}

4.错误码

状态码status 字段说明
400ENCODING_ERROR参数非UTF-8编码
400DOWNLOAD_TIMEOUT网络地址图片获取超时
400IMAGE_ID_NOT_EXIST图片不存在
400CORRUPT_IMAGE文件不是图片文件或已经损坏
400DOWNLOAD_ERROR网络地址图片获取失败
400DOWNLOAD_TIMEOUT图片下载超时
400IMAGE_FILE_SIZE_TOO_BIG图片体积过大
400INVALID_IMAGE_FORMAT_OR_SIZE图片大小或格式不符合要求
400INVALID_ARGUMENT请求参数错误,具体原因见 reason 字段内容
401UNAUTHORIZED账号或密钥错误
401KEY_EXPIRED账号过期,具体情况见 reason 字段内容
403RATE_LIMIT_EXCEEDED调用频率超出限额
403NO_PERMISSION无调用权限
403OUT_OF_QUOTA调用次数超出限额
404NOT_FOUND请求路径错误
500INTERNAL_ERROR服务器内部错误
{
  "status": "INVALID_ARGUMENT",
  "reason": "must specify 'image_id', 'file' or 'url' argument",
  "request_id": "TID8bf47ab6eda64476973cc5f5b6ebf57e"
}

5.输入示例

  • cURL 样例
curl -X POST "https://cloudapi.linkface.cn/ocr/idcard?api_id=ID&api_secret=SECRET" \
  -F file=@/PATH/TO/IMAGE
  • HTTPie 样例
http -f POST "https://cloudapi.linkface.cn/ocr/idcard?api_id=ID&api_secret=SECRET" \
  file@/PATH/TO/IMAGE
  • C++ 样例
#include <iostream>
#include <cstring>
#include <exception>
#include <curl/curl.h>
#include <json/json.h>

using namespace std;
size_t callback(char *ptr, size_t size, size_t nmemb, string &stream){

  size_t sizes = size*nmemb;
  string temp(ptr,sizes);
  stream += temp;
  return sizes;
}
int main( int argv, char * argc[] ){

  CURL *curl;
  CURLM *multi_handle;
  CURLcode res;
  long code;
  string stream;
  struct curl_httppost *formpost = NULL;
  struct curl_httppost *lastptr = NULL;
  struct curl_slist *headerlist = NULL;

  try{

    curl_global_init(CURL_GLOBAL_DEFAULT);
    curl = curl_easy_init();

    if( curl ){

      curl_formadd(&formpost,&lastptr,CURLFORM_COPYNAME,"api_id",
                  CURLFORM_COPYCONTENTS, "ID",CURLFORM_END);
      curl_formadd(&formpost,&lastptr,CURLFORM_COPYNAME,"api_secret",
                  CURLFORM_COPYCONTENTS, "SECRET",CURLFORM_END);
      curl_formadd(&formpost,&lastptr,CURLFORM_COPYNAME,"file",
                  CURLFORM_FILE, argc[1], CURLFORM_END);

      curl_easy_setopt(curl, CURLOPT_URL, "https://cloudapi.linkface.cn/ocr/idcard");
      curl_easy_setopt(curl, CURLOPT_HTTPPOST, formpost);
      curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, callback);
      curl_easy_setopt(curl, CURLOPT_WRITEDATA, &stream);

      #ifdef SKIP_PEER_VERIFICATION
        curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L);
      #endif
      #ifdef SKIP_HOSTNAME_VERIFICATION
        curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L);
      #endif

      res = curl_easy_perform(curl);

      if( res != CURLE_OK ){
        cout<<"curl_easy_perform() failed:"<<curl_easy_strerror(res)<<endl;
        return -1;
      }
      curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &code);
      Json::Value res_data;
      Json::Reader *reader = new Json::Reader(Json::Features::strictMode());
      if(!reader->parse(stream, res_data)){
        cout<<"parse error";
        return -1;
      }
      cout<<"HTTP Status Code:"<<code<<endl;
      cout<<res_data<<endl;
      curl_easy_cleanup(curl);
  }
    curl_global_cleanup();

  }catch(exception &ex){
    cout<<"curl exception:"<<ex.what()<<endl;
  }
}
  • Java 样例
import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.mime.MultipartEntity;
import org.apache.http.entity.mime.content.FileBody;
import org.apache.http.entity.mime.content.StringBody;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.util.EntityUtils;

public class httpClientPost {

      public static final String api_id = "ID"; 
      public static final String api_secret = "SECRET"; 
      public static final String filepath = "C:/Users/card.jpg";//图片路径
      public static final String POST_URL = "https://cloudapi.linkface.cn/ocr/idcard";

      public static void HttpClientPost() throws ClientProtocolException, IOException {
            HttpClient httpclient = new DefaultHttpClient();
            HttpPost post = new HttpPost(POST_URL);
            FileBody fileBody = new FileBody(new File(filepath));
            StringBody id = new StringBody(api_id);
            StringBody secret = new StringBody(api_secret);
            MultipartEntity entity = new MultipartEntity();
            entity.addPart("file", fileBody);
            entity.addPart("api_id", id);
            entity.addPart("api_secret", secret);
            post.setEntity(entity);

            HttpResponse response = httpclient.execute(post);
            if (response.getStatusLine().getStatusCode() == 200) {
                HttpEntity entitys = response.getEntity();
                BufferedReader reader = new BufferedReader(
                    new InputStreamReader(entitys.getContent()));
                String line = reader.readLine();
                System.out.println(line);
            }else{
                HttpEntity r_entity = response.getEntity();
                String responseString = EntityUtils.toString(r_entity);
                System.out.println("错误码是:"+response.getStatusLine().getStatusCode()+"  "+response.getStatusLine().getReasonPhrase());
                System.out.println("出错原因是:"+responseString);
                //你需要根据出错的原因判断错误信息,并修改
            }

            httpclient.getConnectionManager().shutdown();
      }


    public static void main(String[] args) throws ClientProtocolException, IOException {
        HttpClientPost();
    }
}
  • Ruby 样例
require 'net/http/post/multipart'
require 'json'

begin
  uri = URI.parse('https://cloudapi.linkface.cn/ocr/idcard')
  File.open("px.jpg") do |jpg|
    req = Net::HTTP::Post::Multipart.new uri.path,
          "file" => UploadIO.new(jpg, "image/jpeg", "idcard.jpg"),
          "api_id" => "ID",
          "api_secret" => "SECRET"
    res = Net::HTTP.start(uri.host, uri.port, :use_ssl => uri.scheme == 'https') do |http|
      http.request(req)
    end
    result = JSON.parse(res.body)
    puts result
  end
rescue Exception => e
  puts e.message
end
  • Python 样例

我们提供的样例支持 Python 2.7 & 3.4–3.7 和 PyPy,其他版本暂不提供,需要您查阅相关资料。

import requests

try:
    host = 'https://cloudapi.linkface.cn'
    url = host + '/ocr/mask_idcard'
    files = {'file': open('/image/file/path', 'rb')}
    data = {'api_id': 'ID','api_secret': 'SECRET'}

    response = requests.post(url, files = files, data = data)
    result = response.json()
    print result
except Exception as e:
    print("type error: " + str(e))
  • PHP 样例

我们提供的样例是基于 PHP 5.5 与 PHP 5.6 两个版本,其他版本暂不提供,需要您查阅相关资料。

以下样例是基于 PHP 5.5 版本的。

<?php
   $testurl = 'https://cloudapi.linkface.cn/ocr/idcard';  
   $filePath = 'C:/Users/idcard.jpg';  //图片路径
   $fileContent = '@' . realpath($filePath);
   $post_data = array ('api_id' => 'ID','api_secret' => 'SECRET',
             'file'=>$fileContent);
   $ch = curl_init();
   curl_setopt($ch, CURLOPT_URL, $testurl);
   curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
   curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);//您可以根据需要,决定是否打开SSL验证
   curl_setopt($ch, CURLOPT_POST,1);
   curl_setopt($ch, CURLOPT_POSTFIELDS, $post_data);
   $output = curl_exec($ch);
   var_dump($output);
   curl_close($ch);
?>

以下样例是基于 PHP 5.6 版本的。

<?php
   $testurl = 'https://cloudapi.linkface.cn/ocr/idcard';  
   $filePath = 'C:/Users/idcard.jpg';  //图片路径
   $fileContent = new \CURLFile($filePath);
   $post_data = array ('api_id' => 'ID','api_secret' => 'SECRET',
             'file' => $fileContent);
   $ch = curl_init();
   curl_setopt($ch, CURLOPT_URL, $testurl);
   curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
   curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);//您可以根据需要,决定是否打开SSL验证
   curl_setopt($ch, CURLOPT_POST,1);
   curl_setopt($ch, CURLOPT_POSTFIELDS, $post_data);
   $output = curl_exec($ch);
   var_dump($output);
   curl_close($ch);
?>