《opencv实用探索·二十一》人脸识别
Haar级联分类器
在OpenCV中主要使用了两种特征(即两种方法)进行人脸检测,Haar特征和LBP特征。用的最多的是Haar特征人脸检测。
Haar级联分类器是一种用于目标检测的机器学习方法,它是一种基于机器学习的特征选择方法,能够快速而有效地检测出图像中的对象或特定的模式,例如人脸。
Haar级联分类器工作的基本原理是使用弱分类器(通常是基于决策树的弱分类器)级联成一个强大的分类器。在训练过程中,它通过提取训练样本中的特征并根据这些特征进行分类来逐步学习目标对象(例如人脸)的特征模式。级联的概念允许快速筛选出负样本,减少计算量,从而提高了检测速度。下图展示了级联的过程:
我们需要考虑如何在层次结构中组合多个Haar级联分类器,以便用一个分类器识别父区域(就目标而言是一张人脸),用其他分类器识别子区域(比如眼睛)。
opencv提供了多种训练好的级联分类器模型文件,这些文件通常是XML格式,存放在opencv安装目录下源码文件夹中sources\data\haarcascades
haarcascade_eye.xml, 眼睛
haarcascade_eye_tree_eyeglasses.xml, 戴眼镜的眼睛
haarcascade_frontalcatface.xml, 正面猫脸
haarcascade_frontalcatface_extended.xml, 正面猫脸
haarcascade_frontalface_alt.xml, 正面人脸
haarcascade_frontalface_alt2.xml, 正面人脸
haarcascade_frontalface_alt_tree.xml, 正面人脸
haarcascade_frontalface_default.xml, 正面人脸
haarcascade_fullbody.xml, 人体
haarcascade_lefteye_2splits.xml, 左眼
haarcascade_license_plate_rus_16stages.xml,
haarcascade_lowerbody.xml,
haarcascade_profileface.xml,
haarcascade_righteye_2splits.xml, 右眼
haarcascade_russian_plate_number.xml,
haarcascade_smile.xml, 笑脸
haarcascade_upperbody.xml, 上身
从文件名可知这些级联是用于人脸、眼睛、鼻子和嘴的跟踪。这些文件需要正面、直立的人脸图像。创建人脸检测器时会使用这些文件,创建自己的级联,并训练这些级联来检测各种对象。
Haar级联分类器执行流程
1. 数据准备
正样本收集: 收集包含需要检测对象的图像,并对图像进行标注,标注出感兴趣对象的位置。
负样本收集: 收集不包含感兴趣对象的图像,或者与感兴趣对象不相关的图像样本。
创建样本信息文件: 创建包含正样本和负样本信息的数据文件,描述图像路径、对象位置和标签等信息。
2. 特征提取
Haar 特征选择: 对于每个样本图像,从图像中提取 Haar 特征。Haar 特征是一种矩形区域的强度差异计算,用于表示图像的局部特征。
特征值计算: 计算每个样本图像的 Haar 特征值。Haar 特征是根据矩形区域的像素和计算的。这些特征值将用于训练分类器。
3. 训练分类器
级联分类器训练: 使用提取的特征值对分类器进行训练。初始阶段,级联分类器包含多个弱分类器(例如决策树、Adaboost 等)。
特征选择和增强: 训练过程中,级联分类器将对特征进行选择和增强,以提高对感兴趣对象和背景的区分能力。
级联结构构建: 根据训练数据和特征值,构建多个级联阶段,每个阶段都包含多个弱分类器。
4. 级联分类器应用
对象检测: 将训练好的级联分类器应用于新的图像中进行对象检测。级联分类器采用级联结构逐渐缩小搜索区域,使用不同阶段的弱分类器进行对象检测。
非极大值抑制: 对检测到的对象进行非极大值抑制(Non-Maximum Suppression),以消除重叠区域或多次检测到同一对象的情况。
使用 Haar 级联检测器检测图片中的人脸的步骤:
(1)创建一个 CascadeClassifier 级联分类器对象,从 .xml 文件加载级联分类器模型。
(2)读取待检测的图片。
(3)使用 detectMultiScale() 方法检测图片,返回检测到的面部或眼睛的边界矩形。
(4)将检测到的边界矩形绘制到检测图片上。
OpenCV 中定义了级联分类器类 cv::CascadeClassifier。在 Python 语言中,使用接口函数 cv2.CascadeClassifier() 从文件创建分类器。成员函数 cv.CascadeClassifier.detectMultiScale() 用于执行对图像进行目标检测。
代码示例:
#include "opencv2/objdetect/objdetect.hpp"
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"#include <iostream>
#include <stdio.h>using namespace std;
using namespace cv;void detectAndDisplay(Mat frame);//注意,需要把"haarcascade_frontalface_alt.xml"和"haarcascade_eye_tree_eyeglasses.xml"这两个文件复制到工程路径下
string face_cascade_name = "haarcascade_frontalface_alt.xml";
string eyes_cascade_name = "haarcascade_eye_tree_eyeglasses.xml";
CascadeClassifier face_cascade;
CascadeClassifier eyes_cascade;
string window_name = "Capture - Face detection";
RNG rng(12345);//-----------------------------------【main( )函数】--------------------------------------------
// 描述:控制台应用程序的入口函数,我们的程序从这里开始
//-------------------------------------------------------------------------------------------------
int main(void)
{VideoCapture capture;Mat frame;//-- 1. 加载级联(cascades)if (!face_cascade.load(face_cascade_name)) { printf("--(!)Error loading\n"); return -1; };if (!eyes_cascade.load(eyes_cascade_name)) { printf("--(!)Error loading\n"); return -1; };//-- 2. 读取视频capture.open(0);if (capture.isOpened()){for (;;){capture >> frame;//-- 3. 对当前帧使用分类器(Apply the classifier to the frame)if (!frame.empty()){detectAndDisplay(frame);}else{printf(" --(!) No captured frame -- Break!"); break;}int c = waitKey(10);if ((char)c == 'c') { break; }}}return 0;
}void detectAndDisplay(Mat frame)
{std::vector<Rect> faces;Mat frame_gray;cvtColor(frame, frame_gray, COLOR_BGR2GRAY);equalizeHist(frame_gray, frame_gray);//-- 人脸检测face_cascade.detectMultiScale(frame_gray, faces, 1.1, 3, 0 | CASCADE_SCALE_IMAGE, Size(30, 30), Size(200, 200));for (size_t i = 0; i < faces.size(); i++){Point center(faces[i].x + faces[i].width / 2, faces[i].y + faces[i].height / 2);ellipse(frame, center, Size(faces[i].width / 2, faces[i].height / 2), 0, 0, 360, Scalar(255, 0, 255), 2, 8, 0);Mat faceROI = frame_gray(faces[i]);std::vector<Rect> eyes;//-- 在脸中检测眼睛eyes_cascade.detectMultiScale(faceROI, eyes, 1.1, 2, 0 | CASCADE_SCALE_IMAGE, Size(30, 30));for (size_t j = 0; j < eyes.size(); j++){Point eye_center(faces[i].x + eyes[j].x + eyes[j].width / 2, faces[i].y + eyes[j].y + eyes[j].height / 2);int radius = cvRound((eyes[j].width + eyes[j].height) * 0.25);circle(frame, eye_center, radius, Scalar(255, 0, 0), 3, 8, 0);}}//-- 显示最终效果图imshow(window_name, frame);
}
代码分析:
(1)加载级联分类器
通过 CascadeClassifier 类加载人脸和眼睛的级联分类器(XML 文件),即 haarcascade_frontalface_alt.xml 和 haarcascade_eye_tree_eyeglasses.xml。
(2)读取视频流
使用 VideoCapture 对象打开摄像头设备(ID为0),读取视频帧数据。
(3)循环处理每一帧
在循环中,不断从摄像头捕获帧数据 capture >> frame。
对于每一帧,先进行空帧检测,如果帧不为空则调用 detectAndDisplay() 函数进行人脸和眼睛检测。
(4)人脸检测
detectAndDisplay() 函数将传入的帧 frame 转换为灰度图像 frame_gray,并进行直方图均衡化。
调用 face_cascade.detectMultiScale() 在灰度图像中检测人脸区域,并将检测到的人脸区域存储在 faces 向量中。
什么叫直方图均衡化?
首先直方图是图像中像素强度分布的图形表达方式,它统计了每一个强度值所具有的像素个数。如下图所示,横坐标代表图像的灰度变化0-255,纵坐标代码每个灰度对应的像素个数。
那么直方图均衡化是通过拉伸像素强度分布范围来增强图像对比度的一种方法。特别是在一些局部对比度较低的图像中,可以帮助提高图像的质量。
说得更清楚一些, 以下面的直方图为例, 你可以看到左边直方图像素主要集中在中间的一些强度值上. 直方图均衡化要做的就是 拉伸 这个范围.。对其应用均衡化后, 得到了右图所示的直方图. 均衡化的图像见下面右图。可以很明显的看到图像对比度得到了增强。
图像均衡化函数
void equalizeHist(InputArray src, OutputArray dst);
detectMultiScale函数解析:该函数主要用于级联分类器(如 Haar 级联分类器或者基于 HOG 特征的 SVM 分类器)进行对象检测。
void CascadeClassifier::detectMultiScale(InputArray image, // 输入图像std::vector<Rect>& objects, // 检测到的对象位置矩形double scaleFactor = 1.1, // 每次图像缩小的比例int minNeighbors = 3, // 最小邻近数,用于合并矩形int flags = 0, // 未使用的参数,默认为0Size minSize = Size(), // 对象最小尺寸Size maxSize = Size() // 对象最大尺寸
);
image:输入图像(灰度图像或彩色图像)。
objects:检测到的对象位置矩形集合,返回给调用者。
scaleFactor:表示在前后两次相继的扫描中,搜索窗口的比例系数。默认为1.1即每次搜索窗口依次扩大10%。建议范围通常在 1.01 到 1.5 之间,较小的值会增加检测时间,但也会增加准确性。较大的值会减少检测时间,但可能会降低准确性。
minNeighbors:匹配成功所需要的周围矩形框的数目,每一个特征匹配到的区域都是一个矩形框,只有多个矩形框同时存在的时候,才认为是匹配成功,比如人脸,这个默认值是3,较大的值可以提高对象检测的准确性,但也会增加漏检率。通常建议设置在3到6之间。
flags:未使用的参数,通常为0。
可以取如下这些值:
CASCADE_DO_CANNY_PRUNING=1, 利用canny边缘检测来排除一些边缘很少或者很多的图像区域
CASCADE_SCALE_IMAGE=2, 正常比例检测
CASCADE_FIND_BIGGEST_OBJECT=4, 只检测最大的物体
CASCADE_DO_ROUGH_SEARCH=8 初略的检测
minSize 和 maxSize:指定对象的最小和最大尺寸。在实际应用中,可以根据目标对象的大小设置这两个参数,以过滤掉尺寸不在指定范围内的检测结果。minSize对于人脸检测,通常设置在 20x20 到 30x30 的范围内。maxSize对于人脸检测,可以设置在 200x200 到 300x300 之间。
(5)眼睛检测
遍历每个检测到的人脸区域,在每个人脸区域中调用 eyes_cascade.detectMultiScale() 进行眼睛检测,并将检测到的眼睛区域存储在 eyes 向量中。
在检测到的每个眼睛区域周围画一个圆圈。
(6)显示结果
最后通过 imshow() 在窗口中显示带有人脸和眼睛检测框的帧图像。
效果显示:
相关文章:
《opencv实用探索·二十一》人脸识别
Haar级联分类器 在OpenCV中主要使用了两种特征(即两种方法)进行人脸检测,Haar特征和LBP特征。用的最多的是Haar特征人脸检测。 Haar级联分类器是一种用于目标检测的机器学习方法,它是一种基于机器学习的特征选择方法,…...
前端项目配置下载源npm, yarn,pnpm
前端项目配置下载源 npm: npm config set registry registryhttps://registry.npmmirror.com -g验证: npm config get registry yarn: yarn config set registry registryhttps://registry.npmmirror.com -gyarn config get registryyarn找不到, 需要管理员在命令行: set-exec…...
Elasticsearch之ik中文分词篇
Elasticsearch之ik中文分词篇 ik分词器插件ik分词器安装ik分词模式es ik分词测试 ik分词器插件 es在7.3版本已经支持中文分词,由于中文分词只能支持到单个字进行分词,不够灵活与适配我们平常使用习惯,所以有很多对应中文分词出现,…...
2023_Spark_实验三十:测试Flume到Kafka
实验目的:测试Flume采集数据发送到Kafka 实验方法:通过centos7集群测试,将flume采集的数据放到kafka中 实验步骤: 一、 kafka可视化工具介绍 Kafka Tool是一个用于管理和使用Apache Kafka集群的GUI应用程序。 Kafka Tool提供了…...
urllib2 HTTP头部注入
文章目录 注入原理例题 [SWPU 2016]web7 注入原理 参考文章 应用场景是具有SSRF漏洞,结合CRLF注入 我们以redis数据库为例,当存在SSRF时我们伪造以下请求 http://127.0.0.1%0d%0aCONFIG%20SET%20dir%20%2ftmp%0d%0aCONFIG%20SET%20dbfilename%20evil%…...
在 WebRTC 中,Offer/Answer 模型是协商 WebRTC 连接参数的关键部分
在 WebRTC 中,Offer/Answer 模型是协商 WebRTC 连接参数的关键部分。当 Offer 和 Answer 交换失败时,可能涉及到多个原因。以下是一些可能的问题和解决方案: SDP 格式错误: Session Description Protocol(SDPÿ…...
数据结构:图解手撕B-树以及B树的优化和索引
文章目录 为什么需要引入B-树?B树是什么?B树的插入分析B树和B*树B树B*树分裂原理 B树的应用 本篇总结的内容是B-树 为什么需要引入B-树? 回忆一下前面的搜索结构,有哈希,红黑树,二分…等很多的搜索结构&a…...
useConsole的封装,vue,react,htmlscript标签,通用
之前用了接近hack的方式实现了console的封装,目标是获取console.log函数的执行(调用栈所在位置)所在的代码行数。 例如以下代码,执行window.mylog(1)时候,console.log实际是在匿名的箭头函数()>{//这里执行的} con…...
Azure Machine Learning - 提示工程高级技术
本指南将指导你提示设计和提示工程方面的一些高级技术。 关注TechLead,分享AI全维度知识。作者拥有10年互联网服务架构、AI产品研发经验、团队管理经验,同济本复旦硕,复旦机器人智能实验室成员,阿里云认证的资深架构师,…...
七款创意项目管理软件解决方案推荐:高效项目管理与团队协作工具
企业无论大小,都离不开项目经理、营销团队和创意人员。他们参与各种头脑风暴,为特定目标打造项目。然而,在创意项目管理中,细节决定成败。若处理不当,可能导致项目失败和混乱。 过去,创意项目管理依赖纸质规…...
如何在公网环境下使用Potplayer访问本地群晖webdav中的影视资源
文章目录 本教程解决的问题是:按照本教程方法操作后,达到的效果是:1 使用环境要求:2 配置webdav3 测试局域网使用potplayer访问webdav3 内网穿透,映射至公网4 使用固定地址在potplayer访问webdav 国内流媒体平台的内…...
数据可视化Seaborn
数据可视化Seaborn Seaborn简介Seaborn API第一个Seaborn应用Seaborn基本概念Seaborn图表类型Seaborn数据集Seaborn样式Seaborn调色板Seaborn分面网格Seaborn统计图表Seaborn散点图Seaborn折线图Seaborn柱状图Seaborn箱线图Seaborn核密度估计图Seaborn分类散点图Seaborn回归分…...
AWS S3相关配置笔记
关闭 阻止所有公开访问 存储桶策略(开放外部访问) {"Version": "2012-10-17","Id": "S3PolicyId1","Statement": [{"Sid": "statement1","Effect": "Allow","Principal"…...
linux:linux的小动物们(ubuntu)
1.蒸汽小火车 输入下面的命令下载,再输出sl sudo apt-get install sl sl2.今天你哞了吗 apt-get moo 3.会说话的小牛 输入下面的命令下载一下 sudo apt-get install cowsay输入这个 cowsay jianbing cowsay -l 查看其它动物的名字 然后cowsay -f 跟上动物名&…...
每日一题(LeetCode)----栈和队列--逆波兰表达式求值
每日一题(LeetCode)----栈和队列–逆波兰表达式求值 1.题目(150. 逆波兰表达式求值) 给你一个字符串数组 tokens ,表示一个根据 逆波兰表示法 表示的算术表达式。 请你计算该表达式。返回一个表示表达式值的整数。 注意: 有效的算…...
2023年第四届 “赣网杯” 网络安全大赛 gwb-web3 Write UP【PHP 临时函数名特性 + 绕过trim函数】
一、题目如下: 二、代码解读: 这段代码是一个简单的PHP脚本,它接受通过GET请求传递的两个参数:‘pass’和’func’: ① $password trim($_GET[pass] ?? );:从GET请求中获取名为’pass’的参数࿰…...
软件设计师——软件工程(一)
📑前言 本文主要是【软件工程】——软件设计师——软件工程的文章,如果有什么需要改进的地方还请大佬指出⛺️ 🎬作者简介:大家好,我是听风与他🥇 ☁️博客首页:CSDN主页听风与他 🌄…...
阿里云|人工智能(AI)技术解决方案
函数计算部署Stable Diffusion AI绘画技术解决方案 通过函数计算快速部署Stable Diffusion模型为用户提供快速通过文字生成图片的能力。该方案通过函数计算快速搭建了AIGC的能力,无需管理服务器等基础设施,专注模型的能力即可。该方案具有高效免运维、弹…...
Axure中继器的使用
一.中继器介绍 在Axure中,中继器(Relays)是一种功能强大的元件,可以用于创建可重复使用的模板或组件。中继器允许您定义一个主要的模板,并在页面中重复使用该模板的实例。以下是中继器的作用和优缺点: 作…...
猫罐头哪个牌子好性价比高?五大性价比高的品牌推荐
很多猫奴担心猫咪天天吃干猫粮可能会导致营养不足,所以想给猫咪换换口味,改善一下饮食。这时,选择猫罐头是个不错的选择。不过,喂猫罐头也是有一些讲究的。 作为从业6年的宠物护理师来说,作为早在几年就开始接触猫罐头…...
宣布推出 ML.NET 3.0
作者:Jeff Handley 排版:Alan Wang ML.NET 是面向 .NET 开发人员的开源、跨平台的机器学习框架,可将自定义机器学习模型集成到 .NET 应用程序中。ML.NET 3.0 版本现已发布,其中包含大量新功能和增强功能! 此版本中的深…...
常见的排序算法---快速排序算法
快速排序算法 快排是基于分治的思想来的,快速排序就是在元素序列中选择一个元素作为基准值,每趟总数据元素的两端开始交替排序,将小于基准值的交换的序列前端,大于基准值的交换到序列后端,介于两者之间的位置称为基准值…...
hive企业级调优策略之分组聚合优化
测试用表准备 hive企业级调优策略测试数据 (阿里网盘下载链接):https://www.alipan.com/s/xsqK6971Mrs 订单表(2000w条数据) 表结构 建表语句 drop table if exists order_detail; create table order_detail(id string comment 订单id,user_id …...
英码科技受邀参加2023计算产业生态大会,分享智慧轨道交通创新解决方案
12月13-14日,“凝心聚力,共赢计算新时代”——2023计算产业生态大会在北京香格里拉饭店成功举办。英码科技受邀参加行业数字化分论坛活动,市场总监李甘来先生现场发表了题为《AI哨兵,为铁路安全运营站好第一道岗》的精彩主题演讲&…...
【openssl】Linux升级openssl-1.0.1到1.1.1
文章目录 前言一、openssl是什么?二、使用步骤1.下载2.编译安装3.一些问题 总结 前言 记录一次openssl的升级,1.0.1升级到1.1.1 一、openssl是什么? OpenSSL是一个开源的加密工具包,广泛用于安全套接层(SSLÿ…...
美国联邦机动车安全标准-FMVSS
FMVSS标准介绍: FMVSS是美国《联邦机动车安全标准》,由美国运输部下属的国家公路交通安全管理局(简称NHTSA)具体负责制定并实施。是美国联邦政府针对机动车制定的安全标准,旨在提高机动车的安全性能,减少交通事故中的人员伤亡。F…...
龙迅LT6211B,HDMI1.4转LVDS,应用于AR/VR市场
产品描述 LT6211B 是一款用于 VR/ 显示应用的高性能 HDMI1.4 至 LVDS 芯片。 对于 LVDS 输出,LT6211B 可配置为单端口、双端口或四端口。对于2D视频流,同一视频流可以映射到两个单独的面板,对于3D视频格式,左侧数据可以发送到一个…...
解决docker拉取镜像错误 missing signature key 问题
核心原因:本地docker版本过低,需要: 1. 彻底卸载本地docker文件 2. 配置yum 镜像文件, 重新安装最新版本 相信教程可参考: CentOS安装Docker(超详细)_centos 安装docker-CSDN博客...
倒计数器:CountDownLatch
CountDownLatch 是 Java 中用于多线程编程的一个同步工具。 它允许一个或多个线程等待其他线程执行完特定操作后再继续执行。 CountDownLatch 通过一个计数器来实现, 该计数器初始化为一个正整数,每当一个线程完成了指定操作,计数器就会减一。…...
vue内容渲染
内容渲染指令用来辅助开发者渲染DOM元素的文本内容。常用的内容渲染指令有3个 1.v-text 缺点:会覆盖元素内部原有的内容 2.{{}}:插值表达式在实际开发中用的最多,只是内容的占位符,不会覆盖内容 3.v-html:可以把带有标…...
遂宁市网站建设/优化落实防控措施
之前一直在博客园写作,最近几天才开的知乎专栏,才疏学浅, 谬误之处请不吝于评论区指教,谢谢大家。文章目录单行文本溢出的省略从单行文本溢出省略到多行文本溢出省略多行文本溢出的省略(...)方案一 ---简单…...
做彩票网站推广犯法吗/百度推广运营怎么做
为了满足客户在启扬i.MX8M Plus开发板使用过程中编译qt版本的需求,这里小编出一期关于i.MX8M Plus开发板交叉编译qt5.15.2的教程。 如果因为yocto工程过于繁琐而不想拉去工程去编译qt,今天这个教程是个不错的解决方法。 1►编译环境搭建 首先将启扬提供…...
重庆忠县网站建设公司哪里有/市场调研方案范文
前面的级数求解的基础终于结束了。开始到了应用的环节。虽然前面所举例的方程都是无法初等地求解,但是总是一个方程一个方程的求级数解也是够麻烦的。能否像初等求解那样化归出一种类型的方程?就像齐次方程、恰当方程那样?接下来可以看到&…...
上海网页设计公司怎么样/网络建站优化科技
1.刘未鹏 | Mind Hacks 文章质量很高,涉及算法、数学和计算机,很值得一看转载于:https://www.cnblogs.com/cpointer/p/4644833.html...
phpcms仿站教程/网站优化是什么意思
css有两大特性:继承性和层叠性 继承性: 面向对象语言都会存在继承的概念,在面向对象语言中,继承的特点:继承了父类的属性和方法。那么我们现在主要研究css,css就是在设置属性的。不会牵扯到方法的层面。 继…...
建设公司网站费用/提高工作效率的句子
1、工具说明 写报告的时候为了细致性,要把IP地址对应的地区给整理出来。500多条IP地址找出对应地区复制粘贴到报告里整了一个上午。 为了下次更好的完成这项重复性很高的工作,所以写了这个小的脚本。 V2.0 写入到XLS中 2、使用方法 把IP写到.txt文件中就…...