在Python中如何使用OpenCV实现人脸检测?详细实现指南

2021年11月11日18:13:15 发表评论 1,040 次浏览

在 Python 中使用 Haar Cascades 和 Single Shot MultiBox Detector 方法和 OpenCV 的 dnn 模块执行人脸检测。

Python OpenCV实现人脸检测:对象检测是一种与计算机视觉和图像处理相关的计算机技术,用于检测数字图像和视频中某类语义对象(如人脸、汽车、水果等)的实例。

Python如何OpenCV实现人脸检测?在本教程中,我们将构建一个简单的 Python 脚本来处理图像中的人脸检测,我们将使用OpenCV 库中的 两种方法 。首先,我们将使用haar 级联分类器,这是一种简单的方法(也不是那么准确),对初学者来说也是最方便的方法。

之后,我们将深入研究使用Single Shot Multibox Detectors(或简称 SSD),这是一种使用单个深度神经网络检测图像中对象的方法。

注意:值得一提的是,需要区分物体检测和物体分类,物体检测是检测物体及其在图像中的位置,而物体分类是识别物体属于哪个类。如果你对图像分类感兴趣,请前往本教程。

使用 Haar Cascades 进行人脸检测

Python如何OpenCV实现人脸检测Haar 基于特征的级联分类器是一种基于机器学习的方法,其中级联函数是从大量正面和负面图像中训练出来的。然后使用它来检测其他图像中的对象。

基于 haar 特征的级联分类器的好处是你可以为你想要的任何对象创建一个分类器,OpenCV 已经为你提供了一些分类器参数,所以你不必收集任何数据来训练它。

Python人脸检测示例 - 首先,安装要求:

pip3 install opencv-python numpy

好的,创建一个新的 Python 文件并继续,让我们首先导入OpenCV

import cv2

Python OpenCV实现人脸检测:你需要一个样本图片来测试,确保它有清晰的正面,我将使用这张包含两个可爱孩子的库存图片

# loading the test image
image = cv2.imread("kids.jpg")

该函数imread()从指定文件加载图像并将其作为 numpy N 维数组返回。

在我们检测图像中的人脸之前,我们首先需要将图像转换为灰度,这是因为我们将用于检测人脸的函数需要灰度图像:

# converting to grayscale
image_gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)

该函数cvtColor()的输入图像从一个颜色空间到另一个转换,我们指定cv2.COLOR_BGR2GRAY代码装置,该装置从BGR转换(略 ģ颖 ř ED)为灰度。

由于本教程是关于检测人脸的,请继续下载此列表中用于人脸检测的 haar 级联 。更准确地说,是 "haarcascade_frontalface_default.xml" 。让我们把它放在一个名为“cascades”的文件夹中,然后加载它:

# initialize the face recognizer (default face haar cascade)
face_cascade = cv2.CascadeClassifier("cascades/haarcascade_fontalface_default.xml")

复制现在让我们检测图像中的所有人脸:

# detect all the faces in the image
faces = face_cascade.detectMultiScale(image_gray)
# print the number of faces detected
print(f"{len(faces)} faces detected in the image.")

detectMultiScale() 函数将图像作为参数并将不同大小的对象检测为矩形列表,让我们在图像中绘制这些矩形:

# for every face, draw a blue rectangle
for x, y, width, height in faces:
    cv2.rectangle(image, (x, y), (x + width, y + height), color=(255, 0, 0), thickness=2)

最后,让我们保存新图像:

# save the image with rectangles
cv2.imwrite("kids_detected.jpg", image)

这是我的结果图像:在Python中如何使用OpenCV实现人脸检测?详细实现指南

很酷,对吧?随意使用其他对象分类器、其他图像,甚至更有趣的是,使用你的网络摄像头!这是Python人脸检测示例代码:

import cv2

# create a new cam object
cap = cv2.VideoCapture(0)
# initialize the face recognizer (default face haar cascade)
face_cascade = cv2.CascadeClassifier("cascades/haarcascade_fontalface_default.xml")

while True:
    # read the image from the cam
    _, image = cap.read()
    # converting to grayscale
    image_gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
    # detect all the faces in the image
    faces = face_cascade.detectMultiScale(image_gray, 1.3, 5)
    # for every face, draw a blue rectangle
    for x, y, width, height in faces:
        cv2.rectangle(image, (x, y), (x + width, y + height), color=(255, 0, 0), thickness=2)
    cv2.imshow("image", image)
    if cv2.waitKey(1) == ord("q"):
        break

cap.release()
cv2.destroyAllWindows()

一旦你执行了它(当然如果你有网络摄像头),它会打开你的网络摄像头并开始在图像的所有正面周围绘制蓝​​色矩形。代码并不那么具有挑战性,我所做的只是改变了,而不是从文件中读取图像,我创建了一个VideoCapture对象,该对象每次在while循环中都从中读取,一旦按下q按钮,主循环将结束.

使用 SSD 进行人脸检测

Python如何OpenCV实现人脸检测?如你所见,以前的方法并没有那么具有挑战性。不幸的是,它已经过时了,今天在现实世界中很少使用。然而,神经网络总是能派上用场,幸运的是,OpenCV 为我们提供了令人惊叹的包dnn内模块cv2,可以对预训练的深度学习模型进行推理。

Python OpenCV实现人脸检测:要开始使用预测面临固态硬盘在OpenCV中,你需要下载RESNET人脸检测模型架构连同其预训练的权重,然后将其保存到权重文件夹中当前的工作目录:

import cv2
import numpy as np

# https://raw.githubusercontent.com/opencv/opencv/master/samples/dnn/face_detector/deploy.prototxt
prototxt_path = "weights/deploy.prototxt.txt"
# https://raw.githubusercontent.com/opencv/opencv_3rdparty/dnn_samples_face_detector_20180205_fp16/res10_300x300_ssd_iter_140000_fp16.caffemodel 
model_path = "weights/res10_300x300_ssd_iter_140000_fp16.caffemodel"

现在要加载实际模型,我们需要使用readNetFromCaffe()将模型架构和权重作为参数的方法:

# load Caffe model
model = cv2.dnn.readNetFromCaffe(prototxt_path, model_path)

我们将使用上面使用的相同图像:

# read the desired image
image = cv2.imread("kids.jpg")
# get width and height of the image
h, w = image.shape[:2]

现在要将这个图像传递到神经网络中,我们需要准备它。更具体地说,我们需要将图像调整为 的形状(300, 300)并执行平均减法,因为它是这样训练的:

# preprocess the image: resize and performs mean subtraction
blob = cv2.dnn.blobFromImage(image, 1.0, (300, 300), (104.0, 177.0, 123.0))

让我们使用这个blob对象作为网络的输入并执行前馈以获得检测到的人脸:

# set the image into the input of the neural network
model.setInput(blob)
# perform inference and get the result
output = np.squeeze(model.forward())

Python人脸检测示例:现在输出对象具有所有检测到的对象(在本例中为人脸),让我们迭代这个数组并在图像中绘制所有置信度超过50% 的人脸:

font_scale = 1.0
for i in range(0, output.shape[0]):
    # get the confidence
    confidence = output[i, 2]
    # if confidence is above 50%, then draw the surrounding box
    if confidence > 0.5:
        # get the surrounding box cordinates and upscale them to original image
        box = output[i, 3:7] * np.array([w, h, w, h])
        # convert to integers
        start_x, start_y, end_x, end_y = box.astype(np.int)
        # draw the rectangle surrounding the face
        cv2.rectangle(image, (start_x, start_y), (end_x, end_y), color=(255, 0, 0), thickness=2)
        # draw text as well
        cv2.putText(image, f"{confidence*100:.2f}%", (start_x, start_y-5), cv2.FONT_HERSHEY_SIMPLEX, font_scale, (255, 0, 0), 2)

在我们提取检测对象模型的置信度后,我们得到周围的框并将其乘以原始图像的widthheight以获得正确的框坐标,因为你还记得,我们之前已将图像调整为(300, 300),所以输出也应该在0到300之间。

Python如何OpenCV实现人脸检测?在本例中,我们不仅绘制了周围的框,而且还编写了一些文本以百分比形式表示置信度,让我们显示并保存新图像:

# show the image
cv2.imshow("image", image)
cv2.waitKey(0)
# save the image with rectangles
cv2.imwrite("kids_detected_dnn.jpg", image)

这是生成的图像:

在Python中如何使用OpenCV实现人脸检测?详细实现指南
Python OpenCV实现人脸检测示例

太棒了,这种方法更好更准确,但如果你实时预测人脸,它的 FPS 可能会更低,因为它不如 haar 级联方法快。

顺便说一句,如果你想使用相机实时使用此方法检测人脸,你可以查看完整的代码页。

Python OpenCV实现人脸检测有许多实际应用,例如,我们还使用人脸检测使用 OpenCV 实时模糊图像和视频中的人脸!

好的,本教程就到这里,所有教程资料(包括测试图像、haar级联参数、SSD模型权重和完整代码)都可以在这里获取

木子山

发表评论

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: