900字范文,内容丰富有趣,生活中的好帮手!
900字范文 > 使用opencv3.4.2剪切二代证扫描件到一张图片中

使用opencv3.4.2剪切二代证扫描件到一张图片中

时间:2018-10-25 21:07:49

相关推荐

使用opencv3.4.2剪切二代证扫描件到一张图片中

项目地址:/matrix273/scan2one

公司的惠普M126nw一体机,因为是黑白一体机,所以不能通过扫描-打印-再扫描的方式获取彩色扫描图片,虽然去网上可以找到相类似的工具,基本都是在线的,即需要上传自己的证件,这其实有信息泄漏的风险.另外类似的软件都有一个使用次数限制.比如一个月用10次.超过之后就需要缴费等限制.

故而我通过搜索,学习.码出了一个python脚本.实现了将2张证件扫描图片,合并到1张图片的功能.这样就不需要手动剪切复制编辑图片了(以前就是这么干的...).

先看最终效果图

可以看到自动对齐了正面,反面在一页A4纸上,且图片中基本无其他噪点(因为是在一个白纸上的基础上,将部分区域替换成了扫描到的证件)

环境如下:

OS:ubuntu 18.04

python:3.7.9

opencv:3.4.2

numpy:1.19.2

可以看到一体机扫描出来的图片如下图,一次只能扫描一面(我知道有证件扫描模式,但是最终只能得到黑白扫描件,故而不谈).

下图是扫描身份证正面的扫描结果,我特意没有把身份证与扫描边缘对齐,因为这个才是最常见的情况.像素大小: 1700*2338

可以看到扫描出的图片中有些许噪点.这个在处理时需要过滤掉.

下图是身份证背面的扫描结果.

直接上代码

import numpy as np #导入numpyimport cv2 #导入cv2库

主体部分

# 声明全白画布canvas = np.ones((2338, 1700, 3),np.uint8)*255y,x = canvas.shape[:2] #注意是y,x.不是x,y#定义函数处理图片,pic为扫描图片文件名def crop(pic): img = cv2.imread(pic) imgGray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) # 转换为gray灰度图imgBlur = cv2.GaussianBlur(imgGray,(5,5),1) #高斯模糊imgCanny = cv2.Canny(imgBlur,30,30) #边缘检测kernel = np.ones((5,5))imgDial = cv2.dilate(imgCanny,kernel,iterations=2) #膨胀处理,迭代2次imgThres = cv2.erode(imgDial,kernel,iterations=1) #腐蚀处理,迭代1次contours, hier = cv2.findContours(imgThres, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)[-2:] # 寻找轮廓for cidx,cnt in enumerate(contours): #遍历轮廓area = cv2.contourArea(cnt) #获取轮廓的面积if area>500: #面积大于500才处理minAreaRect = cv2.minAreaRect(cnt) #获取最小外接矩形((cx, cy), (w, h), theta) = minAreaRect #中心点坐标,长宽,旋转角度[-90,0),当矩形水平或竖直时均返回-90# 转换为整数点集坐标rectCnt = np.int64(cv2.boxPoints(minAreaRect)) width,height=int(w),int(h) #转换宽,高为整数类型src_pts = rectCnt.astype("float32") #转换数字类型# dst_pts 矩形顶点顺序分别为左下,左上,右上,右下if w > h:dst_pts = np.array([[0, height-1],[0, 0],[width-1, 0],[width-1, height-1]], dtype="float32")# the perspective transformation matrixM = cv2.getPerspectiveTransform(src_pts, dst_pts)# directly warp the rotated rectangle to get the straightened rectanglecroped = cv2.warpPerspective(img, M, (width, height))elif w < h:dst_pts = np.array([[height-1, width-1],[0, width -1],[0, 0],[height-1, 0]], dtype="float32")# the perspective transformation matrixM = cv2.getPerspectiveTransform(src_pts, dst_pts)# directly warp the rotated rectangle to get the straightened rectanglecroped = cv2.warpPerspective(img, M, (height,width)) return cropeddef warp(imread,bias=0): # 定义覆盖函数roiHeiht,roiWidth = imread.shape[:2] #roi的高,宽warpY,warpX=int((x - roiWidth)//2),int(0.1*y)+bias #crop图片插入的元点canvas[warpX:warpX + roiHeiht,warpY:warpY + roiWidth] = imread #直接替换制定区域为imread图片

然后是具体的操作部分

cropFront = crop('front.jpg') #获取front的cropcropBack = crop('back.jpg') #获取back的cropwarp(cropFront) #替换front_roiwarp(cropBack,bias=int(0.8*y-cropBack.shape[0])) #替换back_roicv2.imwrite('Final.jpg',canvas)

以上就是全部代码,用户只需要修改 上面的 front.jpg为正面扫描件,back.jpg为背面扫描件.Final.jpg为最后合成的文件名即可.后期看情况做个GUI版.预计包含opencv,numpy的打包文件可能比较大.

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。