OpenCV56:级联分类器|Cascade Classifier
目标
在本教程中, 将学习
- Haar级联对象检测的工作原理
- 将使用基于Haar Feature的Cascade分类器了解人脸检测和眼睛检测的基础知识
- 将使用cv::CascadeClassifier类来检测视频流中的对象。具体地将使用以下函数:
- cv::CascadeClassifier::load来加载
.xml
分类器文件,它可以是Haar或LBP分类器 - cv::CascadeClassifier::detectMultiScale来执行检测
- cv::CascadeClassifier::load来加载
理论
使用基于Haar特征的级联分类器的对象检测是Paul Viola和Michael Jones于2001年在其论文“Rapid Object Detection using a Boosted Cascade of Simple Features”提出的一种有效的对象检测方法。这是一种基于机器学习的方法,其中从许多正负图像中训练级联函数。然后用于检测其他图像中的对象。
本文中将利用上述方法进行人脸检测。最初,该算法需要大量正图像(面部图像)和负图像(无面部图像)来训练分类器。 然后,需要从中提取特征。为此,使用下图所示的Haar特征, 它们就像卷积核一样,每个特征都是通过从黑色矩形中的像素总和中减去白色矩形中的像素总和而获得的单个值。
每个内核的所有可能大小和位置都能够计算得到许多特征。(试想一下它产生多少计算?即使是一个24x24
的窗口也会产生超过160000个特征)。对于每个特征计算,需要找到白色和黑色矩形下的像素总和。为了解决这个问题,引入了整体图像,无论图像有多大,它都会将给定像素的计算减少到仅涉及四个像素的操作,这使得计算变得更快。
但是在计算的所有这些特征中,大多数都不相关。例如,考虑下图。第一行显示了两个良好的特征。选择的第一个特征似乎着眼于眼睛区域,该区域通常比鼻子和脸颊区域更暗的属性。选择的第二个特征依赖于眼睛比鼻梁更黑的属性。但是,将相同的窗口应用于脸颊或其他任何地方都是无关紧要的。那么,如何从16万多个特征中选择最佳的特征呢,这是由Adaboost实现的。
Adaboost算法的基本原理:
先通过对N个训练样本的学习得到第一个弱分类器;
将分错的样本和其他的新数据一起构成一个新的N个的训练样本,通过对这个样本的学习得到第二个弱分类器;
将1和2都分错了的样本加上其他的新样本构成另一个新的N个的训练样本,通过对这个样本的学习得到第三个弱分类器;
最终经过提升的强分类器,即某个数据被分为哪一类要由各分类器权值决定;
为此,将所有特征应用于所有训练图像。对于每个特征,会找到最佳的阈值,该阈值会将人脸分为正面和负面。显然,会出现错误或分类错误。选择错误率最低的特征,这意味着它们是对人脸和非人脸图像进行最准确分类的特征 (此过程并非如此简单,参考adaboost算法。在开始时,每个图像的权重均相等。在每次分类后,错误分类的图像的权重都会增加。然后执行相同的过程将计算新的错误率,计算新的权重。继续进行此过程,直到达到所需的精度或错误率或找到所需的特征数量为止)。
最终分类器是这些弱分类器的加权和。之所以称为弱分类,是因为仅凭它自己并不能对图像进行正确分类,而是与其他分类一起形成强分类器。该论文说,甚至200个特征都可以提供95%的准确度检测,论文最终设置具有大约6000个特征。
因此,现在拍摄一张照片,取每个24x24
窗口,向其应用6000个特征, 检查图片中是否有脸。该方法是不是效率低下又费时?作者对此提出了一个更好的解决方案。
在图像中,大多数图像是非面部区域。因此,最好有一种简单的方法来检查窗口是否不是面部区域。如果该区域不是人脸区域,就不要再次对其进行处理。相反,应将重点放在可能有脸的区域,将花费更多时间检查可能的面部区域。类似于RPN网络,先获取到候选区域。
为此,引入了级联分类器(Cascade of Classifiers)的概念。不是将所有6000个特征应用到一个窗口中,而是将这些特征分组到不同的分类器阶段,并一一应用 (通常前几个阶段将包含很少的特征)。如果窗口在第一阶段失败,则将其丢弃,不考虑它的其余特征。如果通过,则应用特征的第二阶段并继续该过程,能够经过所有阶段的窗口那就证明是一个面部区域。
作者的检测器具有6000多个特征,具有38个阶段,在前五个阶段具有1、10、25、25和50个特
征(上图中的两个特征实际上是从Adaboost获得的最佳两个特征)。根据作者的说法,每个子窗口平均评估了6000多个特征中的10个特征。因此,这是Viola-Jones人脸检测工作原理的简单直观说明。
OpenCV中的Haar级联检测器
OpenCV提供了一种训练方法或预先训练的模型,可以使用cv::CascadeClassifier::load
方法读取预训练模型。预训练的模型位于OpenCV的data文件夹中,或在github找到。
以下代码示例将使用预训练的Haar级联模型来检测图像中的面部和眼睛。
- 首先,创建一个
cv::CascadeClassifier
并使用cv::CascadeClassifier::load
方法加载必要的XML文件。 - 然后,使用
cv::CascadeClassifier::detectMultiScale
方法完成检测,该方法返回检测到的脸部或眼睛的边界矩形
本教程的代码如下所示,也可以从这里下载:
from __future__ import print_function
import cv2
import numpy as np
import argparsedef detectAndDisplay(frame):frame_gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)frame_gray = cv2.equalizeHist(frame_gray) # 均衡灰度图像的直方图# detect facesfaces = 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]# In each face, detect eyeseyes = 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('--eye_cascade', help='Path to eye cascade', default='./harrcascades/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_cascadeface_cascade = cv2.CascadeClassifier()
eyes_cascade = cv2.CascadeClassifier()#-- 1. Load the cascades
if not face_cascade.load(cv2.samples.findFile(face_cascade_name)):print('--(!)Error loading face cascade')exit(0)
if not eyes_cascade.load(cv2.samples.findFile(eyes_cascade_name)):print('--(!)Error loading eyes cascade')exit(0)camera_device = args.camera
#-- 2. Read the video stream
cap = cvw.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!')breakdetectAndDisplay(frame)if cv.waitKey(10) == 27:break
结果
- 以下是运行上面的代码并使用作为输入内置网络摄像头的视频流的结果:
确保程序会找到文件
haarcascade_frontalface_alt.xml
和haarcascade_eye_tree_eyeglasses.xml
的路径,位于opencv/data/ haarcascades
中
- 以下是使用文件
lbpcascade_frontalface.xml
(经过LBP训练)进行人脸检测的结果。对于眼睛,继续使用本教程中使用的文件
附加资源
https://docs.opencv.org/4.5.5/db/d28/tutorial_cascade_classifier.html
adaboost算法
Paul Viola and Michael J. Jones. Robust real-time face detection. International Journal of Computer Vision, 57(2):137–154, 2004.
Rainer Lienhart and Jochen Maydt. An extended set of haar-like features for rapid object detection. In Image Processing. 2002. Proceedings. 2002 International Conference on, volume 1, pages I–900. IEEE, 2002.
Video Lecture on Face Detection and Tracking
An interesting interview regarding Face Detection by Adam Harvey
OpenCV Face Detection: Visualized on Vimeo by Adam Harvey
OpenCV56:级联分类器|Cascade Classifier相关推荐
- OpenCV级联分类器Cascade Classifier
OpenCV级联分类器Cascade Classifier 级联分类器Cascade Classifier 目标 理论 OpenCV中的Haar级联检测 结果 级联分类器Cascade Classif ...
- OpenCV中的级联分类器Cascade Classifier(面部识别)
OpenCV中的级联分类器Cascade Classifier Goal In this tutorial you will learn how to: Use the CascadeClassifi ...
- 【机器学习】传统目标检测算法之级联分类器Cascade
先附上参考文章吧. 文章其实是"P. Viola, M. Jones. Rapid Object Detection using a Boosted Cascade of Simple Fe ...
- Python+OpenCV:级联分类器(Cascade Classifier)
Python+OpenCV:级联分类器(Cascade Classifier) 目标 We will learn how the Haar cascade object detection works ...
- Haar特征和级联分类器目标检测介绍及应用
文章目录 Haar特征和级联分类器目标检测介绍及应用 1. Haar特征 2. 级联分类器 3. 实现步骤 4.尝试训练自己的级联分类器 4. 应用示例 Haar特征和级联分类器目标检测介绍及应用 H ...
- Python+OpenCV:训练级联分类器(Cascade Classifier Training)
Python+OpenCV:训练级联分类器(Cascade Classifier Training) Introduction Working with a boosted cascade of we ...
- [Opencv]Cascade级联分类器
文章目录 训练级联分类器 使用级联分类器检测 总结 前言 最近在尝试识别指定物体,之前用Opencv自带的级联分类器做过人脸识别感觉效果不错,所以想用级联分类器来做其它物体的识别. 选择学 ...
- cascade自己训练级联分类器(人脸检测)
cascade训练简介 后面有详细解释,和步骤代码的实现,可能需要简单修改,建议代码自己先写着试试 训练步骤 下载文件包opencv.这里的opencv是指编译好的.exe文件,不是需要编译的sour ...
- 【模型开源】Cascade级联分类器车辆检测(无误检)
[模型开源]Cascade级联分类器车辆检测+训练方法(无误检) 目的 训练心得 辅助训练工具 GitHub传送门(包含数据集与各种训练的xml文件) 鸣谢 目的 记录一下关于利用Cascade训练车 ...
最新文章
- 300 行代码带你秒懂 Java 多线程!
- 基于注解的SpringMVC整合JPA
- Java List 排序 :Lambda表达式sort排序
- 16.实现多个具有相同方法的接口和父类与实现接口有相同方法
- rr计算机专业英语,《计算机专业英语》电子教本8.pdf
- mysql分组失效_请教MySql中使用表子查询时,试着先排序后分组,出现排序失效的原因?...
- python中dir用法_Python dir() 函数
- JS 数组 Array 对象详解 与 for...of 增强型迭代
- c# listbox使用
- 继承 actionSupport
- matlab 计算工时,C# + Matlab 实现计件工时拟合
- SSM框架整合详细过程
- 1人30天44587行代码,分享舍得网开发经验(修订版)
- AI智能合同审阅系统
- 测试点击屏幕次数的软件_红蜘蛛5校色仪怎么用?显示器校色及测试色域和色彩精准度详细教程...
- java 坦克大战画坦克_【JAVA语言程序设计基础篇】--JAVA实现坦克大战游戏--画出坦克(二)...
- 计算机网络原理 笔记整理
- 转帖:还有谁在用王林快码,还有谁记得王林
- 7zip核心算法LZMA源码分析心得
- 正则表达式常用语法速查+一个简单使用案例
热门文章
- 如何快速完善SOLIDWORKS文件属性信息
- 股票最新最全的短线操作方法
- find7 android 5,没开玩笑 OPPO Find 5抵价1200换Find 7
- jwt使用:往JwtBuilder中设置claims ,值被覆盖的问题
- 全球与中国亚麻布行业市场现状分析及投资可行性研究报告2022-2028年
- “西湖论剑”四大观察:十年筑梦向未来,数字安全开新局
- Metropolis–Hastings算法
- 视频网站引发首播权大战:谁抢了我的“团长”!
- python的多线程与多进程
- SSH—网上商城之商品图片文件上传