Python+Opencv身份证号码区域提取及识别实现

本文介绍了使用Python和OpenCV实现身份证号码的区域提取和识别,通过特征点匹配和相似度计算来确定每个数字。提供了实训环境和流程,强调了识别过程中模板制作和图像尺寸调整的重要性,以及实训中遇到的问题和解决方案。最后展示了代码效果。
摘要由CSDN通过智能技术生成

前端时间智能信息处理实训,我选择的课题为身份证号码识别,对中华人民共和国公民身份证进行识别,提取并识别其中的身份证号码,将身份证号码识别为字符串的形式输出。现在实训结束了将代码发布出来供大家参考,识别的方式并不复杂,并加了一些注释,如果有什么问题可共同讨论。最后重要的事情说三遍:请勿直接抄袭,请勿直接抄袭,请勿直接抄袭!尤其是我的学弟学妹们,还是要自己做的,小心直接拿我的用被老师发现了挨批_

实训环境:CentOS-7.5.1804 + Python-3.6.6 + Opencv-3.4.1

做测试用的照片以及数字识别匹配使用的模板(自制)提供给大家,通过查询得到,身份证号码使用的字体格式为OCR-B 10
BT格式,实训中用到的身份证图片为训练测试图片,有一部分是老师当时直接给出的,还有一部分是我自己用自己身份证做的测试和从网上找到了一张,由于部分身份证号码不是标准字体格式,对识别造成影响,所以有部分图片我还提前ps了一下。

流程图

前期处理的部分不在描述,流程图和代码注释中都有。其实整个过程并不是很复杂,本来想过在数字识别方面用现成的一些方法,或者想要尝试用到卷积神经网络(CNN)然后做训练集来识别。后来在和老师交流的时候,老师给出建议可以尝试使用特征点匹配或者其他类方法。根据最后数字分割出来单独显示的效果,想到了一个适合于我代码情况的简单方法。

建立一个标准号码库(利用上面自制模板数字分割后获得),然后用每一个号码图片与库中所有标准号码图片做相似度匹配,和哪一个模板相似度最高,则说明该图片为哪一位号码。在将模板号码分割成功后,最关键的一步就是进行相似度匹配。为提高匹配的精确度和效率,首先利用cv.resize()将前面被提取出的每位身份证号码以及标准号码库中的号码做图像大小调整,统一将图像均调整为12x18像素的大小,图像大小的选择是经过慎重的考虑的,如果太大则计算过程耗时,如果过小则可能存在较大误差。匹配的具体方案为:记录需要识别的图片与每个模板图片中有多少位置的像素点相同,相同的越多,说明相似度越高,也就最有可能是某个号码。最终将18位号码都识别完成后,得到的具体的相似度矩阵。

具体代码如下所示:


    import cv2 as cv
    import numpy as np
    import matplotlib.pyplot as plt
    
    # 将身份证号码区域从身份证中提取出
    def Extract(op_image, sh_image):
    
     binary, contours, hierarchy = cv.findContours(op_image,
      cv.RETR_TREE, cv.CHAIN_APPROX_SIMPLE)
     contours.remove(contours[0])
     max_x, max_y, max_w, max_h = cv.boundingRect(contours[0])
     color = (0, 0, 0)
     for c in contours:
     x, y, w, h = cv.boundingRect(c)
     cv.rectangle(op_image, (x, y), (x + w, y + h), color, 1)
     cv.rectangle(sh_image, (x, y), (x + w, y + h), color, 1)
     if max_w < w:
      max_x = x
      max_y = y
      max_w = w
      max_h = h
     cut_img = sh_image[max_y:max_y+max_h, max_x:max_x+max_w]
     cv.imshow("The recognized enlarged image", op_image)
     cv.waitKey(0)
     cv.imshow("The recognized binary image", sh_image)
     cv.waitKey(0)
     return cut_img
    
    # 号码内部区域填充(未继续是用此方法)
    def Area_filling(image, kernel):
     # The boundary image
     iterate = np.zeros(image.shape, np.uint8)
     iterate[:, 0] = image[:, 0]
     iterate[:, -1] = image[:, -1]
     iterate[0, :] = image[0, :]
     iterate[-1, :] = image[-1, :
  • 0
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值