分类: 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()