实验环境
操作系统: Windows 11
IDE: Visual Studio
Python: 3.9.7
实验步骤
一、配置环境
Visul Studio非常不适合像我这样的小白使用,用起来真痛苦。尤其是最新的版本,出了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 cv2def 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_recognitionimport 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 = 2cv2.rectangle(org, start, end, color, thickness)# 展示人脸识别结果cv2.imshow("no cnn ",org)# 按任意键结束程序cv2.waitKey(0)cv2.destroyAllWindows()
这次的识别结果如下。可以看到,除了被灯挡住的刘闲和刘姝贤之外,其他成员的脸全部被识别出来了。
四、基于Dlib的人脸对齐
人脸对齐好像就是识别人脸部的一些特征点,算是人脸识别的进化版本。
人脸识别只是检测出人脸,这一节是直接识别出来人脸的各个部位。
这里利用上一节中安装的dlib包来实现,代码如下(这里还是用的是师姐的代码):
import cv2import 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的基础算法进行了简单的人脸识别和人脸特征点检测。感觉机器学习和图像处理是真的很神奇很有意思,不过我对这个领域没什么兴趣,就稍微了解一下吧。