20230612_python练习_pyqt5截屏后opencv人脸识别根据相似度图片归类

	这个练习开始是想弄截屏录像同步进行人脸识别分类保存,结果电脑原因每次处理需要2秒左右,时间较长,录像效果不好实现,for i in range(1*fps) 只能用来控制识别次数了。
	而且图片保存后比对再删除重创建是浪费资源与时间,而且反复创建删除应该也会影响硬盘寿命,等之后调整为同步识别,最后保存。
# opencv练习面部识别,通过截屏保存图像的方式保存使用。

from PIL import ImageGrab,Image
import uuid,socket,time,os
import win32gui
from PyQt5.QtWidgets import QApplication
import sys
import cv2
import numpy as np

#获取电脑设备信息方便以后分布使用
def get_mac():
    #mac
    mac = uuid.UUID(int=uuid.getnode()).hex[-12:]
    # 获取主机名
    hostname = socket.gethostname()
    # 获取IP
    ip = socket.gethostbyname(hostname)
    # 屏幕分辨率为
    screen = ImageGrab.grab()
    width, height = screen.size
    # 结果数据字典
    pc_mac = {'mac':mac,'hostname':hostname,'ip':ip,'width':width,'height':height}
    # 结果数据导出
    return pc_mac

# 时间计算
def get_current_time():
    ct = time.time()
    local_time = time.localtime(ct)
    data_head = time.strftime("%Y%m%d%H%M%S", local_time)
    data_secs = abs(ct - round(ct)) * 1000
    time_stamp = "%s%03d" % (data_head, data_secs)
    return time_stamp

#屏幕截图
def get_hwnd_title():
    hwnd_title = dict()
    def get_all_hwnd(hwnd,mouse):
        if win32gui.IsWindow(hwnd) and win32gui.IsWindowEnabled(hwnd) and win32gui.IsWindowVisible(hwnd):
            hwnd_title.update({hwnd: win32gui.GetWindowText(hwnd)})
    win32gui.EnumWindows(get_all_hwnd,0)
    # 程序会打印窗口的hwnd和title,有了title就可以进行截图了。
    hwnd = win32gui.FindWindow(None, 'C:\Windows\system32\cmd.exe')
    app = QApplication(sys.argv)
    screen = QApplication.primaryScreen()
    img_qt = screen.grabWindow(hwnd).toImage()
    #pyqt5转PIL
    img_size = img_qt.size()
    img_s = img_qt.bits().asstring(img_size.width() * img_size.height() * img_qt.depth() // 8)
    img_arr = np.frombuffer(img_s, dtype=np.uint8).reshape((img_size.height(), img_size.width(), img_qt.depth() // 8))
    new_image = Image.fromarray(img_arr)
    # PIL转换opencv
    img_cv = cv2.cvtColor(np.asarray(new_image), cv2.COLOR_RGB2BGR)
    return img_cv

#人脸模型加载
def get_face_eye():
    # 人脸
    faceCascade = cv2.CascadeClassifier("C:/Users/HONOR/anaconda3/envs/pytorch/Library/etc/haarcascades/haarcascade_frontalface_default.xml")
    # 眼睛
    faceCascade_eye = cv2.CascadeClassifier("C:/Users/HONOR/anaconda3/envs/pytorch/Library/etc/haarcascades/haarcascade_eye.xml")
    return faceCascade,faceCascade_eye

#人脸识别与眼睛识别
def Face_comparison(img,faceCascade,faceCascade_eye):
    faces_list = []
    eye_list = []
    #转黑白图片
    gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    #人脸识别
    faces = faceCascade.detectMultiScale(gray,1.05)
    #看数量
    #print('faces',len(faces))
    for (x, y, w, h) in faces:
        #print('xywh', (x, y, w, h))
        if w >= 30:  # 图像宽超过50才保存,因为太小的误判可能性更大
            cropped = gray[y:y + w, x:x + h]
            # 加入眼睛识别,如果存在眼睛在保存
            eye = faceCascade_eye.detectMultiScale(cropped, 1.05)
            if len(eye) >= 1:
                for (eye_x, eye_y, eye_w, eye_h) in eye:
                    if eye_w >= 1:
                        eye_list.append([eye_x + x, eye_y + y, eye_w, eye_h])
                # print('eye_list', len(eye_list))
                # print(eye_list)
                faces_list.append([x, y, w, h])
    return faces_list,eye_list

#人脸素材库加载
def face_catalogue(catalogue):
    #面部目录加载,每次读取图片加载一次太浪费效率
    #cv2.face.LBPHFaceRecognizer_create() 需要 pip install opencv-contrib-python
    photos = list()
    lables = list()
    file_name = {}
    # 遍历上层目录
    for root, dirs, files in os.walk(catalogue):
        # 查看存在多少个子目录
        if files == []:
            #print('root', root, 'dirs', dirs, 'files', files)
            for dir in dirs:
                #print('dir',dir)
                for root_son, dirs_son, files_son in os.walk(catalogue + "/%s" % dir):
                    #print('dir', dir, 'files', files_son)
                    dir_id = dir[0:7]
                    dir_name = dir[8:]
                    #print('dir_id', dir_id, 'dir_name', dir_name)
                    #增加字典
                    file_name[dir_id]=dir_name
                    #附件计数
                    file_num = 0
                    for file_son in files_son:
                        #print('file', catalogue + "/%s/%s" % (dir, file_son))
                        # img = cv2.imread(catalogue + "/%s/%s" % (dir, file_son), 0)
                        img = cv2.imdecode(np.fromfile(catalogue + "/%s/%s" % (dir, file_son), dtype=np.uint8), 0)
                        imga = cv2.resize(img, (200, 200))
                        photos.append(imga)
                        lables.append(int(dir_id))
                        file_num += 1
                    #print('序列号',dir,'素材数量:',file_num)
    #print('文件数',set(lables),file_name)
    model = cv2.face.LBPHFaceRecognizer_create()
    model.train(photos, np.array(lables))
    return model,file_name


def model_confidence(image,image_path):
    print(os.getcwd())
    #获取文件名路径
    dir_path = os.path.dirname(image_path)
    #提取文件名
    bas_path = os.path.basename(image_path)

    print('image_path',dir_path,bas_path)
    # 人脸模型加载
    model, file_name = face_catalogue('./image/face_catalogue')
    print('file_name',file_name)
    nex_label = str(int(max(file_name.keys()))+1)
    print(max(file_name.keys()),type(max(file_name.keys())),nex_label)
    # 图片像素扩充与素材一致
    cropped = cv2.resize(image, (200, 200))
    # 相似度比对
    label, confidence = model.predict(cropped)
    print('相似度比对', label,file_name[str(label)], str(round(confidence,2)).replace('.','_'))
    if confidence <= 50:
        # 在相似文件夹内存放图片
        print('相似度比对较高,可以做同一认定')
        path_new = dir_path+'/face_catalogue/'+str(label)+'_'+file_name[str(label)]+'/'+bas_path
        print('转移新路径',path_new)
        cv2.imwrite(path_new,image)
        os.remove(image_path)
        pass
    else:
        # 新创建一个文件夹存放该图片
        print('相似度比对较低,无法做同一认定')
        path_new = dir_path + '/face_catalogue/' + nex_label+'_'+'wumingshi' + '/' + bas_path
        print('转移新路径', path_new)
        if os.path.exists(dir_path+'/face_catalogue/'+nex_label+'_'+'wumingshi'+'/'):
            print('路径已存在',dir_path+'/face_catalogue/'+nex_label+'_'+'wumingshi'+'/')
        else:
            os.mkdir(dir_path+'/face_catalogue/'+nex_label+'_'+'wumingshi'+'/')
            cv2.imwrite(path_new, image)
            os.remove(image_path)
        pass
    print('文件处理完成!')


#图片人脸标准化存档,大小改为200*200,灰色,时间+第几个
def Face_image_save(image,faces,in_time):
    image_dict = {}
    i = 0
    for (x, y, w, h) in faces:
        i += 1
        cropped_gray = cv2.resize(cv2.cvtColor(image[y:y + w, x:x + h], cv2.COLOR_BGR2GRAY),(200,200))
        image_name = './image/'+in_time+'_'+str(i)+'.jpg'
        #print('image_name',image_name)
        cv2.imwrite(image_name,cropped_gray)
        image_dict[image_name]=cropped_gray
    return image_dict

if __name__ == '__main__':
    # 获取系统数据
    mac_id= get_mac()
    # 展现数据
    print('计算机参数展示', mac_id)
    # 获取内容
    mac, hostname, ip = mac_id['mac'],mac_id['hostname'],mac_id['ip']
    width,height = mac_id['width'],mac_id['height']
    #人脸模型与眼睛模型
    faceCascade,faceCascade_eye = get_face_eye()
    #录屏准备
    fourcc = cv2.VideoWriter_fourcc('X','V','I','D')
    in_time = get_current_time()
    fps = 1
    # 视频存档
    # file_name = './image/avi'+in_time+'.avi'
    # output = cv2.VideoWriter( file_name ,fourcc,fps,(width,height))

    #录屏循环,意义不大
    for i in range(1*fps):
        #图片时间同步
        in_time = get_current_time()
        #获取屏幕截图
        image = get_hwnd_title()
        #人脸位置与眼睛位置获取
        faces_list,eye_list = Face_comparison(image,faceCascade,faceCascade_eye)
        print('人脸列表',faces_list)
        # 视频存档:视频增加帧数
        # output.write(image)
        #图片加工存档
        image_dict = Face_image_save(image,faces_list,in_time)
        print('image_dict',len(image_dict),image_dict.keys())
        for image_path in image_dict.keys():
            cropped = image_dict[image_path]
            model_confidence(cropped,image_path)

        js_time = get_current_time()
        print('js_time1',in_time, js_time)
        time.sleep(0.1)

    print('1111')





你可能感兴趣的:(python,qt,opencv)