【人脸检测】基于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版本。

        接着,我们需要找到安装好的分类器的位置。首先通过键入 where python 来查看自己的Python路径。可以看到我这里不仅有原装的Python,还有Anaconda下的Python。

【人脸检测】基于OpenCV和Face_Recognition实现人脸检测_第1张图片

        然后我们在如下路径中找到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实现人脸检测_第2张图片

         我们可以通过Python、Pycharm、Jupyter等多种编辑器写代码,在这里我选择了Jupyter。在Jupyter中键入以下代码:

import cv2

def 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实现人脸检测_第3张图片

        效果如下:

        我们会发现虽然识别出了人脸,但它并没有精确地把所有人脸都识别出来。这是因为图片中人物过多、人脸角度不同、尺寸不同等都可能影响到识别的精度

        此外,我们还可以使用"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的方法。 二、 安装环境…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 dlib

path = "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,效果如下所示:

你可能感兴趣的:(计算机视觉,opencv,python,人工智能)