Chinaunix首页 | 论坛 | 博客
  • 博客访问: 3657145
  • 博文数量: 365
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 2522
  • 用 户 组: 普通用户
  • 注册时间: 2019-10-28 13:40
文章分类

全部博文(365)

文章存档

2023年(8)

2022年(130)

2021年(155)

2020年(50)

2019年(22)

我的朋友

分类: Python/Ruby

2022-05-05 17:33:30

import os

import cv2

import sys

import time

import numpy as np

import face_recognition

from PyQt5.QtGui import QPixmap

from PyQt5.QtWidgets import QApplication,QLabel

# 全局变量

path = './data'  # 人像存储路径

showflag = True  # 是否实时显示图像

# 利用PyQt5打开全屏窗口,实现窗口替换效果

def lock_screen(image_path='lock.jpg'):

    app = QApplication(sys.argv)

    pixmap = QPixmap(image_path)

    screen = QLabel()

    screen.setPixmap(pixmap)

    screen.showFullScreen()

    sys.exit(app.exec_())

# 读取本地肖像库,建立识别白名单

def load_portrait(path=path):

    '''

    path:肖像库路径

    '''

    # 消息提示

    print('>>>本地图像库读取中,请稍后',end='')

    for i in range(5):

        print('.', end='')

        time.sleep(0.3)

    # 建立白名单

    white_map = {}

    for name in os.listdir(path):

        filepath = '%s/%s'%(path, name)

        avg_coding = np.zeros(128)

        n = 0

        for file in os.listdir(filepath):

            if '.jpg' in file:

                image = face_recognition.load_image_file('%s/%s'%(filepath, file))

                encoding = face_recognition.face_encodings(image)[0]

                avg_coding += encoding

                n += 1

        avg_coding /= n

        white_map[name] = avg_coding

        print('>>"%s"人脸数据加载完成!'%name)

    return white_map

# 人脸识别,判断当前画面的人像是否与白名单中的匹配

def recognize(frame, white_map):

    '''

    frame: 捕获的摄像头帧

    white_map: 人像库白名单

    '''

    # 根据白名单,提取肖像编码

    known_face_encodings = list(white_map.values())

    known_face_names = list(white_map.keys())

    # 图像预处理(包括大小调整、格式转换)

    frame = cv2.resize(frame, (0, 0), fx=0.25, fy=0.25) # 调整图像大小,以减小计算需求

    frame =外汇跟单gendan5.com frame[:, :, ::-1] # BGR->RGB

    # 计算人脸的编码值

    face_locations = face_recognition.face_locations(frame)

    face_encodings = face_recognition.face_encodings(frame, face_locations)

    # 计算的编码与白名单比较,获得其匹配的名字

    face_names = []

    for face_encoding in face_encodings:

        # 默认为"未知"

        name = '未知'

        # 匹配

        matches = face_recognition.compare_faces(known_face_encodings, face_encoding)

        if True in matches:

            index = matches.index(True)

            name = known_face_names[index]

        face_names.append(name)

    return face_names, face_locations

if __name__ == '__main__':

    # 加载白名单

    white_map = load_portrait(path)

    #开启摄像头

    video_capture = cv2.VideoCapture(0, cv2.CAP_DSHOW)

    # 采集图像

    flag = 0

    while True:

        flag %= 3

        _, frame = video_capture.read()

        if flag == 0: # 3帧处理因此(提高处理速度,防止视频卡顿)

            face_names, face_locations = recognize(frame, white_map)

            if '未知' in face_names: # 如果有白名单之外的人

                lock_screen()

                break

        flag += 1

        if showflag:

            # 将人脸框出

            for (top, right, bottom, left), name in zip(face_locations, face_names):

                # 改变坐标位置(因为处理时原图被缩小了4*4

                top *= 4

                right *= 4

                bottom *= 4

                left *= 4

                # 矩形框

                cv2.rectangle(frame, (left, top), (right, bottom), (0, 0, 255), 2)

                #加上姓名

                cv2.rectangle(frame, (left, bottom - 35), (right, bottom), (0, 0, 255), cv2.FILLED)

                font = cv2.FONT_HERSHEY_DUPLEX

                cv2.putText(frame, name, (left + 6, bottom - 6), font, 1.0, (255, 255, 255), 1)

            # 显示图像

            cv2.imshow('monitor', frame)

        # Q退出

        if cv2.waitKey(1) & 0xFF == ord('q'):

            break

    video_capture.release()

    cv2.destroyAllWindows()

阅读(515) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~