python-opencv识别身份证图片并拼接

对接的银行要求扫描身份证正反面,放在一张A4纸上,而且大小和原证相同。本来也没啥,扫描就完事了。可单位的扫描仪是老款,一次只能扫一面,放在A4纸中间。文员小姐姐找我帮忙,我肯定义不容辞啊。所以就开始了一下的过程:

python-opencv识别身份证图片并拼接_第1张图片python-opencv识别身份证图片并拼接_第2张图片python-opencv识别身份证图片并拼接_第3张图片

1.截图工具+word

用截图工具截好放进word,大小又跟原来的肯定不一样,调成一样的非常麻烦。

2.找APP:

市面上现在有很多扫描APP,用手机就能扫出不错的效果,更是很清楚这些银行的要求,大小一样,A4纸上。坑爹的是这玩意竟然收费动辄30,40一个月。晕。

3.自己写:

    3.1想来想去用Python写一下应该很简单,所以就自己写了一下。代码:https://github.com/liuzehao/Stitching-ID-Card

   3.2考虑到一个让一个小白用python,估计难度较大,我也懒得给windows装环境,想到了能不能打包成exe(真是聪明又贴心啊),没想到还真有这种好东西。名曰:PyInstaller(http://www.pyinstaller.org/)

遇到了几个BUG记录一下:

3.2.1 ModuleNotFoundError: No module named 'setuptools._vendor' 

更新下即可:

pip install --upgrade setuptools

 3.2.2 Cannot find existing PyQt5 plugin directories

安装一下即可:

pip install python-qt5

5.11更新今天小姐姐说不好用,因为每次扫描出来的位置并不是固定的。好吧,用opencv来检测出来身份证,然后再来实现了一下。花了一个上午(大哭):

大概流程为:

1.高斯滤波

2.边缘检测

3.膨化处理

4.找边缘

5.找凸包

6.多边拟合

7.特征选取

def find(img):
    gray=cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)#转化为灰度图
    blur = cv2.GaussianBlur(gray, (3, 3),0)  # 用高斯滤波处理原图像降噪
    canny = cv2.Canny(blur, 20, 30)  # 20是最小阈值,50是最大阈值 边缘检测
    kernel = cv2.getStructuringElement(cv2.MORPH_RECT,(3, 3))
    dilation = cv2.dilate(canny,kernel,iterations = 1)#膨胀一下,来连接边缘
    contours, hierarchy = cv2.findContours(dilation,cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)#找边框
#cv2.drawContours(img,contours,-1,(0,255,0),10)  
    p1=()
    p2=()
    p3=()
    p4=()
    pp=[p1,p2,p3,p4]
#筛选边框

    for t in range(len(contours)):
        hull = cv2.convexHull(contours[t])
        epsilon = 0.1*cv2.arcLength(hull, True)#0.36081735求边框周长,epsilon 是精度
  
        point=cv2.approxPolyDP(hull, epsilon, True) 
        if (len(point) == 4 and epsilon>100 and epsilon<600 ):#and (int(point[0][0][0:1])>700) and (int(point[0][0][1:2])>1000)这里找身份证特征,因为背景简单直接判断边框周长就行
	        for i in range(len(point)-1):
		    #cv2.line(img, tuple(point[i][0]), tuple(point[i+1][0]), (0,255,0), 8)
		        pp[i]=tuple(point[i][0])
		        if(i==(len(point)-2)):
			        pp[i+1]=tuple(point[i+1][0])
		    
            
			
#扩展边界
    extends=150
    ppx1=pp[0][0]+extends
    ppy1=pp[0][1]+extends
    temp=(ppx1,ppy1)
    pp[0]=temp

    ppx2=pp[1][0]-extends
    ppy2=pp[1][1]+extends
    temp=(ppx2,ppy2)
    pp[1]=temp

    ppx3=pp[2][0]-extends
    ppy3=pp[2][1]-extends
    temp=(ppx3,ppy3)
    pp[2]=temp

    ppx4=pp[3][0]+extends
    ppy4=pp[3][1]-extends
    temp=(ppx4,ppy4)
    pp[3]=temp
    #cv2.rectangle(img, pp[0], pp[2], (0,255,0),10)#框出身份证
    imga=img[ppy4:ppy1,ppx3:ppx4]
    return imga

过程不难,当作复习一遍opencv吧。注释写的比较多的,可以学习一下。

https://github.com/liuzehao/Stitching-ID-Card

下面是一些常用的方法,记录一下省得下次再写了

#读取当前文件下的所有图片
path='./'
def get_img_file(file_name):
    imagelist = []
    for parent, dirnames, filenames in os.walk(trainpath):
        for filename in filenames:
            if filename.lower().endswith(('.bmp', '.dib', '.png', '.jpg', '.jpeg', '.pbm', '.pgm', '.ppm', '.tif', '.tiff')):
                imagelist.append(os.path.join(parent, filename))
        return imagelist
   
#创建图像
I=numpy.zeros((3501,2500),dtype=numpy.uint8)
I[:]=255
I=cv2.cvtColor(I,cv2.COLOR_GRAY2BGR)
for z in range(len(arr)):
    img = cv2.imread(arr[z])
    y, x = img.shape[0:2]
    imga=find(img)
    ya, xa = imga.shape[0:2]
#粘贴
    if (z==0):
        I[225:(225+ya),665:(665+xa)]=imga
    else:
	    I[(675+ya):(675+ya*2),665:(665+xa)]=imga
    #IX, IY = I.shape[0:2]
#保存图像
cv2.imwrite("./ok.jpg", I)

 

你可能感兴趣的:(无聊制作)