花了一个暑假做了身份证识别demo,也借鉴了各种资料,在这里记录下用到的思路和算法,作为一整个暑假学习的总结。身份证识别算法具体采用目标检测yolo5、文字检测dbnet、文字识别crnn。
由于以下两个原因,通过目标检测识别文字类型是必要的:
1.由于实际拍照环境复杂,并且图片中身份证具有不同的倾角,在识别文字前最好先定位文字位置。
2.身份证识别不同于ocr识别,身份证识别作为一个下游任务,姓名、性别等中文是不需要识别的,仅需要识别后面的实体。
在这里通过yolo5目标检测直接对身份证内姓名、性别、民族、出生、住址、身份证号码、人脸七个部分进行识别
对于复杂背景的图像,除了基本的预处理手段:二值化、哈弗变换等等,最有效的自然还是深度学习。这里通过yolo5目标检测,标注工具labelimg对500张身份证背面,300张身份证正面各个文字位置进行标注。
直接通过yolo5训练,测试发现效果不错。
图片识别结果
但由于样本数量不均衡,当民族出现少数民族或身份证样式与二代身份证不一致时,会出现同一部分文字,结果识别出两种类型,如图:
识别框重叠
通过观察识别错误的图片会存在一个类别,例如‘姓名’重复识别两次。因此通过遍历寻找重叠项和重复识别项,其中重复识别项为两个矩形检测框面积大于一定阈值threth则为重复,然后保留未重叠的元素删除重叠元素。通过该后处理能够降低手动标注图片的时间,并极大的提高准确率。
当我们完成yolo5目标检测后,我们能够获得七个类别的矩形检测框,为了防止身份证本身的倾角影响识别效果,我们要对其进行旋转处理。这里通过对身份证号码进行文字检测,对识别的文本框长边进行倾斜角度计算并旋转,同时我们要对文字进行0°与180°的角度判断,防止文字框倒置导致识别有误。
计算文本框角度的方法:首先将文本框四个点按顺时针排序。取横坐标最小点作为左上角,选取另外三点中随机一点连线。若另外两点分别在直线两侧(即一个点带入直线方程大于0,另一个点啊小于0),则构成顺时针排序,其中直线上侧点为右上,直线下侧点为左下,直线外侧端点为右下,至此四个坐标已顺时针排序。然后计算相邻两点距离,若长度较长则为长边。
以下为原图和翻转后。
处理前,身份证有倾角处理后,文字变成水平
在该部分由于下游任务数据太少,并且难以通过爬取获得身份证图像。这里采用百度开源的paddleocr里的预训练模型直接进行测试。同时由于采用的开源预训练模型,这限制了整个项目的准确率是以后的优化方向。
下面介绍用到的算法:
dbnet算法是一种文字检测算法。用来提取图片中的文本框坐标
当文字字体较大时,会出现文字检查后文本框太小未完整包括文字的问题,这里需要修改thresholdmap的阈值。
由于dbnet本身算法缺陷,当文字较为密集,会出现文字被截断的问题。因此进行后处理:对每个检测框的横坐标范围检测,如果两个检测框横坐标接近且纵坐标重叠,则合并为一块检测框送入目标识别。
对文本框进行文字识别。由于环境的多变,直接的crnn文字识别效果并不好,可以在此基础上进行后处理。
对于性别、民族,本身实体的字库很少,应把crnn结果作为参考并添加后处理规则,该操作能提高识别准确率,并对该部分的清晰要求降低。类似的,出生年月日也可以与身份证号码中7-14位相互对应。
下列3-1,3-2,3-3分别为原图、目标检测后图片、文本识别后结果。
图3-1 原图(来自互联网)图3-2 目标检测图3-3 ocr识别
各种模糊图片和生僻字,会对识别文字产生影响。因此应当增加文字纠错功能。
1.对于性别:男、女识别时,由于光照等因素导致的识别错误,可通过身份证号码第15位的校验码进行反向纠错
2.对于民族:可建立各个民族的字典,其中包含各种识别有误的字。当识别字不在56个民族且在字典中,且在错误字典中,则更正为字典键值。
3.对于地址信息,可通过国家各级地址的数据库,对错误的地址信息进行勘误。缺点:当某些地方区域重新改名划分后会把正确识别的地址错误的改为旧地址,可以考虑只纠错省、市信息。
在第一步文字区域的截取中,我采用了yolo目标检测的算法,把目标检测用在了文字分类的功能上,当时首先考虑的是文档分析,不过由于操作便捷还是采用了yolo5,并且在后处理后保证准确率达99%以上。
在crnn中,由于本身模型限制,中文文字识别准确率较低,对於姓名和身份证号码经过测试准确率只有91%。最优的方法是对百度开源的crnn模型进行fineturn,有待开学后实现。
第一次写知乎,贡献代码,欢迎各位大佬提供意见。
身份证识别地址,给个star谢谢啦。
其中,dbnet与crnn部分源码来自paddleocr,地址如下:
上一篇