计算机视觉|【人脸检测】基于OpenCV和Face_Recognition实现人脸检测

【计算机视觉|【人脸检测】基于OpenCV和Face_Recognition实现人脸检测】目录
一、人脸区域检测
(一)基于OpenCV
(二) 基于Dlib+Face_Recognition
二、人脸特征点检测
一、人脸区域检测 (一)基于OpenCV
首先,我们需要安装OpenCV。徽标键(win)+R键打开运行窗口,输入cmd打开命令提示符,键入如下命令来安装。第一种方法速度可能比较慢,推荐使用第二种清华开源的方法。

pip install opencv-python // 或者 pip install -i https://pypi.tuna.tsinghua.edu.cn/simple opencv-python

安装好之后可以在Python中导入,并查看版本号。我这里显示安装的是4.5.5版本。
计算机视觉|【人脸检测】基于OpenCV和Face_Recognition实现人脸检测
文章图片

接着,我们需要找到安装好的分类器的位置。首先通过键入 where python 来查看自己的Python路径。可以看到我这里不仅有原装的Python,还有Anaconda下的Python。
计算机视觉|【人脸检测】基于OpenCV和Face_Recognition实现人脸检测
文章图片

然后我们在如下路径中找到haarcascade_frontalface_default.xml分类器。
'Python路径下/Lib/site-packages/cv2/data/haarcascade_frontalface_default.xml'
通过查找可以发现,我的分类器放在了"D:/Anaconda/Lib/site-packages/cv2/data/haarcascade_frontalface_default.xml"之中,如下图所示。
计算机视觉|【人脸检测】基于OpenCV和Face_Recognition实现人脸检测
文章图片

我们可以通过Python、Pycharm、Jupyter等多种编辑器写代码,在这里我选择了Jupyter。在Jupyter中键入以下代码:
import cv2def detect(filename): ## 创建一个级联分类器,加载一个 .xml文件 # 这里路径替换成自己的'Python路径下/Lib/site-packages/cv2/data/haarcascade_frontalface_default.xml' face_cascade = cv2.CascadeClassifier('D:/Anaconda/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) # scaleFactor表示人脸检测过程中每次迭代时图片的压缩率(1.3) # minNeighbors:每个人脸矩形保留近邻数目的最小值(5) # 在原图上绘制矩形 # 遍历faces矩形框向量组里每一组矩形(即每一张脸) for (x, y, w, h) in faces: # 通过坐标绘制矩形,x,y是左上?坐标;w,h分别是宽度和高度 # 参数:图片,?方形框左上?坐标, ?方形框右下?坐标,字体颜色,字体粗细) img = cv2.rectangle(img, (x, y), (x + w, y + h), (255, 0, 0), 2) # 其中参数的含义:(255, 0, 0)表示颜色, 2表示线条粗细 cv2.imshow('Person Detected!', img) cv2.waitKey(0) cv2.destroyAllWindows()if __name__ == '__main__': detect('test.jpg') # 将图片与代码放在同一路径下

我们以这张图为例,测试一下代码。
计算机视觉|【人脸检测】基于OpenCV和Face_Recognition实现人脸检测
文章图片

效果如下:

我们会发现虽然识别出了人脸,但它并没有精确地把所有人脸都识别出来。这是因为图片中人物过多、人脸角度不同、尺寸不同等都可能影响到识别的精度。
此外,我们还可以使用"Python路径下/Lib/site-packages/cv2/data/"中的其他分类器。如果把haarcascade_frontalface_default.xml替换为haarcascade_eye.xml,会有什么效果呢?大家自己试试看!

(二) 基于Dlib+Face_Recognition
Face_Recognition是一种准确度更高的人脸识别方法。首先,我们先安装所需要的包。除了上面安装好的Python、OpenCV外,我们还需要安装cmake、dlib和face_recognition,同样是在cmd中运行。
pip install cmake pip install dlib pip install face_recognition

如果dlib安装失败,可参考以下这篇文章。
Windows系统下通过本地whl或tar.gz文件安装dlib方法 - 知乎一、 为什么需要本地安装?因为直接采用pip install dlib指令在线安装dlib会反复出现编译不通过的情况,而本地安装不会面临这样的问题,所以在此介绍通过下载whl或tar.gz文件在本地安装dlib的方法。 二、 安装环境…计算机视觉|【人脸检测】基于OpenCV和Face_Recognition实现人脸检测
文章图片
https://zhuanlan.zhihu.com/p/464846060接下来,我们在Jupyter中键入以下代码:
import face_recognition import cv2 # 加载图像文件(.jpg,.png等),返回的数据是Numpy数组,记录了图片的所有像素的特征向量 image = face_recognition.load_image_file("test.jpg") # 定位图中所有的人脸的像素位置,返回值为列表形式,列表中每一行是一张人脸的位置信息,包括【top, right, bottom, left】这是一组元组。 face_locations_noCNN=face_recognition.face_locations(image) # face_locations_useCNN =face_recognition.face_locations(image,model='cnn') # A list of tuples of found face locations in css (top, right, bottom,left) order # 因为返回值的顺序是这样子的,因此在后面的for循环里面赋值要注意按这个顺序来print("face_location_noCNN:") print(face_locations_noCNN) face_num2=len(face_locations_noCNN) print(face_num2)# The number of faces # 到这里为止,可以观察两种情况的坐标和人脸数,一般来说,坐标会不一样,但是检测出来的人脸数应该是一样的 # 也就是说face_num1=face_num2;face_locations_useCNN和face_locations_noCNN不一样org = cv2.imread("test.jpg") img = cv2.imread("test.jpg") cv2.imshow("test.jpg",img)# 原始图片for i in range(0,face_num2): 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()

运行一下看看会有什么效果!输出结果如下:
face_location_noCNN: [(94, 328, 137, 285), (98, 477, 142, 434), (108, 204, 151, 160), (177, 543, 239, 481), (90, 625, 141, 573), (188, 394, 239, 343), (205, 152, 257, 101), (184, 688, 246, 626), (188, 256, 239, 204)] 9

(这里的9代表识别出9张人脸)
效果图:

和OpenCV比,Face_Recognition识别人脸的准确度明显提高!


二、人脸特征点检测 Dlib有专门的函数和模型,能够实现人脸68个特征点的定位。支持更加精确的标定点。标定点分为68点和5点,可以圈出面部眼鼻嘴的位置。
首先需要下载预训练模型shape_predictor_68_face_landmarks.dat和shape_predictor_5_face_landmarks.dat,并将这两个包放在python路径下的site-packages里(记得解压喔!)
链接:https://pan.baidu.com/s/1Pl8m2pNm84JZsCawrCFjsA?pwd=4px3
提取码:4px3
接下来,我们在Jupyter中键入以下代码:
import cv2 import dlibpath = "test.jpg" # 读取图片 img = cv2.imread(path) # 灰度化处理 gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)# 获得脸部位置检测器 detector = dlib.get_frontal_face_detector() # 初步人脸检测,框出矩形。返回值是,即一个矩形,表示为能够唯一表示这个人脸矩形框两个点坐标:左上?(x1,y1)、右下?(x2,y2) dets = detector(gray, 1) # 使用模型构建特征提取器,返回5/68个特征点的位置 # 此处路径是自己的python路径下site-packages位置 predictor =dlib.shape_predictor(r"D:/Anaconda/Lib/site-packages/shape_predictor_68_face_landmarks.dat") for face in dets: shape = predictor(img, face) # 寻找人脸的68个标定点 # 遍历所有点,打印出其坐标,并圈出来 # shape.parts() 类型为_dlib_pybind11.points,可返回检测到的关键点的位置坐标 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()

效果如下:

如果我们使用shape_predictor_5_face_landmarks.dat,效果如下所示:

    推荐阅读