【OpenCV-Python】教程:9-1 级联分类器

news2024/11/18 12:28:04

OpenCV Python 级联分类器

【目标】

  • Haar 级联目标检测器工作方式;
  • Haar 级联分类器检测人脸和人眼

【理论】

基于Haar特征的级联分类器的目标检测是Paul Viola和Michael Jones在2001年的论文中提出的一种有效的目标检测方法。这是一种基于机器学习的方法,从大量的正面和负面图像中训练级联函数。然后用它来检测其他图像中的物体。

这里我们将使用人脸检测。最初,该算法需要大量的正面图像(人脸图像)和负面图像(没有人脸的图像)来训练分类器。然后我们需要从中提取特征。为此,使用下图所示的Haar特征。它们就像卷积核一样。每个特征都是一个单独的值,由黑色矩形下的像素和减去白色矩形下的像素和得到。

在这里插入图片描述

现在,每个内核的所有可能的大小和位置都被用来计算大量的特征。(想象一下它需要多少计算量?即使是一个24x24的窗口也会产生超过160000个特征)。对于每个特征计算,我们需要找到白色和黑色矩形下的像素之和。为了解决这个问题,他们引入了积分图。无论您的图像有多大,它都将给定像素的计算减少到只涉及四个像素的操作。不错,不是吗?它让事情变得超快。

但在我们计算的所有这些特征中,大多数都是不相关的。例如,考虑下面的图像。上面一行显示了两个很好的特征。选择的第一个特征似乎集中在眼睛区域通常比鼻子和脸颊区域更黑的属性上。选择的第二个特征依赖于眼睛比鼻梁暗的属性。但同样的窗口应用于脸颊或任何其他地方是无关紧要的。那么,我们如何从160000多个功能中选择出最好的功能呢?它由Adaboost实现。

在这里插入图片描述

为此,我们将每个特征应用到所有的训练图像上。对于每个特征,它会找到最佳阈值,将人脸分为正面和负面。显然,会有错误或错误分类。我们选择错误率最小的特征,这意味着它们是最准确地分类人脸和非人脸图像的特征。(这个过程没有这么简单。每张图片在开始时都被赋予了相同的权重。每次分类后,错误分类的图像权重都会增加。然后进行相同的过程。计算新的错误率。还有新的砝码。该过程将继续进行,直到达到所需的精度或错误率或找到所需的特征数量为止)。

最后的分类器是这些弱分类器的加权和。它被称为弱分类器,因为它单独不能对图像进行分类,但与其他分类器一起形成强分类器。论文称,即使200个特征也能提供95%的检测准确率。他们的最终设置有大约6000个功能。(想象一下从160000多个功能减少到6000个功能。这是一个很大的收获)。

现在你得到一个图像。以每个24x24的窗口为例。应用6000个特性。检查一下是不是脸。哇. .这不是有点低效和耗时吗?是的,它是。作者对此有一个很好的解决方案。

在图像中,大部分图像是非人脸区域。因此,最好有一个简单的方法来检查一个窗口是否不是一个人脸。如果不是,一次性丢弃它,不要再处理它。相反,把注意力集中在可以露出脸的部位。这样,我们花更多的时间检查可能的面部区域。

为此,他们引入了分级器级联的概念。不是将所有6000个特征应用到一个窗口上,而是将这些特征分组到分类器的不同阶段并逐个应用。(通常前几个阶段包含的功能会非常少)。如果一个窗口在第一阶段失败,则丢弃它。我们不考虑剩余的功能。如果通过了,应用第二阶段的特性并继续这个过程。通过所有阶段的窗口是一个面区域。那个计划怎么样!

作者的探测器有6000多个特征,共38个阶段,前5个阶段分别为1、10、25、25和50个特征。(上图中的两个特征实际上是从Adaboost中获得的最佳两个特征)。根据作者的说法,每个子窗口平均评估6000多个特征中的10个。

这是对Viola-Jones人脸检测工作原理的一个简单直观的解释。阅读论文以获得更多细节,或查看附加资源部分的参考资料。

【代码】

在这里插入图片描述

import cv2

def detectAndDisplay(frame):
    frame_gray = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
    frame_gray = cv2.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 = 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 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 = cv2.circle(frame, eye_center, radius, (255, 0, 0), 4)
    cv2.imshow('Capture - Face detection', frame)
    return frame 

face_cascade_name = "assets/haarcascade_frontalface_alt.xml"
eyes_cascade_name = "assets/haarcascade_eye_tree_eyeglasses.xml"

face_cascade = cv2.CascadeClassifier()
eyes_cascade = cv2.CascadeClassifier()
# -- 1. Load the cascades
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 = 0
camera_device = "assets/1.mp4"
# -- 2. Read the video stream
cap = cv2.VideoCapture(camera_device)

ret, frame = cap.read()
h, w, _ = frame.shape


# 定义保存视频的编码格式、分辨率和帧率等信息
fourcc = cv2.VideoWriter_fourcc(*'XVID')
out = cv2.VideoWriter('output.mp4', fourcc, 20.0, (w//2,  h//2))

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
  
    framersz = cv2.resize(frame, (0, 0), fx=0.5, fy=0.5)
    frmaeres = detectAndDisplay(framersz)
  
    # 保存视频
    out.write(frmaeres)
  
    if cv2.waitKey(10) == 27:
        break
  
cap.release()
out.release()
cv2.destroyAllWindows()

【接口】

  • CascadeClassifier
cv2.CascadeClassifier(		) ->	<CascadeClassifier object>
cv2.CascadeClassifier(	filename	) ->	<CascadeClassifier object>

从文件加载一个级联分类器

  • detectMultiScale
cv2.CascadeClassifier.detectMultiScale(	image[, scaleFactor[, minNeighbors[, flags[, minSize[, maxSize]]]]]	) ->	objects
cv2.CascadeClassifier.detectMultiScale2(	image[, scaleFactor[, minNeighbors[, flags[, minSize[, maxSize]]]]]	) ->	objects, numDetections
cv2.CascadeClassifier.detectMultiScale3(	image[, scaleFactor[, minNeighbors[, flags[, minSize[, maxSize[, outputRejectLevels]]]]]]	) ->	objects, rejectLevels, levelWeights

检测输入图像中不同大小的对象。检测到的对象作为矩形列表返回。

  • image: 待检测目标的图像
  • objects: 检测到的目标,vector或者list
  • numDetections: 对应对象的检测数向量。一个物体的探测次数是相邻的正分类矩形的数量,这些矩形连接在一起形成了该物体。
  • scaleFactor: 指定在每个图像尺度上图像大小减小多少。
  • minNeighbors: 指定每个候选矩形应该有多少个相邻矩形框来保留它。
  • flags: 该参数与cvHaarDetectObjects函数中对于旧级联的含义相同。但它不用于新的级联。
  • minSize: 最小目标大小
  • maxSize: 最大目标大小

【参考】

  1. OpenCV: Cascade Classifier
  2. Paul Viola and Michael J. Jones. Robust real-time face detection. International Journal of Computer Vision, 57(2):137–154, 2004. [263]
  3. 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. [149]
  4. Video Lecture on Face Detection and Tracking
  5. An interesting interview regarding Face Detection by Adam Harvey
  6. OpenCV Face Detection: Visualized on Vimeo by Adam Harvey
  7. OpenCV: cv::CascadeClassifier Class Reference

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/125282.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Swift 周报 第二十期

前言 本期是 Swift 编辑组自主整理周报的第十一期&#xff0c;每个模块已初步成型。各位读者如果有好的提议&#xff0c;欢迎在文末留言。 欢迎投稿或推荐内容。目前计划每两周周一发布&#xff0c;欢迎志同道合的朋友一起加入周报整理。 在这个来去匆匆风云变幻的季节&…

工厂设备管理难点与解决方案

工厂设备管理中经常会遇到哪些问题&#xff1f; 设备是生产力的重要组成部分&#xff0c;是工厂从事生产经营的重要工具&#xff0c;生产设备无论从企业资产的占有率&#xff0c;还是从管理工作的内容上都占据相当大的比重&#xff0c;管好、用好设备&#xff0c;提高设备管理…

JS 之 对象、继承

目录 JS对象 1.通过new Object()创建 2.工厂模式 3.构造函数模式 4.原型模式 5.组合使用构造函数与原型对象 6.动态原型模式 7. 寄生构造函数模式 8.稳妥构造函数模式 原型对象 原型链 继承 1.原型链继承 2.借用构造函数&#xff08;经典继承 | 伪造函数&#xff…

CTF之密码学题目-classical coding

CTF系列文章 第一篇 CTF之密码学题目-classical && coding 文章目录CTF系列文章前言一、题目是什么&#xff1f;二、解题步骤1.下载文件&#xff0c;解压2.解码Unicode3.ASCII码解码4.BrainFunk解码5.莫斯码解码6.字频解密总结前言 在CTF比赛中&#xff0c;有关密码学…

Memtiter-benchmark源码解析2--shared_connection

shard_connection.h class shad_connection private members Line 161 行 bufferevent* m_bev&#xff1b;重要的bufferevent_event important methods setup_event shard_connection.cpp bufferevent_setcb 设置了 m_bev 的读事件的函数回调&#xff0c;没有设置写事件的函…

如何策划一场银行校招线上笔试?

策划一场银行校园招聘线上笔试&#xff0c;只需要4步。 牛客基于服务的上千家企业现状发现&#xff0c;银行业大多数企业在校园招聘的笔试环节会面临这些核心问题&#xff1a; 缺乏出题专业度&#xff1a;大多数企业出题者为业务部门员工&#xff0c;技能水平不一&#xff0c…

Educational Codeforces Round 97 (Rated for Div. 2) D. Minimal Height Tree

Problem - D - Codeforces 翻译&#xff1a; Monocarp有一棵树&#xff0c;它由&#x1d45b;个顶点组成&#xff0c;并以顶点1为根。他决定研究BFS(宽度优先搜索)&#xff0c;所以他在他的树上运行BFS&#xff0c;从根开始。BFS可以用下面的伪代码描述: A [] #处理顶点的顺序…

欧几里得空间

文章目录1 欧几里得范数2 距离3 标准内积4 柯西-施瓦茨不等式5 正交6 叉乘7 平行四边形法则8 欧几里得运动线性空间里最重要的就是欧几里得空间了&#xff0c;这是线性代数学习绕不过去的槛。欧几里得空间&#xff0c;学习起来我觉得吧&#xff0c;主要是三个点&#xff1a;内积…

Golang面试宝典——Go语言实现排序算法之快速排序

关于Golang面试宝典 最近几年&#xff0c;Go的热度持续飙升&#xff0c;国内外很多大公司都在大规模的使用Go。Google是Go语言诞生的地方&#xff0c;其他公司如Facebook、腾讯、阿里、字节跳动、百度、京东、小米等都在拥抱和转向Go。Go语言的开源项目也非常多&#xff0c;如…

无人驾驶(四)---远程桌面控制工具: NoMachine踩坑记录

NoMachine for mac是一款免费的远程桌面访问工具&#xff0c;这款软件的连接到远程桌面后延迟可以非常低&#xff0c;NX协议在高延迟低带宽的链路上提供了近乎本地速度的响应能力&#xff0c;打破空间和时间的障碍&#xff0c;让您的桌面环游世界。 1.环境配置 服务端&#x…

西门子PLC各类通信协议差异对比

西门子PLC有4大类&#xff0c;几十个型号类型&#xff0c;PLC不同所支持的通讯协议也不相同。 S7-200系列支持的协议有&#xff1a;PPI、MPI、PROFIBUS、以太网、S7协议、AS-INTERFACE、USS、MODBUS、自由口。 S7-300\400系列支持的协议有&#xff1a;MPI、PROFIBUS、ETHERNE…

陌陌综合案例

注&#xff1a;大家觉得博客好的话&#xff0c;别忘了点赞收藏呀&#xff0c;本人每周都会更新关于人工智能和大数据相关的内容&#xff0c;内容多为原创&#xff0c;Python Java Scala SQL 代码&#xff0c;CV NLP 推荐系统等&#xff0c;Spark Flink Kafka Hbase Hive Flume等…

【python3】10.python高阶内容:装饰器

10.python高阶内容&#xff1a;装饰器 2022.12.28 装饰器装饰器(Decorators)是 Python 的一个重要部分。简单地说&#xff1a;他们是修改其他函数的功能的函数。参数可以是函数&#xff0c;返回值也可以是函数。 10.1 形式 def decorator(fn):def wrapper(name):print(name&…

【Linux进程】进程的基本概念,fork的使用,各种状态的含义,孤儿和僵尸进程的含义

目录 1.进程的基本概念 2.描述进程-PCB 3.fork创建子进程 4.各种状态对应的含义及进程大概的运行原理 5.僵尸进程 ​6.孤儿进程 7.进程的优先级 1.进程的基本概念 2.描述进程-PCB PCB概念:进程信息被放在一个叫做进程控制块的数据结构中&#xff0c;可以理解为进程属性的集…

ChatGPT注册教程

ChatGPT是最近很火的AI智能对话聊天软件。我们是能够去用来进行更加自由的智能内容讨论和聊天。有的小伙伴还不知道怎么注册。 官方地址&#xff1a;chat.openai.com/chat 注册步骤 1、进入官网后&#xff0c;点击注册按钮。 2、点击创建账号。 3、输入自己的邮箱账号。 4、…

整合Kafka

Main Concepts 一些服务器形成了存储层&#xff0c;被称为broker&#xff0c;其他服务器运行kafka连接去不断地导入和导出数据作为事件流&#xff0c;将kafka和关系型数据库等存在的系统集成。 Servers: Kafka is run as a cluster of one or more servers that can span mult…

高手不用Redis内存数据库一

不是说Redis不好&#xff0c;不用Redis用别的(比如:Memcached 2、VoltDB 3、MongoDB 4、Hazelcast 5、Aerospike) No! No! No!!! Redis 很好&#xff0c;我不拦着您用…… 而是说&#xff0c;我们的水平更高了以后&#xff0c;您一定会感受到 内存数据库 不够用、不够灵活、不…

JavaScript基础篇2之日期时间函数

一、计算机中时间字母表示的预知识储备&#xff1a; G&#xff08;age&#xff0c;时代年龄等意思&#xff09;&#xff1a;时代标志&#xff0c;如AD&#xff08;Anno Domini公元&#xff09;、BC&#xff08;Before Christ公元前&#xff09;。 y&#xff08;year&#xff…

zabbix安装使用

1.1 Zabbix概述 Zabbix是一款能够监控各种网络参数以及服务器健康性和完整性的软件。Zabbix使用灵活的通知机制&#xff0c;允许用户为几乎任何事件配置基于邮件的告警。这样可以快速反馈服务器的问题。基于已存储的数据&#xff0c;Zabbix提供了出色的报告和数据可视化功能。…

基于python的turtle实现圣诞树的绘制

文章目录一、前言二、基于turtle实现绘制圣诞树三、效果展示四、实现步骤代码实现分步骤1. 导入库2. 配置圣诞树高度等信息3. 定义函数get_color()可获取随机颜色4. 定义函数snow() 绘制一朵雪花5. 定义函数name()可随机写一些文字6. 定义函数koc() 绘制星星7.定义函数tree()绘…