Pyhton,OpenCV对象检测之——Haar级联人脸及眼睛检测

Posted 程序媛一枚~

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Pyhton,OpenCV对象检测之——Haar级联人脸及眼睛检测相关的知识,希望对你有一定的参考价值。

这篇博客将介绍如何使用预训练的模型——基于Haar特征的级联检测器进行人脸及眼睛检测。

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

1. 效果图

单人面部及眼睛检测效果图如下:

多人面部及眼睛检测效果图如下:

2. 原理

2.1 Haar人脸检测原理

使用人脸检测。最初该算法需要大量的正面图像(人脸图像)和负面图像(没有人脸的图像)来训练分类器。然后从中提取特征。对于每个特征,它会找到将人脸分类为正面和负面的最佳阈值。但很明显会有错误或错误分类。

每一次选择错误率最小的特征,这意味着它们是对人脸和非人脸图像进行最佳分类的特征。

人脸即便是 24*24 的图像,也有近160000个特征,Haar级联分类器将特征降到了6000个。并且引入了分类级联器的概念。不是在一个窗口上应用所有 6000 个特征,而是将特征分组到分类器的不同阶段并逐一应用。 (通常前几个阶段将包含非常少的功能)。如果窗口在第一阶段失败,则丢弃它。如果通过,则应用第二阶段的功能并继续该过程。通过所有阶段的窗口是面部区域。

Haar 检测器有 6000 多个特征,分为 38 个阶段,前五个阶段有 1、10、25、25 和 50 个特征。 平均而言,每个子窗口会评估 6000 多个特征中的 10 个特征。

2.2 Haar级联预训练的模型

OpenCV库维护一个预先训练好的Haar级联库。包括:

  • haarcascade_frontalface_default.xml:检测面部
  • haarcascade_eye.xml:检测左眼和右眼
  • haarcascade_smile.xml:检测面部是否存在嘴部
  • haarcascade_eye_tree_eyeglasses.xml:检测是否带墨镜🕶
  • haarcascade_frontalcatface.xml:检测猫脸
  • haarcascade_frontalcatface_extended.xml:检测猫脸延伸
  • haarcascade_frontalface_alt.xml:检测猫脸属性
  • haarcascade_frontalface_alt_tree.xml
  • haarcascade_frontalface_alt2.xml
  • haarcascade_fullbody.xml:检测全身
  • haarcascade_lefteye_2splits.xml:检测左眼
  • haarcascade_licence_plate_rus_16stages.xml:检测证件
  • haarcascade_lowerbody.xml:检测下半身
  • haarcascade_profileface.xml
  • haarcascade_righteye_2splits.xml:检测右眼
  • haarcascade_russian_plate_number.xml:检测俄罗斯字母车牌号
  • haarcascade_upperbody.xml:检测上半身

3. 源码

3.1 图像面部及眼睛检测

# Haar级联检测器对脸、眼睛👀进行检测

import cv2

# 加载预训练的脸、眼睛检测XML模型
face_cascade = cv2.CascadeClassifier('haarcascades/haarcascade_frontalface_default.xml')
eye_cascade = cv2.CascadeClassifier('haarcascades/haarcascade_eye.xml')

# 加载图像或者视频帧(灰度图)
img = cv2.imread('images/rbyy.jpg')
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

# 检测脸
faces = face_cascade.detectMultiScale(gray, 1.3, 5)

# 遍历每一张脸,并绘制面部ROI为蓝色
for (x, y, w, h) in faces:
    cv2.rectangle(img, (x, y), (x + w, y + h), (255, 0, 0), 2)
    roi_gray = gray[y:y + h, x:x + w]
    roi_color = img[y:y + h, x:x + w]

    # 在面部进行眼睛的检测
    eyes = eye_cascade.detectMultiScale(roi_gray)
    # 绘制眼睛ROI为绿色
    for (ex, ey, ew, eh) in eyes:
        cv2.rectangle(roi_color, (ex, ey), (ex + ew, ey + eh), (0, 255, 0), 2)

cv2.imshow('img', img)
cv2.waitKey(0)
cv2.destroyAllWindows()

3.2 视频帧面部及眼睛检测

# 获取网络摄像头,并捕获帧,检测面部及眼睛👀,并且计算轮廓的中心及外接圆半径,在面部绘制紫色圆圈,在眼睛上绘制蓝色圆圈
import argparse

import cv2

# 检测面部并显示
def detectAndDisplay(frame):
    frame_gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
    frame_gray = cv2.equalizeHist(frame_gray)

    # 检测面部
    faces = face_cascade.detectMultiScale(frame_gray)
    for (x, y, w, h) in faces:
        center = (x + w // 2, y + h // 2)
        frame = cv2.ellipse(frame, center, (w // 2, h // 2), 0, 0, 360, (255, 0, 255), 4)

        faceROI = frame_gray[y:y + h, x:x + w]

        # 在每一张脸上,检测眼睛👀
        eyes = eyes_cascade.detectMultiScale(faceROI)
        for (x2, y2, w2, h2) in eyes:
            eye_center = (x + x2 + w2 // 2, y + y2 + h2 // 2)
            radius = int(round((w2 + h2) * 0.25))
            frame = cv2.circle(frame, eye_center, radius, (255, 0, 0), 4)

    cv2.imshow('Capture - Face detection', frame)


parser = argparse.ArgumentParser(description='Code for Cascade Classifier tutorial.')
parser.add_argument('--face_cascade', help='Path to face cascade.',
                    default='haarcascades/haarcascade_frontalface_alt.xml')
parser.add_argument('--eyes_cascade', help='Path to eyes cascade.',
                    default='haarcascades/haarcascade_eye_tree_eyeglasses.xml')
parser.add_argument('--camera', help='Camera divide number.', type=int, default=0)
args = parser.parse_args()

face_cascade_name = args.face_cascade
eyes_cascade_name = args.eyes_cascade

face_cascade = cv2.CascadeClassifier()
eyes_cascade = cv2.CascadeClassifier()

# 1. 加载级联检测器(面部及眼睛👀检测)
if not face_cascade.load(face_cascade_name):
    print('--(!)Error loading face cascade')
    exit(0)
if not eyes_cascade.load(eyes_cascade_name):
    print('--(!)Error loading eyes cascade')
    exit(0)

camera_device = args.camera

# 2.读取视频帧
cap = cv2.VideoCapture(camera_device)
if not cap.isOpened:
    print('--(!)Error opening video capture')
    exit(0)

while True:
    ret, frame = cap.read()
    if frame is None:
        print('--(!) No captured frame -- Break!')
        break

    detectAndDisplay(frame)

    # 按下ESC键,退出~
    if cv2.waitKey(10) == 27:
        break

参考

以上是关于Pyhton,OpenCV对象检测之——Haar级联人脸及眼睛检测的主要内容,如果未能解决你的问题,请参考以下文章

Haar-级联对象检测 OpenCV - .xml 文件分类器未正确检测

OpenCV-Python实战(番外篇)——基于 Haar 级联的猫脸检测器

OpenCV-Python实战(番外篇)——基于 Haar 级联的猫脸检测器

OpenCV中的Haar+Adaboost:AdaBoost之DAB与GAB

如何创建 Haar Cascade(.xml 文件)以在 OpenCV 中使用?

[opencv][转载]利用级联分类器车辆检测训练