本文主要讲述如何使用比较少的代码实现人脸识别和对比功能。
环境搭建
本次试验环境是搭建在Ubuntu下的。装成了虚拟机,当然也可以直接装在物理机上,做成双系统或者直接使用Ubuntu作为日常使用系统。
安装虚拟机
当前主流的虚拟机软件有VirtualBox(免费软件)和VMWare(收费软件).
使用VirtualBox
下载VirtualBox
在如下地址下载一个VirtualBox。
VirtualBox下载地址
下载完成之后,安装,一直next就行。
下载ubuntu
在如下地址选择一个可用的桌面版就行
Ubuntu下载地址
安装虚拟光驱
VirtualBox不像VMWare那么强大,可以直接从ISO镜像文件安装,它必须借助虚拟光驱来安装。在其官网上下载一个,用个人免费证书即可。
新建虚拟机
打开VirtualBox,点击 “新建”,选择虚拟机的系统和输入名称,然后“下一步”。
选择虚拟机内存大小
默认的1G容易卡死,推荐4G。由于我机子只有8G,只给了3G。
新建虚拟硬盘
一直使用默认配置即可。虚拟机硬盘大小推荐在20G以上。
启动虚拟机
创建完虚拟机之后,在右边的虚拟机列表中就可以找到刚刚创建的虚拟机,点击启动,按照提示,一步步就可以了。
安装VMWare
VMWare是商用的,要收钱,虽然不地道,去网上找一个破解版或者试用30天。它不需要额外再安装一个虚拟光驱,可以直接从ISO镜像文件安装ubuntu。
虚拟机使用摄像头
VirtualBox使用宿主机摄像头
VirtualBox刚装完之后是无法识别宿主机的摄像头的,必须在如下地址下载一个扩展包安装。
VirtualBox扩展包下载地址
安装完成之后,点击“管理”-“全局设定”-“扩展”,查看是否成功安装完扩展包。
目前使用Visualbox调用宿主机还存在问题,改用VMWare。有知道的小伙伴欢迎留言告知。
VMWare使用宿主机摄像头
在虚拟机打开之后,选择“虚拟机”-“可移动设备”,找到对应的摄像头设备即可。
然后,右键或者快捷键Ctrl+T打开Ubuntu终端,输入cheese,打开摄像头应用,查看是否配置成功。
可能有些情况下,打开是黑屏的,那是USB的兼容方式不对。打开“虚拟机”-“设置”
找到USB控制器,其右侧有一个 USB兼容性。如果是2.0的就改为3.0,3.0的就改为2.0.这样就能正常显示画面了。
安装opencv
pip install opencv-python
安装face-recognition
pip install face_recognition
安装dlib
在安装face_recognition的过程中会出现报错,或者长时间卡在dlib相关的环节。此时就要单独安装dlib了。
去github或者dlib.net下载一个dlib的源码包,解压,进入到setup.py的相关目录
执行命令
Python setup.py install
它会编译dlib并且安装python的dlib扩展包。
成功后,下载face_recognition的源码包,从源码安装即可。
训练模型
准备一个目录,存放的是已知的人脸图片。
核心代码
读取图片
def get_all_img_files(path):
path_dir = os.listdir(path)
result = []
for allDir in path_dir:
child = os.path.join('%s/%s' % (path, allDir))
result.append(child)
return result
known_imgs = get_all_img_files("/home/kingwang/Workspace/Python/FaceDetect/src/known")
imgs = []
img_encodings = []
for image in known_imgs:
temp_image = face_recognition.load_image_file(image)
imgs.append(temp_image)
img_encodings.append(face_recognition.face_encodings(temp_image)[0])
读取摄像头
while True:
ret, frame = video_capture.read()
if frame is None:
print "None"
break
small_frame = cv2.resize(frame, (0, 0), fx=0.25, fy=0.25)
对比
if process_this_frame:
face_locations = face_recognition.face_locations(small_frame)
face_encodings = face_recognition.face_encodings(small_frame,face_locations)
face_names = []
name = "unknown"
for face_encoding in face_encodings:
for index in range(len(img_encodings)):
match =face_recognition.compare_faces([img_encodings[index]], face_encoding)
if match[0]:
name =known_imgs[index][-10:]
break
face_names.append(name)
对比结果
源码
# -*- coding: utf-8 -*-
import face_recognition
import cv2
import os
def get_all_img_files(path):
path_dir = os.listdir(path)
result = []
for allDir in path_dir:
child = os.path.join('%s/%s' % (path, allDir))
result.append(child)
return result
known_imgs =get_all_img_files("/home/kingwang/Workspace/Python/FaceDetect/src/known")
imgs = []
img_encodings = []
for image in known_imgs:
temp_image = face_recognition.load_image_file(image)
imgs.append(temp_image)
img_encodings.append(face_recognition.face_encodings(temp_image)[0])
face_locations = []
face_encodings = []
face_names = []
process_this_frame = True
video_capture = cv2.VideoCapture(0)
while True:
ret, frame = video_capture.read()
if frame is None:
print "None"
break
small_frame = cv2.resize(frame, (0, 0), fx=0.25, fy=0.25)
if process_this_frame:
face_locations = face_recognition.face_locations(small_frame)
face_encodings = face_recognition.face_encodings(small_frame,face_locations)
face_names = []
name = "unknown"
for face_encoding in face_encodings:
for index in range(len(img_encodings)):
match = face_recognition.compare_faces([img_encodings[index]],face_encoding)
if match[0]:
name =known_imgs[index][-10:]
break
face_names.append(name)
process_this_frame = not process_this_frame
for (top, right, bottom, left), name in zip(face_locations, face_names):
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),2)
font = cv2.FONT_HERSHEY_DUPLEX
cv2.putText(frame, name, (left + 6, bottom - 6), font, 1.0, (255, 255,255), 1)
cv2.imshow('Video', frame)
if cv2.waitKey(1) & 0xFF == ord('q'):
break
video_capture.release()
cv2.destroyAllWindows()
碰到的问题
Visulbox无法打开摄像头
Visualbox在关联摄像头的时候提示错误,无法绑定摄像头之类的。改用VMWare
Dlib安装超时或者报错
手动安装dlib
Opencv无法打开摄像头读取视频
Usb兼容性问题,见上文步骤。