这个练习开始是想弄截屏录像同步进行人脸识别分类保存,结果电脑原因每次处理需要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')