实验环境
操作系统: Windows 11
IDE: Visual Studio 2022
Python: 3.9.7
实验步骤
一、配置环境
Visul Studio非常不适合像我这样的小白使用,用起来真痛苦。尤其是最新的2022版本,出了bug都很难找到中文的解决方法。唉,学英语真的好重要,尤其是对计算机专业的学生来说。
Visual Studio创建Python项目的话,首先要安装Python支持,就是下图这个:
安装好之后,点击[文件]--[新建]--[项目],就可以找到Python项目了。这里我们准备创建一个Python应用程序模板(我们只需要在本地跑一跑人脸识别的代码,不需要太复杂的模板)。
项目创建成功之后,我们要从右边的“解决方案管理器”菜单栏中右键点击“Python环境”选项,然后点击[查看所有Python环境]。
点击[概述]--[包(PyPI)]就可以搜索安装Python包了。
到这里,我们就可以开始今天的实验了。
(还要注意一点,要在高级保存选项中设置保存的编码为UTF-8,要不然会报错)
二、基于OpenCV的人脸检测
这里要用到opencv-python包。
opencv-python包在安装的时候会自动安装一些已经训练好的分类器,OpenCV完成人脸识别靠的就是分类器。所以,我们要去找到这些分类器的位置,它们保存在python安装路径下的"/Lib/sitepackages/cv2/data/"这个目录。
找到之后,我们就可以开始写人脸识别的代码了(这里用的是师姐的代码):
import cv2
def detect(filename):
# 加载检测人脸的分类器
face_cascade = cv2.CascadeClassifier('C:\Program Files (x86)\Microsoft Visual Studio\Shared\Python39_64\Lib\site-packages\cv2\data\haarcascade_frontalface_default.xml')
# 加载我们准备识别的图像
img = cv2.imread(filename)
# 把图像转化成灰度图
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# 开始进行人脸识别,并将识别到的人脸的位置和大小保存在faces中
faces = face_cascade.detectMultiScale(gray, 1.3, 5)
# 用faces里面的数据,去绘制包住识别出的人脸的矩形框
for (x, y, w, h) in faces:
img = cv2.rectangle(img, (x, y), (x + w, y + h), (255, 0, 0), 2)
# 展示人脸识别结果
cv2.imshow('Person Detected!', img)
# 按任意键结束程序
cv2.waitKey(0)
cv2.destroyAllWindows()
detect("2.jpg")
要注意的是,图片尺寸不能太大,否则识别时间会很长,跟死机了一样。
识别结果如下:
可以看到,SNH48 Team NII的大部分成员的脸都被识别出来了。
三、基于Dlib+face_recognition的人脸检测
我们可以发现,上一节的例子中还有很多人脸没有被识别出来,这表明,OpenCV默认分类器的人脸识别能力还不是很强。
通过师姐的介绍,我了解到了另一种人脸识别方法,那就是face_recognition(以下简称fr)。
fr在安装之前,还需要先安装cmake和dlib依赖,dlib非常难安装,普通的pip install没法在线安装它,只能从官网找到dlib的whl文件,然后利用pip install来离线安装。
三个都安装好以后,就可以开始写人脸识别的代码了(这里还是用的是师姐的代码):
import face_recognition
import cv2
# 加载我们准备识别的图像
image = face_recognition.load_image_file("2.jpg")
# 开始进行默认模式的人脸识别,并将识别到的人脸的位置保存在face_locations_noCNN中
face_locations_noCNN = face_recognition.face_locations(image)
# 计算一下识别到的人脸数量
face_num2 = len(face_locations_noCNN)
# 再读取一下需要进行人脸识别的图像,准备绘制识别结果
org = cv2.imread("2.jpg")
for i in range(0,face_num2):
# 从face_locations_noCNN里面去读取默认模式下识别到的人脸的位置信息
top = face_locations_noCNN[i][0]
right = face_locations_noCNN[i][1]
bottom = face_locations_noCNN[i][2]
left = face_locations_noCNN[i][3]
# 绘制包住识别出的人脸的矩形框
start = (left, top)
end = (right, bottom)
color = (0,255,255)
thickness = 2
cv2.rectangle(org, start, end, color, thickness)
# 展示人脸识别结果
cv2.imshow("no cnn ",org)
# 按任意键结束程序
cv2.waitKey(0)
cv2.destroyAllWindows()
这次的识别结果如下。可以看到,除了被灯挡住的刘闲和刘姝贤之外,其他成员的脸全部被识别出来了。
四、基于Dlib的人脸对齐
人脸对齐好像就是识别人脸部的一些特征点,算是人脸识别的进化版本。
人脸识别只是检测出人脸,这一节是直接识别出来人脸的各个部位。
这里利用上一节中安装的dlib包来实现,代码如下(这里还是用的是师姐的代码):
import cv2
import dlib
# 加载我们准备识别的图像
path = "3.jpg"
img = cv2.imread(path)
# 把图像转化成灰度图
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# 获得脸部位置检测器
detector = dlib.get_frontal_face_detector()
# 初步⼈脸检测,并将识别到的人脸的位置保存在dets中
dets = detector(gray, 1)
# 加载特征点提取器
predictor =dlib.shape_predictor("C:\Program Files (x86)\Microsoft Visual Studio\Shared\Python39_64\Lib\site-packages\shape_predictor_68_face_landmarks.dat")
for face in dets:
# 用特征点提取器去检测人脸的特征点
shape = predictor(img, face)
for pt in shape.parts():
# 读取每个特征点的坐标
pt_pos = (pt.x, pt.y)
# 绘制特征点
cv2.circle(img, pt_pos, 2, (0, 255, 0), 1)
# 展示人脸特征点检测结果
cv2.imshow("image", img)
# 按任意键结束程序
cv2.waitKey(0)
cv2.destroyAllWindows()
识别结果如下。可以看到,张怀瑾脸上的68个特征点全部被识别出来了。
总结
这次实验中,我学着调用了OpenCV和face_recognition的基础算法进行了简单的人脸识别和人脸特征点检测。感觉机器学习和图像处理是真的很神奇很有意思,不过我对这个领域没什么兴趣,就稍微了解一下吧。