身份证头像截取

今天练习一下身份证头像的截取功能,,做个备忘

环境:

操作系统:  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)

 

posted on 2019-07-22 15:03  孔扎根  阅读(1516)  评论(0编辑  收藏  举报

导航