其他分享
首页 > 其他分享> > 基于Dlib的身份证复印件 正反面裁剪

基于Dlib的身份证复印件 正反面裁剪

作者:互联网

业务需求:把一些历史的身份证复印件资料,按照正反面截取,并重新命名为 xxxx_FROT.jpg & xxxx_BACK.jpg 存放进一个文件夹中

实现思路:通过人脸识别,找到身份证正面和反面,并进行裁剪

遇到的问题:1 识别出了一个"人脸框",但却不是人脸 2 如何知道是从人脸的上方还是下方进行裁剪(即身份证正面在A4纸的上面还是下面)

对于问题1,我做了一些测试,发现框了一个但框错的情况都是框小了(且非常小),所以取了个身份证框面积大小的经验值,作为是否框对的判断条件;

对于问题2,则基于计算出的身份证框,做两次裁剪:一次在框的上方,一次在框的下方,还是用面积做判断,如果 area(上) <= area(下),则说明脸在上,否则脸在下

PS: 关于人脸检测,可ref我的另外一篇文章:https://www.cnblogs.com/caesar-the-great/p/12750772.html

具体的数据类似于下面这样:

eg1:

eg2:

 

 

 实现代码:

 1 #coding=utf-8
 2 #图片检测 - Dlib版本
 3 import cv2
 4 import dlib
 5 import glob
 6 
 7 # 不同情况下的图片存放路径
 8 dealedimg = "img/dealedimg/" # 检测到一个人脸,并框正确
 9 unhandledimg = "img/unhandledimg/" # 检测不到人脸
10 errorhandledimg = "img/errorhandledimg/" # 检测错误
11 multiFaceimg = "img/multiFaceimg/" # 多张人脸
12 originalimg = "img/originalimg/"
13 
14 
15 #人脸分类器
16 detector = dlib.get_frontal_face_detector()
17 # 获取人脸检测器
18 predictor = dlib.shape_predictor(
19     "D:\\software\\anaconda3\\Lib\\site-packages\\dlib\\shape_predictor_68_face_landmarks.dat"
20 )
21 count = 0
22 count1 = 0
23 # 身份证上的常规人脸大小(基于测试数据的经验值)
24 commonFaceArea = 10000
25 # 循环遍历originalimg路径下的所有图片
26 for index, filename in enumerate(glob.glob(originalimg + '*.jpg')):
27     img = cv2.imread(filename)  # 读取图片
28     gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)  # 转换灰色
29     # 预测出的脸的集合,第二个参数代表图片的放大倍数
30     dets = detector(gray, 2)
31     faceCounts = len(dets)
32     imgName = filename.split("\\")[1]
33     # 检测到多个人脸
34     if faceCounts > 1:
35         print("------------检测到多个人脸------------")
36         cv2.imwrite(multiFaceimg + imgName, img)
37         continue
38     # 检测不到人脸
39     if faceCounts == 0:
40         count = count + 1
41         print("未检测到人脸。。。。。count = " + count.__str__())
42         cv2.imwrite(unhandledimg + imgName, img)
43         continue
44     # 检测到一个人脸
45     if faceCounts:
46         # 在图片中标注人脸,并显示
47         left = dets[0].left()
48         top = dets[0].top()
49         right = dets[0].right()
50         bottom = dets[0].bottom()
51         # 人脸框的面积
52         faceArea = (bottom - top) * (right - left)
53         # 人脸框小于经验值,则证明框错
54         if faceArea < commonFaceArea:
55             print("------------框到的矩形不是人脸------------")
56             cv2.imwrite(errorhandledimg + imgName, img)
57             continue
58         # 框到了一个正确的人脸,则裁剪
59         # 提取身份证正面
60         y0 = int(top - 1.5*(bottom - top))
61         y1 = int(bottom + 1.5*(bottom - top))
62         x0 = 0
63         # shape[0] 高度
64         orgHeight, orgWidth, channel = img.shape
65         x1 = orgWidth
66         # 裁剪正面,坐标为[y0:y1, x0:x1]
67         cropped = img[y0:y1, x0:x1]
68         imgNameFront = imgName.split(".")[0] + "_FRONT." + imgName.split(".")[1]
69         cv2.imwrite(dealedimg + imgNameFront, cropped)
70         # 基于计算出的身份证框,做两次裁剪:一次在框的上方,一次在框的下方
71         # 如果 area(上) <= area(下),则说明脸在上,否则脸在下
72         areaUp = y0 * (right - left)
73         areaDown = (orgHeight - y1) * (right - left)
74         if areaUp <= areaDown:
75             croppedBack = img[y1:orgHeight, x0:x1]
76         else:
77             croppedBack = img[0:y0, x0:x1]
78         imgNameBack = imgName.split(".")[0] + "_BACK." + imgName.split(".")[1]
79         cv2.imwrite(dealedimg + imgNameBack, croppedBack)
View Code

 

标签:imgName,img,裁剪,cv2,正反面,人脸,身份证,Dlib
来源: https://www.cnblogs.com/caesar-the-great/p/12786314.html