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