印刷文字识别-身份证识别(阿里云)

Posted 头大的冯冯

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了印刷文字识别-身份证识别(阿里云)相关的知识,希望对你有一定的参考价值。

以下是自己根据阿里云api文档说明封装的工具类,主要是获取阿里云Oss身份证图片信息

阿里云api文档URL:https://market.aliyun.com/products/57124001/cmapi010401.html?spm=a2c4g.11186623.2.7.VojbRu

<?php

namespace Helper;

use org\\Response;
use think\\Controller;
use think\\Request;
use think\\Db;
use think\\Loader;

/**
 * 身份证识别
 * Class AutoRecognition
 * @package Helper
 * @author fgf <2018-06-07>
 */
class AutoRecognition
{
    /**
     * 读取远程图片的二进制流
     * @param string $url 远程图片URL地址
     * @return bool|string
     */
    public static function httpDownload($url=\'\'){
        if(empty($url)){
            return false;
        }
        ob_start();
        $contents = @readfile($url);
        $img = ob_get_contents();
        ob_end_clean();
        return $img;
    }

    /**
     * 身份证正面识别
     * $file 你的文件路径
     * $param $appcode 阿里云APPCODE
     * @return array
     */
    public static function face($file=\'\')
    {
        if (empty($file)) {
            return Response::response(1,\'图片为空\');
        }
        //请求阿里云api地址
        $url = "https://dm-51.data.aliyun.com/rest/160601/ocr/ocr_idcard.json";
        $appcode = config(\'APPCODE\');//读取配置文件阿里云APPCODE
        //你的文件路径
        //$file = "你的文件路径";
        //如果输入带有inputs, 设置为True,否则设为False
        $is_old_format = false;
        //如果没有configure字段,config设为空
        $config = array(
            "side" => "face"//身份证正反面类型:face/back
        );
        //$config = array()
        //打开文件
        if($fp = @fopen($file, "rb", 0)) {
            //$binary = fread($fp, filesize($file)); // 文件读取-filesize无法获取远程文件的大小,只能读取path路径文件
            $binary = self::httpDownload($file); // 文件读取-读取远程图片的二进制流
            fclose($fp);
            $base64 = base64_encode($binary); // 转码
        }else{
            return Response::response(1,\'图片打开失败,请检查图片路径是否正确\');
        }
        $headers = array();
        array_push($headers, "Authorization:APPCODE " . $appcode);
        //根据API的要求,定义相对应的Content-Type
        array_push($headers, "Content-Type".":"."application/json; charset=UTF-8");
        $querys = "";
        if($is_old_format == TRUE){
            $request = array();
            $request["image"] = array(
                "dataType" => 50,
                "dataValue" => "$base64"
            );

            if(count($config) > 0){
                $request["configure"] = array(
                    "dataType" => 50,
                    "dataValue" => json_encode($config)
                );
            }
            $body = json_encode(array("inputs" => array($request)));
        }else{
            $request = array(
                "image" => "$base64"
            );
            if(count($config) > 0){
                $request["configure"] = json_encode($config);
            }
            $body = json_encode($request);
        }
        $method = "POST";
        $curl = curl_init();
        curl_setopt($curl, CURLOPT_CUSTOMREQUEST, $method);
        curl_setopt($curl, CURLOPT_URL, $url);
        curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
        curl_setopt($curl, CURLOPT_FAILONERROR, false);
        curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($curl, CURLOPT_HEADER, true);
        if (1 == strpos("$".$url, "https://"))
        {
            curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
            curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false);
        }
        curl_setopt($curl, CURLOPT_POSTFIELDS, $body);
        $result = curl_exec($curl);
        $header_size = curl_getinfo($curl, CURLINFO_HEADER_SIZE);
        $rheader = substr($result, 0, $header_size);
        $rbody = substr($result, $header_size);

        $httpCode = curl_getinfo($curl,CURLINFO_HTTP_CODE);
        if($httpCode == 200){
            if($is_old_format){
                $output = json_decode($rbody, true);
                $result_str = $output["outputs"][0]["outputValue"]["dataValue"];
            }else{
                $result_str = $rbody;
            }
            //printf("result is :\\n %s\\n", $result_str);//这是阿里原生的结果打印
            //身份证读取内容输出
            return Response::response(0, json_decode($result_str));
        }else{
            //printf("Http error code: %d\\n", $httpCode);//这是阿里原生的结果打印
            //printf("Error msg in body: %s\\n", $rbody);//这是阿里原生的结果打印
            //printf("header: %s\\n", $rheader);//这是阿里原生的结果打印
            return Response::response(1,\'获取身份信息失败\');
        }
    }

    /**
     * 身份证反面识别
     * $param $file 你的文件路径
     * $param $appcode 阿里云APPCODE
     * @param string $file
     */
    public static function back($file=\'\')
    {
        if (empty($file)) {
            return Response::response(1,\'图片为空\');
        }
        //请求阿里云api地址
        $url = "https://dm-51.data.aliyun.com/rest/160601/ocr/ocr_idcard.json";
        $appcode = config(\'APPCODE\');//读取配置文件阿里云APPCODE
        //你的文件路径
        //$file = "你的文件路径";
        //如果输入带有inputs, 设置为True,否则设为False
        $is_old_format = false;
        //如果没有configure字段,config设为空
        $config = array(
            "side" => "back"//身份证正反面类型:face/back
        );
        //$config = array()
        //打开文件
        if($fp = @fopen($file, "rb", 0)) {
            //$binary = fread($fp, filesize($file)); // 文件读取-filesize无法获取远程文件的大小,只能读取path路径文件
            $binary = self::httpDownload($file); // 文件读取-读取远程图片的二进制流
            fclose($fp);
            $base64 = base64_encode($binary); // 转码
        }else{
            return Response::response(1,\'图片打开失败,请检查图片路径是否正确\');
        }
        $headers = array();
        array_push($headers, "Authorization:APPCODE " . $appcode);
        //根据API的要求,定义相对应的Content-Type
        array_push($headers, "Content-Type".":"."application/json; charset=UTF-8");
        $querys = "";
        if($is_old_format == TRUE){
            $request = array();
            $request["image"] = array(
                "dataType" => 50,
                "dataValue" => "$base64"
            );

            if(count($config) > 0){
                $request["configure"] = array(
                    "dataType" => 50,
                    "dataValue" => json_encode($config)
                );
            }
            $body = json_encode(array("inputs" => array($request)));
        }else{
            $request = array(
                "image" => "$base64"
            );
            if(count($config) > 0){
                $request["configure"] = json_encode($config);
            }
            $body = json_encode($request);
        }
        $method = "POST";
        $curl = curl_init();
        curl_setopt($curl, CURLOPT_CUSTOMREQUEST, $method);
        curl_setopt($curl, CURLOPT_URL, $url);
        curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
        curl_setopt($curl, CURLOPT_FAILONERROR, false);
        curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($curl, CURLOPT_HEADER, true);
        if (1 == strpos("$".$url, "https://"))
        {
            curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
            curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false);
        }
        curl_setopt($curl, CURLOPT_POSTFIELDS, $body);
        $result = curl_exec($curl);
        $header_size = curl_getinfo($curl, CURLINFO_HEADER_SIZE);
        $rheader = substr($result, 0, $header_size);
        $rbody = substr($result, $header_size);

        $httpCode = curl_getinfo($curl,CURLINFO_HTTP_CODE);
        if($httpCode == 200){
            if($is_old_format){
                $output = json_decode($rbody, true);
                $result_str = $output["outputs"][0]["outputValue"]["dataValue"];
            }else{
                $result_str = $rbody;
            }
            //printf("result is :\\n %s\\n", $result_str);//这是阿里原生的结果打印
            //身份证读取内容输出
            return Response::response(0, json_decode($result_str));
        }else{
            //printf("Http error code: %d\\n", $httpCode);
            //printf("Error msg in body: %s\\n", $rbody);
            //printf("header: %s\\n", $rheader);
            return Response::response(1,\'获取身份信息失败\');
        }
    }
}

工具类在tp5.0中的结构位置如下图

 正常返回示例

正面返回结果:
{
    
    "address"    : "浙江省杭州市余杭区文一西路969号",   #地址信息
    "config_str" : "{\\\\\\"side\\\\\\":\\\\\\"face\\\\\\"}",                #配置信息,同输入configure
    "face_rect":{
        "angle": -90,
        "center":{
            "x" : 952,
            "y" : 325.5
        },
        "size":{
            "height":181.99,
            "width":164.99
            }
    },                          #人脸位置,center表示人脸矩形中心坐标,size表示人脸矩形长宽,angle表示矩形顺时针旋转的度数。
    "name" : "张三",                                  #姓名
    "nationality": "汉", #民族 
    "num" : "1234567890",                             #身份证号
    "sex" : "男",                                     #性别
    "birth" : "20000101",                             #出生日期
    "nationality" : "汉",                             #民族
    "success" : true                                  #识别结果,true表示成功,false表示失败
}


反面返回结果:
{
    "config_str" : "{\\\\\\"side\\\\\\":\\\\\\"back\\\\\\"}",#配置信息,同输入configure
    "start_date" : "19700101",       #有效期起始时间
    "end_date" : "19800101",         #有效期结束时间
    "issue" : "杭州市公安局",         #签发机关
    "success" : true                   #识别结果,true表示成功,false表示失败
}

 

使用此工具类可参考如下步骤

1.Controller引入工具类 use Helper\\AutoRecognition;

2.方法接收参数 idcard_b-身份证正面 idcard_a-身份证国徽面 

public function save(Request $request)
    {
        $param = $request->only([\'username\', \'idnum\', \'mobile\', \'idcard_a\', \'idcard_b\']);
        $param[\'userid\'] = $this->userid;
        $param[\'status\'] = 0;
        
        //身份证正面识别
        $res = self::check_idcard_face_message($param);
        if (!$res) {
            return Response::response(1,\'填写身份证号码与证件号码不符\');
        }
        //身份证反面识别
        $res1 = self::check_idcard_back_message($param);
        if (!$res1) {
            return Response::response(1,\'身份证已过期\');
        }
    }

 

3.调用工具类验证

/**
     * 身份证正面信息校对
     * @param $file 身份证正面图片
     * @return bool
     */
    public static function check_idcard_face_message($param)
    {
        if ($param[\'idcard_b\']) {
            $file = get_image_url($param[\'idcard_b\']);
        } else {
            return false;
        }
        //调取阿里身份认证api获取身份证信息
        $data =  AutoRecognition::face($file);
        //dump($data);exit;
        if($data[\'data\'] != \'获取身份信息失败\' && $data[\'data\']->num == $param[\'idnum\']){
            return true;
        }else{
            return false;
        }
    }

    /**
     * 身份证反面信息校对
     * @param $file 身份证反面图片-国徽面
     * @return bool
     */
    public static function check_idcard_back_message($param)
    {
        if ($param[\'idcard_a\']) {
            $file = get_image_url($param[\'idcard_a\']);
        } else {
            return false;
        }
        //调取阿里身份认证api获取身份证信息
        $data =  AutoRecognition::back($file);
        //dump($data);exit;
        if ($data[\'data\'] != \'获取身份信息失败\') {
            $end_date = $data[\'data\']->end_date;//提取身份证过期时间
            $y = substr($end_date,0,4);//截取年
            $m = substr($end_date,4,2);//截取月
            $d = substr($end_date,6,2);//截取日
            $last_date_unix = strtotime($y.\'-\'.$m.\'-\'.$d);//身份证截止日时间戳
            $today_unid = strtotime(date(\'Y-m-d\'));//今日时间戳
            //身份证截止日时间戳 > 今日时间戳,身份证未过期,返回true
            if($last_date_unix > $today_unid){
                return true;
            } else {
                return false;
            }
        } else {
            return false;
        }

    }

 

以上是关于印刷文字识别-身份证识别(阿里云)的主要内容,如果未能解决你的问题,请参考以下文章

调用阿里云的通用文字识别-高精版识别接口,识别图片中的文字详解

如何用阿里云的API进行身份证识别

微信小程序开发工具结合腾讯云开发AI人脸识别和身份证识别——基于腾讯云开发者实验项目

Python使用阿里API进行身份证识别

文档地址整理

iOS身份证号码识别