身份证头像截取
今天练习一下身份证头像的截取功能,,做个备忘
环境:
操作系统: windows
python: 3.5.3, opencv, dlib
1、用法
python source_pic.jpg dest_pic.jpg
提供一个源图片名 生成的目标文件名
#!/usr/bin/env python3 # -*- coding:utf-8 -*- # __author__:kzg ''' cv2.imshow("image", img_blank) # 显示图片 cv2.waitKey(0) # 窗口一直开着 ''' import cv2 import dlib import numpy as np import os, sys if len(sys.argv) == 3: in_pic = sys.argv[1] out_pic = sys.argv[2] else: in_pic = input("Input Pic Path:") out_pic = input("Output Pic Path:") # 初始化正脸检测器 dector = dlib.get_frontal_face_detector() # 利用opencv读取图片 if os.path.exists(in_pic): img = cv2.imread(in_pic) else: exit("pic not exists") # 检测图上的人脸数 try: dets = dector(img, 1) except Exception as ex: # 脸部无法检测 exit(ex) # 身份证上只能有一个人脸,即为检查结果的第一个值 if dets: face = dets[0] # [(354, 96) (444, 186)] 检测出左上、右下两个点 else: exit("face detor is null") # 计算想裁取的图片的高度 下-上 height = face.bottom()-face.top() + 60 # 计算想裁取的图片的宽度 右-左 width = face.right()-face.left() + 40 # 以计算出的图片大小生成空白板 img_blank = np.zeros((height, width, 3), np.uint8) # 将图片写入空白板 for i in range(height): for j in range(width): # top线上方40像素位置开始读, left线左15像素位置开始读 img_blank[i][j] = img[face.top() - 40 + i][face.left() - 15 + j] try: cv2.imwrite(out_pic, img_blank) # 保存写入数据后的空白板图片 except Exception as ex: exit(ex) cv2.destroyAllWindows() # 释放所有窗口资源
2、身份证图片截取过程中发现, 在45度范围内的身份证可以正确识别头像,所以对于不标准的头像需要将图片旋转。
#!/usr/bin/env python3 # -*- coding:utf-8 -*- # __author__:kzg ''' cv2.imshow("image", img_blank) # 显示图片 cv2.waitKey(0) # 窗口一直开着 ''' import cv2 import dlib import numpy as np import os, sys def tranposeDector(img, cnt=0): ''' :param infile: imread后的图片对象 ''' # 检测图上的人脸数 try: dets = dector(img, 1) except Exception as ex: # 脸部无法检测 exit(ex) # 身份证上只能有一个人脸,即为检查结果的第一个值 if dets: face = dets[0] # [(354, 96) (444, 186)] 检测出左上、右下两个点 # 计算想裁取的图片的高度 下-上 height = face.bottom() - face.top() + 60 # 计算想裁取的图片的宽度 右-左 width = face.right() - face.left() + 40 # 以计算出的图片大小生成空白板 img_blank = np.zeros((height, width, 3), np.uint8) # 将图片写入空白板 for i in range(height): for j in range(width): # top线上方40像素位置开始读, left线左15像素位置开始读 img_blank[i][j] = img[face.top() - 40 + i][face.left() - 15 + j] try: cv2.imwrite(out_pic, img_blank) # 保存写入数据后的空白板图片 except Exception as ex: exit(ex) cv2.destroyAllWindows() # 释放所有窗口资源 else: cnt += 1 if cnt > 3: print(">3") print("transpose times:", cnt) transposeImage = cv2.transpose(img) # 图像反向旋转90度 flipedImageX = cv2.flip(transposeImage, 0) # 沿X轴方向的镜像图片 cv2.imshow("flipedImageX",flipedImageX) cv2.waitKey(1000) tranposeDector(flipedImageX, cnt) if __name__ == '__main__': if len(sys.argv) == 3: in_pic = sys.argv[1] out_pic = sys.argv[2] else: in_pic = input("Input Pic Path:") out_pic = input("Output Pic Path:") # 初始化正脸检测器 dector = dlib.get_frontal_face_detector() # 利用opencv读取图片 if os.path.exists(in_pic): img = cv2.imread(in_pic) else: exit("pic not exists") tranposeDector(img)
3、目录pic_folder下存储需要截取头像的身份证图片,目录extra_folder存储截取好的头像图片。 每5秒获取一次pic_folder内的图片, 自动将裁剪后的头像保存在extra_folder目录下。
#!/usr/bin/env python3 # -*- coding:utf-8 -*- # __author__:kzg ''' cv2.imshow("image", img_blank) # 显示图片 cv2.waitKey(0) # 窗口一直开着 ''' import cv2 import dlib import numpy as np import os, sys, time from random import randint # 图片源 sourceDir = "c:\\lionbridge\\scripts\\bigdata\\pic_folder" # 保存使用过的文件 dataset = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'dataset') # 处理图片保存目录 outPic = "c:\\lionbridge\\scripts\\bigdata\\extra_folder" def tranposeDector(img, cnt=0): ''' :param infile: imread后的图片对象 ''' # 检测图上的人脸数 try: dets = dector(img, 1) except Exception as ex: # 脸部无法检测 exit(ex) # 身份证上只能有一个人脸,即为检查结果的第一个值 if dets: face = dets[0] # [(354, 96) (444, 186)] 检测出左上、右下两个点 # 计算想裁取的图片的高度 下-上 height = face.bottom() - face.top() + 60 # 计算想裁取的图片的宽度 右-左 width = face.right() - face.left() + 40 # 以计算出的图片大小生成空白板 img_blank = np.zeros((height, width, 3), np.uint8) # 将图片写入空白板 for i in range(height): for j in range(width): # top线上方40像素位置开始读, left线左15像素位置开始读 img_blank[i][j] = img[face.top() - 40 + i][face.left() - 15 + j] try: cv2.imwrite(os.path.join(outPic, str(randint(0,10000))+".jpg"), img_blank) # 保存写入数据后的空白板图片 except Exception as ex: exit(ex) cv2.destroyAllWindows() # 释放所有窗口资源 else: cnt += 1 if cnt > 3: print(">3") print("transpose times:", cnt) transposeImage = cv2.transpose(img) # 图像反向旋转90度 flipedImageX = cv2.flip(transposeImage, 0) # 沿X轴方向的镜像图片 # cv2.imshow("flipedImageX",flipedImageX) # cv2.waitKey(1000) tranposeDector(flipedImageX, cnt) if __name__ == '__main__': # 初始化正脸检测器 dector = dlib.get_frontal_face_detector() while True: # 图片目录下所有文件集 sSet = set(os.listdir(sourceDir)) # 数据集中所有文件名 if os.path.exists(dataset): with open(dataset, 'r') as fp: dSet = set() for i in fp.readlines(): dSet.add(i.replace("\n", "")) else: with open(dataset, 'w') as fp: fp.write("") fp.close() dSet = set() sSet.difference_update(dSet) for p in sSet: print("start:", p) # 利用opencv读取图片 img = cv2.imread(os.path.join(sourceDir, p)) tranposeDector(img) # 转换过的图片保存到dataset with open(dataset, 'a') as fp: fp.write(p + "\n") time.sleep(5)
4、修改完善版, 没有把未成功切图的目录另外保存
#!/usr/bin/env python3 # -*- coding:utf-8 -*- # __author__:kzg ''' cv2.imshow("image", img_blank) # 显示图片 cv2.waitKey(0) # 窗口一直开着 ''' import cv2 import dlib import numpy as np import os, sys, time from random import randint BASEDIR = os.path.dirname(os.path.abspath(__file__)) # 图片源 sourceDir = os.path.join(BASEDIR, "pic_folder") # 保存使用过的文件 dataset = os.path.join(BASEDIR, 'dataset') # 处理图片保存目录 outPic = os.path.join(BASEDIR, "extra_folder") def tranposeDector(img, cnt=0): ''' :param infile: imread后的图片对象 ''' # 检测图上的人脸数 try: dets = dector(img, 1) except Exception as ex: # 脸部无法检测 return (ex) # 身份证上只能有一个人脸,即为检查结果的第一个值 if dets: face = dets[0] # [(354, 96) (444, 186)] 检测出左上、右下两个点 # 计算想裁取的图片的高度 下-上 height = face.bottom() - face.top() + 60 # 计算想裁取的图片的宽度 右-左 width = face.right() - face.left() + 40 # 以计算出的图片大小生成空白板 img_blank = np.zeros((height, width, 3), np.uint8) # 将图片写入空白板 try: for i in range(height): for j in range(width): # top线上方40像素位置开始读, left线左15像素位置开始读 img_blank[i][j] = img[face.top() - 40 + i][face.left() - 15 + j] cv2.imwrite(os.path.join(outPic, str(randint(0,10000))+".jpg"), img_blank) # 保存写入数据后的空白板图片 except Exception as ex: print(ex) cv2.destroyAllWindows() # 释放所有窗口资源 else: cnt += 1 if cnt < 3: transposeImage = cv2.transpose(img) # 图像反向旋转90度 flipedImageX = cv2.flip(transposeImage, 0) # 沿X轴方向的镜像图片 cv2.imshow("flipedImageX",flipedImageX) cv2.waitKey(1000) tranposeDector(flipedImageX, cnt) else: print("人脸检测失败 transpose times:", cnt) cv2.destroyAllWindows() # 释放所有窗口资源 if __name__ == '__main__': # 初始化正脸检测器 dector = dlib.get_frontal_face_detector() while True: # 图片目录下所有文件集(增加文件后缀判断) sSet = set(os.listdir(sourceDir)) # 数据集中所有文件名 if os.path.exists(dataset): with open(dataset, 'r') as fp: dSet = set() for i in fp.readlines(): dSet.add(i.replace("\n", "")) else: with open(dataset, 'w') as fp: fp.write("") fp.close() dSet = set() sSet.difference_update(dSet) for p in sSet: print("start:", p) # 利用opencv读取图片 img = cv2.imread(os.path.join(sourceDir, p)) tranposeDector(img) # 转换过的图片保存到dataset with open(dataset, 'a') as fp: fp.write(p + "\n") time.sleep(5)