opencv基于Haar人脸检测和眼睛检测
作者:过去的时候 发布时间:2022-02-10 13:43:59
本文为大家分享了opencv基于Haar人脸检测和眼睛检测的具体代码,供大家参考,具体内容如下
在这里,我们将进行人脸检测。最初,该算法需要大量正图像(面部图像)和负图像(无面部图像)来训练分类器。然后,我们需要从中提取特征。为此,使用下图所示的Haar功能。它们就像我们的卷积核。每个特征都是通过从黑色矩形下的像素总和中减去白色矩形下的像素总和而获得的单个值。
现在,每个内核的所有可能大小和位置都用于计算许多功能。(试想一下它需要多少计算?即使是一个24x24的窗口也会产生超过160000个特征)。对于每个特征计算,我们需要找到白色和黑色矩形下的像素总和。为了解决这个问题,他们引入了整体形象。无论您的图像有多大,它都会将给定像素的计算减少到仅涉及四个像素的操作。很好,不是吗?它使事情变得超快。
但是在我们计算的所有这些功能中,大多数都不相关。例如,考虑下图。第一行显示了两个良好的功能。选择的第一个特征似乎着眼于眼睛区域通常比鼻子和脸颊区域更暗的性质。选择的第二个功能依赖于眼睛比鼻梁更黑的属性。但是,将相同的窗口应用于脸颊或其他任何地方都是无关紧要的。那么,我们如何从16万多个功能中选择最佳功能?它是由Adaboost实现的。
为此,我们将所有功能应用于所有训练图像。对于每个功能,它会找到最佳的阈值,该阈值会将人脸分为正面和负面。显然,会出现错误或分类错误。我们选择错误率最低的特征,这意味着它们是对人脸和非人脸图像进行最准确分类的特征。(此过程并非如此简单。在开始时,每个图像的权重均相等。在每次分类后,错误分类的图像的权重都会增加。然后执行相同的过程。将计算新的错误率。还要计算新的权重。继续进行此过程,直到达到所需的精度或错误率或找到所需的功能数量为止。
最终分类器是这些弱分类器的加权和。之所以称为弱分类,是因为仅凭它不能对图像进行分类,而是与其他分类一起形成强分类器。该论文说,甚至200个功能都可以提供95%的准确度检测。他们的最终设置具有大约6000个功能。(想象一下,从160000多个功能减少到6000个功能。这是很大的收获)。
因此,现在您拍摄一张照片。取每个24x24窗口。向其应用6000个功能。检查是否有脸。哇…这不是效率低下又费时吗?是的。作者对此有一个很好的解决方案。
在图像中,大多数图像是非面部区域。因此,最好有一种简单的方法来检查窗口是否不是面部区域。如果不是,请一次性丢弃它,不要再次对其进行处理。相反,应将重点放在可能有脸的区域。这样,我们将花费更多时间检查可能的面部区域。
为此,他们引入了级联分类器的概念。不是将所有6000个功能部件应用到一个窗口中,而是将这些功能部件分组到不同阶段的分类器中,并一一应用。(通常前几个阶段将包含很少的功能)。如果窗口在第一阶段失败,则将其丢弃。我们不考虑它的其余功能。如果通过,则应用功能的第二阶段并继续该过程。经过所有阶段的窗口是一个面部区域。这个计划怎么样!
作者的检测器具有6000多个特征,具有38个阶段,在前五个阶段具有1、10、25、25和50个特征。(上图中的两个功能实际上是从Adaboost获得的最佳两个功能)。根据作者的说法,每个子窗口平均评估了6000多个特征中的10个特征。
首先,创建一个cv :: CascadeClassifier并使用cv :: CascadeClassifier :: load方法加载必要的XML文件。然后,使用cv :: CascadeClassifier :: detectMultiScale方法完成检测,该方法返回检测到的脸部或眼睛的边界矩形
from __future__ import print_function
import cv2 as cv
import argparse
def detectAndDisplay(frame):
frame_gray = cv.cvtColor(frame, cv.COLOR_BGR2GRAY)#灰度处理
frame_gray = cv.equalizeHist(frame_gray)#直方图均衡化
#-- Detect faces
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]#获取感兴趣的区域,即人脸矩形
#-- In each face, detect eyes
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='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 = cv.CascadeClassifier()
eyes_cascade = cv.CascadeClassifier()
#-- 1. Load the cascades
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. Read the video stream
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
来源:https://blog.csdn.net/weixin_43886213/article/details/103148871
猜你喜欢
- 翻译:ShiningRay简介你是否知道JavaScript其实也是一个函数式编程语言呢?本指南将教你如何利用JavaScript的函数式特
- 爬取某人的微博数据,把某人所有时间段的微博数据都爬下来。具体思路:创建driver-----get网页----找到并提取信息-----保存c
- 在JavaScript中,我们应该尽可能的用局部变量来代替全局变量,这句话所有人都知道,可是这句话是谁先说的?为什么要这么做?有什么根据么?
- 本文实例讲述了Python三元运算实现方法。分享给大家供大家参考。具体分析如下:Python中没有像C++和Java等语言中的三元运算符,但
- 首先,自学Python是能够找到相关工作的。Python语言在近几年的上升趋势非常明显,语言生态也越来越健全,在Web开发、大数据开发、人工
- 我们都知道float:left和float:right,但是否想过float:center呢?居中浮动。。。<div id="
- 图片外框特征参数:①dashed:虚线 ②dotted:点虚线 ③solid:实线 ④double:双线 ⑤groove:沟槽状 ⑥ridg
- 解决的问题需要将数组(list)或元组(tuple)中的元素导出到N个变量中。解决的方案任何序列都可以通过简单的变量赋值方式将其元素分配到对
- 前两天有一位网友问我一个关于Javascript中++操作符的问题,他的代码大致是这样的ADS.addEvent(window,'c
- 一.权限表mysql数据库中的3个权限表:user 、db、 host权限表的存取过程是:1)先从user表中的host、 user、 pa
- 详细参考:https://gitee.com/copperpeas/uniapp-paymentuniapp-payment介绍uniapp
- 随着短视频的大火,不仅可以给人们带来娱乐,还有热点新闻时事以及各种知识,刷短视频也逐渐成为了日常生活的一部分。本文以一个简单的小例子,简述如
- 围绕一门语言,学习它的文化精髓,能让你成为一名更优秀的程序员。如果你还没读过Python之禅(Zen of Python) ,那么打开Pyt
- PHP获取当前url路径的函数及服务器变量:代码:<?php$path = /usr/opt/../ect/abcd;echo $_S
- 相关概念并发:指一个时间段内,有几个程序在同一个cpu上运行,但是任意时刻只有一个程序在cpu上运行。比如说在一秒内cpu切换了100个进程
- 本文为大家分享了python链表的基础概念和基础用法,供大家参考,具体内容如下一、什么是链表链表是由多个不同的节点组成,每个节点通过指针区域
- Python中的布尔类型Python中的布尔类型(bool)只有两个取值,分别是True和False。bool类型通常用于逻辑判断和条件控制
- 本文实例为大家分享了python实现打砖块小游戏的具体代码,供大家参考,具体内容如下开发益智的打砖块小游戏,你可以试一下能打几块import
- 阅读上一篇:微软建议的ASP性能优化28条守则(4)技巧 13:避免重新确定数组的维数 应尽量避免 Redim 数组。就性能而言,如果计算机
- 1. ASCII 返回与指定的字符对应的十进制数; SQL> select ascii(A) A,ascii(a) a,as