手工特征目标检测(1)级联目标检测器

在前面的博文主要是以模板匹配、颜色等像素级的目标特征为基础,描述如何进行目标检测。由于深度学习类算法的蓬勃发展,这些算法在实际应用中,除了在一些特殊的应用场景之外,已经很少见到了。但是,为了能够完整地讲叙目标检测的发展历程,还是稍费口舌进行叙述。从本篇开始,从像素级的目标检测,进入手工特征的目标检测阶段。
手工特征目标检测,是相对于基于机器学习的目标检测的概念。通俗地说,手工特征是指人为的设计一种方法或者算法,从像素级特征的基础上提取特征。例如:haar特征、LBP特征、HOG特征。反过来,如果是基于机器学习的目标特征,是指设计一种可训练或者可学习的模型,经过大量数据的训练,让模型自己可以从像素级特征得到更高层次的特征,更适用于目标检测任务。最典型的是,基于深度卷积网络的目标检测模型的backbone(特征提取模型)。

1 级联检测器

级联检测器是由多个分类器分级构成的,每一个分类器负责判断某个特征是否存在。当对某个区域进行检测时,如果某一级分类器负责的特征检测结果是存在,则会将该区域送入下一级分类器进行特征检测,逐级检测最终输出结果。如果某一级分类器负责的特征检测结果是不存在,则直接判定该区域不是待检测目标。用白话来说就是,类似于净水器的工作原理。一层有一层的过滤掉背景,剩下的就是目标了。每一层都是一个简单的分类器(弱分类器),联合很多的弱分类器,就可以形成一个强分类器。
在这里插入图片描述

2 VJ人脸检测器

科研工作者Paul Viola和Michael Jones设计了出了一个快速而准确的人脸检测器:在获得相同甚至更好准确度的同时,速度提升了几十上百倍——在当时的硬件条件下达到了每秒处理15张图像的速度,已经接近实时速度25fps(即25帧每秒)。这不仅是人脸检测技术发展的一个里程碑,也标志着计算机视觉领域的研究成果开始具备投入实际应用的能力。为了纪念这一工作,人们将这个人脸检测器用两位科研工作者的名字命名,称之为Viola-Jones人脸检测器,或者简称为VJ人脸检测器。

3 opencv的人脸检测器

opencv视觉算法库从1.0的版本就引进了Viola-Jones人脸检测器这套算法,并在历年的版本中当作默认的人脸检测器。下面,我们以python代码演示下,如何调用。

import cv2
import tkinter as tk
from tkinter import filedialog


def img_test():
    # 获取选择文件路径
    # 实例化
    root = tk.Tk()
    root.withdraw()
    # 获取文件或文件夹的绝对路径路径
    return filedialog.askopenfilename()


def haar_detection():
    face_path = 'haarcascades\\haarcascade_frontalface_default.xml'
    eye_path = 'haarcascades\\haarcascade_eye.xml'
    smile_path = 'haarcascades\\haarcascade_smile.xml'
    diction = {'face': face_path, 'eye': eye_path, 'smile': smile_path}
    for i in diction:
        diction[i] = cv2.CascadeClassifier(diction[i])
    return diction


def image_detection(img, detection):
    image_gray = cv2.cvtColor(img, cv2.COLOR_BGRA2GRAY)
    face_ret = detection['face'].detectMultiScale(image_gray, scaleFactor=1.02, minNeighbors=5, minSize=(15, 15),
                                                  maxSize=(50, 50), flags=cv2.CASCADE_DO_CANNY_PRUNING)
    if len(face_ret) != 0:
        for (x, y, w, h) in face_ret:
            face_roi = image_gray[y:y + h, x:x + w]
            eye_ret = detection['eye'].detectMultiScale(face_roi, scaleFactor=1.1, minNeighbors=3, minSize=(15, 15),
                                                        flags=cv2.CASCADE_SCALE_IMAGE)
            smile_ret = detection['smile'].detectMultiScale(face_roi, scaleFactor=1.1, minNeighbors=3, minSize=(15, 15),
                                                            flags=cv2.CASCADE_SCALE_IMAGE)
            for (xx, yy, ww, hh) in eye_ret:
                pt1 = (x + xx, y + yy)
                pt2 = (pt1[0]+ww, pt1[1]+hh)
                cv2.rectangle(img, pt1, pt2, (255, 0, 0), 2)
            for (xx, yy, ww, hh) in smile_ret:
                pt1 = (x + xx, y + yy)
                pt2 = (pt1[0]+ww, pt1[1]+hh)
                cv2.rectangle(img, pt1, pt2, (0, 255, 0), 2)
            cv2.rectangle(img, (x, y), (x+w, y+h), (0, 0, 255), 2)
        print('图像中有人脸')
    else:
        print('图像中无人脸')

    return img


if __name__ == '__main__':
    image = cv2.imread('image\\icon.jpg')
    cv2.namedWindow('Press q to exit and n to load the next picture', cv2.WINDOW_NORMAL)
    cv2.imshow('Press q to exit and n to load the next picture', image)
    while 1:
        k = cv2.waitKey()
        if k == ord('n'):
            image = cv2.imread(img_test())
            detector = haar_detection()
            image = image_detection(image, detector)
            cv2.imshow('Press q to exit and n to load the next picture', image)
        elif k == ord('q'):
            break
    cv2.destroyAllWindows()

在这里插入图片描述

opencv中内置了已经训练好的级联人脸、眼睛、嘴部等检测器,以.XML格式存储,可以将它们应用于图片及实时视频流的检测。
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:检测上半身
opencv的人脸检测级联检测器是最稳定和准确的,但在许多情况下眼睛检测和嘴巴检测的效果要差上许多。如果要对眼睛和嘴巴进行检测,可以尝试python、dlib、opencv工作流,它的效果更好、速度更快。
Haar级联算法是OpenCV最流行的目标检测算法,主要优点是速度快,尽管许多算法(如HOG+线性SVM、SSDs、更快的R-CNN、YOLO等等)比Haar级联算法更精确。但如果需要纯粹的速度,就是无法打败OpenCV的Haar cascades。Haar级联的缺点是容易出现假阳性检测,应用于推理/检测时需要进行参数调整。

4 结束语

在没有GPU的年代,这些经典的检测器是CV算法工程师必备的技能。时过境迁,除了在一些特定的应用场景下,大部分情况下,都会选择基于深度学习方向的解决方案。虽然解决方案已经过时,但是,其中的算法理念还是值得借鉴和学习的。

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

深图智能

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值