美文网首页
身份证识别

身份证识别

作者: samychen | 来源:发表于2018-02-24 15:35 被阅读0次

  前面介绍了好些OpenCV基本知识之后,现在我们小试牛刀,稍微写个身份证识别功能出来,这里我们就把工程移植到安卓平台,其实核心业务逻辑是完全一样的。
项目地址:https://github.com/samychen/IDcardRecognization.git
  我们知道身份证上那么多文字,我们怎么知道去哪拿身份证号码?

  居民二代身份证除了基本信息不同,其他地方都是模板样式,那么我们可以先把敏感信息找到,也就是把身份证号码那一块区域先找到,我们可以把公民身份证那块区别作为匹配模板,找到整张图片的模板所在的区域,而OpenCV刚好提供了模板匹配的方法matchTemplate( InputArray image, InputArray templ,OutputArray result, int method, InputArray mask = noArray() )

身份证样板.png

  通过这个方法我们就找到了模板所在的区域,这下子是不是与想法了,我们拿到模板矩阵像素坐标后,是不是可以根据身份证像素坐标的宽度进行一定计算来确定真实身份证号码所在的区域范围了。

接下来我们可以确定真实号码所在区域的结构体范围

  • X:模板的左上角像素坐标x加上模板的宽
  • Y:模板的y
  • W:全图宽-(身份证(模版)X+身份证(模版)宽) - n(给个大概值)
  • H:模板的高

  有了以上参数我们就可以把号码所在的区域专门截取出来,是不是已经实现了最重要的功能了。

  当然,拿到号码之后我们还需要对号码去进行识别,这里我们采用tesseract-ocr训练的模型来识别具体号码,关于tesseract-ocr的使用可以自行去谷歌。

  这里还有许多需要优化的地方,身份证原图是彩色图片,考虑到OpenCV计算多通道图片需要耗费性能,在预处理阶段需要先转换为灰度图,之后还需要进行高斯边界模糊处理消除噪声的影响。

核心代码:

#include "common.h"


#define DEFAULT_IDCARD_WIDTH  640
#define DEFAULT_IDCARD_HEIGHT  320

#define DEFAULT_IDNUMBER_WIDTH  240
#define DEFAULT_IDNUMBER_HEIGHT  120

#define  FIX_IDCARD_SIZE Size(DEFAULT_IDCARD_WIDTH,DEFAULT_IDCARD_HEIGHT)
#define  FIX_IDNUMBER_SIZE  Size(DEFAULT_IDNUMBER_WIDTH,DEFAULT_IDNUMBER_HEIGHT)

#define FIX_TEMPLATE_SIZE  Size(150, 26)

extern "C"
JNIEXPORT jobject JNICALL
Java_com_samychen_gracefulwrapper_idcardrecognization_ImageUtils_findIdNumber(JNIEnv *env,
                                                                              jclass type,
                                                                              jobject src,
                                                                              jobject out,
                                                                              jobject tpl,
                                                                              jobject config) {

    //原始图
    Mat img_src;
    //灰度图 需要拿去模版匹配
    Mat img_gray;
    //二值图 进行轮廓检测
    Mat img_threshold;
    //高斯图 进行边界模糊
    Mat img_gaussian;
    //边界图
    Mat img_canny;
    //模版
    Mat img_tpl;
    //获得的身份证图
    Mat img_idCard;
    //获得的身份证号码图
    Mat img_idNumber;
    bitmap2Mat(env, src, img_src);
    bitmap2Mat(env, tpl, img_tpl);
    //灰度化
    cvtColor(img_src, img_gray, COLOR_BGRA2GRAY);
    //二值化
    threshold(img_gray, img_threshold, 100, 255, THRESH_BINARY);
    GaussianBlur(img_threshold,img_gaussian,Size(3,3),0);
    Canny(img_gaussian,img_canny,180,255);
    vector<vector<Point>> contours;
    vector<Vec4i> hierachy;//每个边界轮廓都由上下左右4个坐标组成,所以需要vector数据结构
    //轮廓检测 只检测外轮廓 并压缩水平方向,垂直方向,对角线方向的元素,只保留该方向的终点坐标,比如矩形就是存储四个点
    //findContours(img_threshold, contours, hierachy, RETR_EXTERNAL, CHAIN_APPROX_SIMPLE);
    findContours(img_canny, contours, hierachy, RETR_EXTERNAL, CHAIN_APPROX_SIMPLE);
    int width = img_src.cols >> 1;//图片宽的一半
    int height = img_src.rows >> 1;//图片高的一半
    if (contours.empty()) {
        //可能整张图就是身份证
        img_idCard = img_gray;
    } else {
        Rect roiArea;
        vector<Rect> roiAreas;
        Rect rectMin;
        for (auto points : contours) {
            //根据4个顶点获得区域
            Rect rect = boundingRect(points);
            //身份证轮廓的宽必须大于图片宽的一半
            //高必须大于图片高的一半
            if (rect.width >= width && rect.height >= height) {
                roiArea = rect;
                roiAreas.push_back(rect);
            }
        }
        if (roiAreas.size()>0){
            rectMin = roiAreas.at(0);//找出满足条件的所有轮廓中最小的就是正好身份证的轮廓
            for(int i=0;i<roiAreas.size();i++){
                Rect temp = roiAreas.at(i);
                if (temp.area()<rectMin.area()){
                    rectMin = temp;
                }
            }
        } else{
            rectMin = Rect(0,0,img_gray.cols,img_gray.rows);
        }
        img_idCard = img_gray(rectMin);
        //roiarea有面积
//        if (roiArea.area())
//            img_idCard = img_gray(roiArea);
    }
    resize(img_idCard, img_idCard, FIX_IDCARD_SIZE);//身份证大小640 x 400
    resize(img_tpl, img_tpl, FIX_TEMPLATE_SIZE);
    cvtColor(img_tpl, img_tpl, COLOR_BGRA2GRAY);//使用灰度图进行匹配,彩色图计算量太大
    int cols = img_idCard.cols - img_tpl.cols + 1;
    int rows = img_idCard.rows - img_tpl.rows + 1;
    //创建输出图像,输出图像的宽度 = 被查找图像的宽度 - 模版图像的宽度 + 1
    Mat match(rows, cols, CV_32F);
    //Mat match;
//        TM_SQDIFF 平方差匹配法
//        TM_CCORR 相关匹配法
//        TM_CCOEFF 相关系数匹配法
//        TM_SQDIFF_NORMED
//        TM_CCORR_NORMED
//        TM_CCOEFF_NORMED
    // 对于方法 SQDIFF 和 SQDIFF_NORMED, 越小的数值代表更高的匹配结果. 而对于其他方法, 数值越大匹配越好
    matchTemplate(img_idCard, img_tpl, match, TM_CCORR_NORMED);
    //归一化
    normalize(match, match, 0, 1, NORM_MINMAX, -1);
    Point maxLoc;
    minMaxLoc(match, 0, 0, 0, &maxLoc);
    //计算 [身份证(模版):号码区域]
    //号码区域:
    //x: 身份证(模版)的X+宽
    //y: 身份证(模版)Y
    //w: 全图宽-(身份证(模版)X+身份证(模版)宽) - n(给个大概值)
    //h: 身份证(模版)高
    Rect rect(maxLoc.x + img_tpl.cols, maxLoc.y, img_idCard.cols - (maxLoc.x + img_tpl.cols) - 40,
              img_tpl.rows);
    //拿二值的号码
    resize(img_threshold, img_threshold, FIX_IDCARD_SIZE);
    img_idNumber = img_threshold(rect);
    jobject obj=createBitmap(env,img_idNumber,config);
//    resize(img_idNumber, img_idNumber, FIX_IDNUMBER_SIZE);
//    mat2Bitmap(env, img_idNumber, out);


    img_src.release();
    img_gray.release();
    img_threshold.release();
    img_idCard.release();
    img_idNumber.release();
    img_tpl.release();
    match.release();
    return obj;
}

演示结果:


身份证原图.jpg 识别结果.jpg

相关文章

  • 身份证拍照识别sdk

    身份证拍照识别SDK,身份证拍照识别,android身份证拍照识别,身份证拍照识别 一、身份证拍照识别sdk应用背...

  • 微信小程序身份证ocr识别

    关键词:身份证识别 身份证ocr识别 微信小程序身份证识别 微信小程序ocr识别 身份证ocr识别api (网图,...

  • 身份证ocr识别核验webservice API接口调用

    关键词:身份证识别 身份证ocr识别 身份证核验 身份证识别核验 身份证ocr核验API 现在出门没有身份证可谓是...

  • 手机端证件ocr识别sdk

    关键词:证件ocr识别 安卓证件识别 ios证件识别 证件ocr识别SDK 身份证识别 身份证、驾驶证等证件是每个...

  • 移动端证件识别ocr SDK

    关键词:证件ocr识别 安卓证件识别 ios证件识别 证件ocr识别SDK 身份证识别 身份证、驾驶证等证件是每个...

  • OCR识别训练

    ============================身份证识别========================...

  • 【Python】Python利用百度AI进行文字识别

    1.通用文字识别 2.网络图片文字识别 识别一些网络上背景复杂,特殊字体的文字。 3.身份证识别 身份证识别包括正...

  • 简单的事情快乐做

    这次中考,我的工作是身份证核查。 工作极其简单:把身份证放到身份证识别仪上,听到“此身份证为真证”,或看到识别仪读...

  • 人工智能:身份证识别(OCR技术)

    1.什么是身份证识别 身份证识别是指使用技术对身份证信息自动提取,并对身份证信息按要素格式化输出信息,供计算机系统...

  • android,ios证件识别,手机只需扫一扫

    关键词:证件ocr识别 安卓证件识别 ios证件识别 证件ocr识别SDK 身份证识别 证件识别,该产品支持And...

网友评论

      本文标题:身份证识别

      本文链接:https://www.haomeiwen.com/subject/ibiqxftx.html