这边小编提前去百度找了几张别人ps过的身份证照片,但是可以用的,我接下来会通过这个身份证照片查询到身份证号码(字体的格式为OCR-B 10 BT
格式)小编在这里提醒各位不要把一些隐私的东西发到网上,以免被一些图谋不轨的人利用你的这些隐私信息做一些违法犯罪的事情,小编在这里就找了三张图片如下:
接下来就是实现这个功能的流程图:
流程图介绍:
前期处理的部分不在描述,流程图和代码注释中都有。其实整个过程并不是很复杂,本来想过在数字识别方面用现成的一些方法,或者想要尝试用到卷积神经网络(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, :]
while True