的级联选择_OpenCV-Python 级联分类器 | 六十二
目标
在本教程中,
- 我们将学习Haar级联对象检测的工作原理。
- 我们将使用基于Haar Feature的Cascade分类器了解人脸检测和眼睛检测的基础知识。
- 我们将使用cv::CascadeClassifier类来检测视频流中的对象。特别是,我们将使用以下函数: cv::CascadeClassifier::load来加载.xml分类器文件。它可以是Haar或LBP分类器 cv::CascadeClassifier::detectMultiScale来执行检测。
理论
使用基于Haar特征的级联分类器的对象检测是Paul Viola和Michael Jones在其论文“使用简单特征的增强级联进行快速对象检测”中于2001年提出的一种有效的对象检测方法。这是一种基于机器学习的方法,其中从许多正负图像中训练级联函数。然后用于检测其他图像中的对象。
在这里,我们将进行人脸检测。最初,该算法需要大量正图像(面部图像)和负图像(无面部图像)来训练分类器。 然后,我们需要从中提取特征。为此,使用下图所示的Haar功能。 它们就像我们的卷积核一样。 每个特征都是通过从黑色矩形下的像素总和中减去白色矩形下的像素总和而获得的单个值。
现在,每个内核的所有可能大小和位置都用于计算许多功能。(试想一下它产生多少计算?即使是一个24x24的窗口也会产生超过160000个特征)。对于每个特征计算,我们需要找到白色和黑色矩形下的像素总和。为了解决这个问题,他们引入了整体图像。无论你的图像有多大,它都会将给定像素的计算减少到仅涉及四个像素的操作。很好,不是吗?它使事情变得更快。
但是在我们计算的所有这些特征中,大多数都不相关。例如,考虑下图。第一行显示了两个良好的特征。选择的第一个特征似乎着眼于眼睛区域通常比鼻子和脸颊区域更暗的性质。选择的第二个特征依赖于眼睛比鼻梁更黑的属性。但是,将相同的窗口应用于脸颊或其他任何地方都是无关紧要的。那么,我们如何从16万多个功能中选择最佳特征?它是由Adaboost实现的。
为此,我们将所有特征应用于所有训练图像。对于每个特征,它会找到最佳的阈值,该阈值会将人脸分为正面和负面。显然,会出现错误或分类错误。我们选择错误率最低的特征,这意味着它们是对人脸和非人脸图像进行最准确分类的特征。 (此过程并非如此简单。在开始时,每个图像的权重均相等。在每次分类后,错误分类的图像的权重都会增加。然后执行相同的过程。将计算新的错误率。还要计算新的权重。继续进行此过程,直到达到所需的精度或错误率或找到所需的功能数量为止。
最终分类器是这些弱分类器的加权和。之所以称为弱分类,是因为仅凭它不能对图像进行分类,而是与其他分类一起形成强分类器。该论文说,甚至200个功能都可以提供95%的准确度检测。他们的最终设置具有大约6000个功能。 (想象一下,从160000多个功能减少到6000个功能。这是很大的收获)。
因此,现在你拍摄一张照片。取每个24x24窗口。向其应用6000个功能。检查是否有脸。哇..这不是效率低下又费时吗?是的。作者对此有一个很好的解决方案。
在图像中,大多数图像是非面部区域。因此,最好有一种简单的方法来检查窗口是否不是面部区域。如果不是,请一次性丢弃它,不要再次对其进行处理。相反,应将重点放在可能有脸的区域。这样,我们将花费更多时间检查可能的面部区域。
为此,他们引入了级联分类器的概念。不是将所有6000个功能部件应用到一个窗口中,而是将这些功能部件分组到不同的分类器阶段,并一一应用。 (通常前几个阶段将包含很少的功能)。如果窗口在第一阶段失败,则将其丢弃。我们不考虑它的其余功能。如果通过,则应用功能的第二阶段并继续该过程。经过所有阶段的窗口是一个面部区域。这个计划怎么样!
作者的检测器具有6000多个特征,具有38个阶段,在前五个阶段具有1、10、25、25和50个特征。 (上图中的两个功能实际上是从Adaboost获得的最佳两个功能)。根据作者的说法,每个子窗口平均评估了6000多个特征中的10个特征。
因此,这是Viola-Jones人脸检测工作原理的简单直观说明。阅读本文以获取更多详细信息,或查看其他资源部分中的参考资料。
OpenCV中的Haar-级联检测器
OpenCV提供了一种训练方法(请参阅Cascade分类器训练)或预先训练的模型,可以使用cv::CascadeClassifier::load方法读取。预训练的模型位于OpenCV安装的data文件夹中,或在此处找到。
以下代码示例将使用预训练的Haar级联模型来检测图像中的面部和眼睛。首先,创建一个cv::CascadeClassifier并使用cv::CascadeClassifier::load方法加载必要的XML文件。然后,使用cv::CascadeClassifier::detectMultiScale方法完成检测,该方法返回检测到的脸部或眼睛的边界矩形。
本教程的代码如下所示。你也可以从这里下载
from __future__ import print_functionimport cv2 as cvimport argparsedef detectAndDisplay(frame): frame_gray = cv.cvtColor(frame, cv.COLOR_BGR2GRAY) frame_gray = cv.equalizeHist(frame_gray) #-- 检测面部 faces = face_cascade.detectMultiScale(frame_gray) for (x,y,w,h) in faces: center = (x + w//2, y + h//2) frame = cv.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 = cv.circle(frame, eye_center, radius, (255, 0, 0 ), 4) cv.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='data/haarcascades/haarcascade_frontalface_alt.xml')parser.add_argument('--eyes_cascade', help='Path to eyes cascade.', default='data/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_cascadeeyes_cascade_name = args.eyes_cascadeface_cascade = cv.CascadeClassifier()eyes_cascade = cv.CascadeClassifier()#-- 1. 加载级联if not face_cascade.load(cv.samples.findFile(face_cascade_name)): print('--(!)Error loading face cascade') exit(0)if not eyes_cascade.load(cv.samples.findFile(eyes_cascade_name)): print('--(!)Error loading eyes cascade') exit(0)camera_device = args.camera#-- 2. 读取视频流cap = cv.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) if cv.waitKey(10) == 27: break
结果
- 这是运行上面的代码并将内置摄像头的视频流用作输入的结果:
请确保程序会找到文件haarcascade_frontalface_alt.xml和haarcascade_eye_tree_eyeglasses.xml的路径。它们位于opencv/data/ haarcascades中
- 这是使用文件lbpcascade_frontalface.xml(经过LBP训练)进行人脸检测的结果。对于眼睛,我们继续使用本教程中使用的文件。
附加资源
- Paul Viola and Michael J. Jones. Robust real-time face detection. International Journal of Computer Vision, 57(2):137–154, 2004. [228]
- 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. [129]
- 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
的级联选择_OpenCV-Python 级联分类器 | 六十二相关推荐
- 如何选择适合你的兴趣爱好(六十二),骑马
围城网的摇摇今天给大家带来了"如何选择适合你的兴趣爱好"系列专辑的第六十二讲 --骑马.在今天,骑马是一项集休闲.娱乐.健身.康复于一体的时尚高雅运动,素有"贵族运动&q ...
- 面渣逆袭:三万字,七十图,详解计算机网络六十二问(收藏版)
大家好,我是老三,开工大吉,虎年第一篇,面渣逆袭系列继续! 这次给大家带来了计算机网络六十二问,三万字,七十图详解,大概是全网最全的网络面试题. 建议大家收藏了慢慢看,新的一年一定能够跳槽加薪,虎年& ...
- 面渣逆袭:计算机网络六十二问,三万字图文详解!速收藏!
这次给大家带来了计算机网络六十二问,三万字,七十图详解,大概是全网最全的网络面试题. 基础 1.说下计算机网络体系结构 计算机网络体系结构,一般有三种:OSI 七层模型.TCP/IP 四层模型.五层结 ...
- 【Microsoft Azure 的1024种玩法】六十二.利用Azure Private DNS 实现虚拟网络中域名的管理解析
[简介] Azure Private DNS是Azure为我们虚拟网络提供的安全可靠的DNS服务,我们无需自行配置DNS即可在虚拟网络中实现域名的解析及配置, 于此同时,我们在内网中也可以利用自己的自 ...
- 达芬奇密码 第六十二章
达芬奇密码 第六十二章[@more@] 第六十二章 "雷,我是被冤枉的."兰登说道,尽量保持着镇定."你是了解我的.我绝对不会杀人." 提彬的口气依然严厉.&q ...
- JavaEE学习日志(六十二): jQuery遍历,jQuery事件,省市联动,左右互选
JavaEE学习日志持续更新----> 必看!JavaEE学习路线(文章总汇) JavaEE学习日志(六十二) jQuery jQuery遍历 传统遍历 jQuery对象遍历 jQuery全局函 ...
- linux i2c adapter 增加设备_「正点原子Linux连载」第六十二章Linux SPI驱动实验(一)...
1)实验平台:正点原子Linux开发板 2)摘自<正点原子I.MX6U嵌入式Linux驱动开发指南>关注官方微信号公众号,获取更多资料:正点原子 第六十二章Linux SPI驱动实验 上一 ...
- JavaScript学习(六十二)—解析选项和序列化选项
JavaScript学习(六十二)-解析选项和序列化选项 一.解析选项 格式:JSON.parse(参数1,参数2); 参数说明 参数1:表示要转换为JS对象的json字符串 参数2:表示将json转 ...
- 问题六十二:怎么求一元十次方程在区间内的所有不相等的实根(2)——修正“区间端点零值”问题
前续"问题六十二:怎么求一元十次方程在区间内的所有不相等的实根"和"问题五十九:怎么求一元六次方程在区间内的所有不相等的实根(3)--修正一个问题" 不管是求解 ...
最新文章
- 怎么扫描_打印机上扫描仪怎么用 打印机上扫描仪使用及添加方法
- Java基础-OOP特性之封装、继承、多态、抽象
- Javascript中的prototype
- EasyUI中分页的简单使用
- ScrollView’s handy trick
- 蚂蚁金服SOFA开源负责人鲁直:不只是中间件,未来会开源更多
- SpringMVC 控制层注解
- debian查询端口进程_centos linux系统配置查询
- 太强了!一个基于 Redis 的限流系统的设计!
- PDF阅读器哪个好用?看完这篇文章就可以不用再问了
- sysmain服务怎么启动 Win7 SuperFetch无法启动
- 打印系统开发(66)——监控打印机的打印队列
- lldb连接debugserver报错failed to get reply to handshake packet
- 陶哲轩实分析 6.4 节习题试解
- C. Minimum Ties (构造)
- 如何使用快应用内置地图查看、导航位置
- echarts关系图(force图)
- 跳过SourceTree的注册步骤
- Tessent scan ATPG(7) 设计规则检查 (DRC)
- 网页二维码生成器纯js代码带logo图纯前端合成