php中文网 | cnphp.com

 找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 645|回复: 0

python用于检查照片是否符合人脸识别使用要求

[复制链接]

3138

主题

3148

帖子

1万

积分

管理员

Rank: 9Rank: 9Rank: 9

UID
1
威望
0
积分
7946
贡献
0
注册时间
2021-4-14
最后登录
2024-11-21
在线时间
763 小时
QQ
发表于 2022-5-22 10:09:03 | 显示全部楼层 |阅读模式
[mw_shl_code=python,true]# -*- coding: utf-8 -*-
import os
import ab as ab
import cv2
import openpyxl
from openpyxl import Workbook
from PIL import Image
import numpy as np

# 注意:haarcascade文件位置与opencv环境配置有关
face_cascade = cv2.CascadeClassifier('C:/Users/Administrator/AppData/Local/Programs/Python/Python39/Lib/site-packages/cv2/data/haarcascade_frontalface_default.xml')
# face_cascade = cv2.CascadeClassifier('./data/haarcascade_frontalface_default.xml')

"""图片人脸检测及返回相关信息
face_img:照片文件路径
返回值
resolution:分辨率;   dpi1:文件DPI信息;  n_photo:照片是否存在人脸;  blur:人脸模糊指数;"""
def ImgDetect(face_img):
    # imgDPI = cv2.imread(face_img)

    img = cv2.imdecode(np.fromfile(face_img, dtype=np.uint8), cv2.IMREAD_COLOR)  # 解决上面函数中文路径及中文文件名报错问题
    gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

    # 人脸检测
    faces = face_cascade.detectMultiScale(gray, 1.3, 9, minSize=(50, 50))
    faces_ratio = 0
    faces_size = 0

    if len(faces):                              # 判断照片是否存在人脸信息
        im = Image.open(face_img)
        n_photo="人物照片"

        # 此方法为文件头检查法检测文件是否为JPG文件,有时会出错
        # print(im.info)
        # if im.info=={}:                                                      #判断是否为JPG文件,一般PNG文件无info信息
        #    print("请转换成jpg文件")
        # else:
        #     if 'dpi' in im.info.keys():                                      #判断dpi信息的key是否存在
        #        print("DPI:", im.info['dpi'])                                 #打印dpi信息
        #     else:
        #         print("无DPI信息")

        if 'dpi' in im.info.keys():             # 判断dpi信息的key是否存在
            dpi1=im.info['dpi']
            # print("DPI:", im.info['dpi'])     # 打印dpi信息
        else:
            dpi1=()
            # print("无DPI信息")

        resolution=im.size                      # 分辨率值
        faces_ratio=format(round(faces[0][3]/resolution[1],4),'.2%')  # 人脸占比
        faces_size=faces[0][3]

        # 测试数据代码:
        print("人脸位置:", faces)
        print("分辨率:", im.size)  # 打印分辨率信息
        print("人脸图像占比:", faces_ratio)
        print("人脸分辨率:",faces_size)
        # print('模糊指数:', cv2.Laplacian(gray, cv2.CV_64F).var())  # 拉普拉斯方差算法获取拉普拉斯卷积值(越大越清晰)
        # print("原照片【宽:",img.shape[1],"照片高:",img.shape[0],"】\r\n")    # 获取图片分辨率信息(高,宽,bgr层)
        # print(img.dtype)

        photo_blur=Blur_photo(img,faces,gray)         # 获取模糊指数值
        blur=photo_blur[0]
        photo_t=photo_blur[1]

    else:
        n_photo="照片无人脸"
        resolution=()
        dpi1=()
        blur = cv2.Laplacian(gray, cv2.CV_64F).var()
        photo_t = "异常照片"

    return[n_photo, resolution, dpi1, faces_ratio, faces_size, blur,photo_t]


"""历遍文件夹文件"""
def getListFiles(path):
    ret = []
    for root, dirs, files in os.walk(path):
        for filespath in files:
            ret.append(os.path.join(root, filespath))
    return ret


""" 读取图片 """
def get_file_content(filePath):
    with open(filePath, 'rb') as fp:
        return fp.read()


"""JPG文件判断"""
def is_jpg(filename):
    try:
        i = Image.open(filename)
        return i.format == 'JPEG'
    except IOError:
        return False


"""差分法照片人脸清晰度检查模块
1、人脸检测框选需优化或跟换算法;
2、部分照片模糊指数错误成因需关注(低分辨率小尺寸照片模糊指数很高);"""
def Blur_photo(img,rect,gray):
    """
    img:原图片数据
    rect:人脸检测位置数据
    gray:图片转换灰度数据
    """

    # save_path = 'D:/程序测试素材/'

    box_data = gray[rect[0][1]rect[0][1] + rect[0][3]), (rect[0][0])rect[0][0] + rect[0][2])]  # 取矩形目标区域


    # 参数测试用代码:
    # print("传入参数有效性检测")
    # print("原图:", img)
    # print("灰度图:", gray)
    # print("人脸框:", rect)
    # print("计算参数:", box_data)
    # print("人脸图像占比:", rect[0][3] / img.shape[1])
    print("模糊指数:", cv2.Laplacian(box_data, cv2.CV_64F).var())       # 拉普拉斯方差算法获取拉普拉斯卷积值(越大越清晰)

    """加权调整模糊指数
    有误差,待解决
    """
    # print("加权模糊指数:", cv2.Laplacian(box_data, cv2.CV_64F).var() * img.shape[0]/500)
    # zhishu=cv2.Laplacian(box_data, cv2.CV_64F).var()/(cv2.Laplacian(box_data, cv2.CV_64F).var() * img.shape[0]/500)
    # if zhishu>2 or zhishu<0.5:
    #     print("异常照片")
    # else:
    #     print("正常照片")

    """找出存在低分辨率且高模糊指数的照片,判定照片是否需要人工检查"""
    if img.shape[0]<300 and cv2.Laplacian(box_data, cv2.CV_64F).var()>90:
        photo_T="照片异常"
    else:
        photo_T="照片正常"


    while True:
        img1 = cv2.rectangle(img, (rect[0][0], rect[0][1]), (rect[0][0] + rect[0][2], rect[0][1] + rect[0][3]),(255, 0, 0), 2)
        cv2.namedWindow('frame',cv2.WINDOW_NORMAL)
        cv2.resizeWindow('frame',600,800)
        cv2.namedWindow('cat', cv2.WINDOW_NORMAL)
        cv2.resizeWindow('cat', 600, 800)
        cv2.imshow('frame', img1)
        cv2.imshow('cat', box_data)
        if cv2.waitKey(1) & 0xFF == ord('q'):
            break

    # cap.release()
    cv2.destroyAllWindows()
    return cv2.Laplacian(box_data, cv2.CV_64F).var(),photo_T


"""创建信息检索输出表"""
def C_workbook(Photo_Path):
    f = Workbook()  # 创建工作表

    """表改名"""
    sh = f['Sheet']
    sh.title = "照片信息"

    """定义表头"""
    H_report = ["文件名", "文件路径", "人像", "分辨率", "宽", "高", "DPI", "水平", "垂直", "人脸占比","人脸px","模糊指数","照片状态"]

    # # tableTitle = ['userName', 'Phone', 'age', 'Remark']
    #
    # # 维护表头
    # #  if row < 1 or column < 1:
    # #   raise ValueError("Row or column values must be at least 1")
    # # 如上,openpyxl 的首行、首列 是 (1,1)而不是(0,0),如果坐标输入含有小于1的值,提示 :Row or column values must be at least 1,即最小值为1.

    """创建表头"""
    for col in range(len(H_report)):
        sh.cell(row=1, column=col + 1).value = H_report[col]

    # 格式化列

    sh.column_dimensions["A"].width = 20
    sh.column_dimensions["B"].width = 50
    sh.column_dimensions["C"].width = 10
    sh.column_dimensions["D"].width = 10
    sh.column_dimensions["E"].width = 8
    sh.column_dimensions["F"].width = 8
    sh.column_dimensions["G"].width = 10
    sh.column_dimensions["H"].width = 8
    sh.column_dimensions["I"].width = 8
    sh.column_dimensions["J"].width = 15
    sh.column_dimensions["K"].width = 10

    Sfile = Photo_Path + '/照片信息检索.xlsx'
    f.save(Sfile)
    f.close()
    return Sfile


if __name__ == '__main__':
    # 检索目录
    # "E:\工作\我的文档\工作\Project\正宇软件\黑龙江\大庆\人大\2018\照片"
    # "D:\程序测试素材"
    # "D:\程序测试素材\照片"

    Photo_Path=input()                  # 输入检索文件夹路径

    file_name=C_workbook(Photo_Path)    # 创建信息输出表,返回表文件路径

    ret = getListFiles(Photo_Path)      # 检索目录文件

    Ex_file = openpyxl.load_workbook(file_name)     # 加载Excel表
    sheet=Ex_file["照片信息"]                         # 激活工作表

    for each in ret:                        # each为检索目录返回值
        print("文件位置:",each)

        file_n=each.replace(Photo_Path,"").replace("\\","")     # 获取文件名
        print("文件名:", file_n)

        if is_jpg(each):                            # 判断是否为JPG照片
            ab=ImgDetect(each)                      # 比对照片,返回照片参数
            print(ab)
        else:                                       # 非JPG文件处理
            ab=['非JPG照片',(),(),"","",0,'异常照片']
            print("请转换为JPG文件!")

        # 整理数据
        photo_data=[file_n,each]
        for i in range(len(ab)):
            # 提取元组数据
            if isinstance(ab, tuple):                # 检测是否为元组
                if len(ab) == 0:                     # 检测是否为空
                    # print("数据为空")
                    for n in range(3):                  # 插入3个空值
                        # print(n)
                        photo_data.append("")
                else:                                   # 提取数据
                    xl = ""
                    for n in range(len(ab)):
                        if n<(len(ab)-1):
                            xl=xl+str(int(ab[n]))+"*"
                        else:
                            xl=xl+str(int(ab[n]))
                    photo_data.append(xl)
                    for n in range(len(ab)):
                        photo_data.append(int(ab[n]))
            else:
                photo_data.append(ab)
        print(photo_data)
        print()
        sheet.append(photo_data)                            # 追加一条数据进Excel文件
        Ex_file.save(Photo_Path + '/照片信息检索.xlsx')       # 保存Excel文件

    Ex_file.close()                                         # 关闭Excel文件

    # file_object=open(Photo_Path + '/照片信息检索.xlsx')
    files_object = os.system(Photo_Path + '/照片信息检索.xlsx')
[/mw_shl_code]

回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|php中文网 | cnphp.com ( 赣ICP备2021002321号-2 )

GMT+8, 2024-11-22 03:05 , Processed in 1.087477 second(s), 36 queries , Gzip On.

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2020, Tencent Cloud.

申明:本站所有资源皆搜集自网络,相关版权归版权持有人所有,如有侵权,请电邮(fiorkn@foxmail.com)告之,本站会尽快删除。

快速回复 返回顶部 返回列表