opencv 进阶10-人脸识别原理说明及示例-cv2.CascadeClassifier.detectMultiScale()

news2024/11/24 7:00:03

人脸识别是指程序对输入的人脸图像进行判断,并识别出其对应的人的过程。人脸识别程 序像我们人类一样,“看到”一张人脸后就能够分辨出这个人是家人、朋友还是明星。

当然,要实现人脸识别,首先要判断当前图像内是否出现了人脸,也即人脸检测。只有检 测到图像中出现了人脸,才能根据人脸判断这个人到底是谁。

人脸检测

当我们预测的是离散值时,进行的是“分类”。例如,预测一个孩子能否成为一名优秀的运动员,其实就是看他是被划分为“好苗子”还是“普通孩子”的分类。对于只涉及两个类别的“二分类”任务,我们通常将其中一个类称为“正类”(正样本),另一个类称为“负类”(反类、负样本)。

例如,在人脸检测中,主要任务是构造能够区分包含人脸实例和不包含人脸实例的分类器。这些实例被称为“正类”(包含人脸图像)和“负类”(不包含人脸图像)。

本节介绍分类器的基本构造方法,以及如何调用OpenCV中训练好的分类器实现人脸检测。

基本原理

OpenCV 提供了三种不同的训练好的级联分类器,下面简单介绍其中涉及的一些概念。

  1. 级联分类器
    通常情况下,分类器需要对多个图像特征进行识别。例如,识别一个动物到底是狗(正类)还是其他动物(负类),我们可能需要根据多个条件进行判断,这样比较下来是非常烦琐的。
    但是,如果首先就比较它们有几条腿:
  • 有“四条腿”的动物被判断为“可能为狗”,并对此范围内的对象继续进行分析和判断。
  • 没有“四条腿”的动物直接被否决,即不可能为狗。

这样,仅仅比较腿的数目,根据这个特征就能排除样本集中大量的负类(例如鸡、鸭、鹅等不是狗的其他动物实例)。级联分类器就是基于这种思路,将多个简单的分类器按照一定的顺序级联而成的。

级联分类器的基本原理如图 23-1 所示。

在这里插入图片描述
级联分类器的优势是,在开始阶段仅进行非常简单的判断,就能够排除明显不符合要求的实例。在开始阶段被排除的负类,不再参与后续分类,这样能极大地提高后面分类的速度。这有点像我们经常收到的骗子短信,大多数人通常一眼就能识别出这些短信是骗人的,也不可能上当受骗。骗子们随机大量发送大多数人明显不会上当受骗的短信,这种做法虽然看起来非常蠢,但总还是会有人上当。这些短信,在最开始的阶段经过简单的筛选过滤就能够将完全不可能上当的人排除在外。不回复短信的人,是不可能上当的;而回复短信的人,才是目标人群。

这样,骗子轻易地就识别并找到了目标人群,能够更专注地“服务”于他们的“最终目标人群”(不断地进行短信互动),从而有效地避免了与“非目标人群”(不回复短信的人群)发生进一
步的接触而“浪费”时间和精力。

OpenCV 提供了用于训练级联分类器的工具,也提供了训练好的用于人脸定位的级联分类器,都可以作为现成的资源使用。

  1. Haar级联分类器
    OpenCV 提供了已经训练好的 Haar 级联分类器用于人脸定位。Haar 级联分类器的实现,经过了以下漫长的历史:
  • 首先,有学者提出了使用 Haar 特征用于人脸检测,但是此时 Haar 特征的运算量超级大,这个方案并不实用。

  • 接下来,有学者提出了简化 Haar 特征的方法,让使用 Haar 特征检测人脸的运算变得简单易行,同时提出了使用级联分类器提高分类效率。

  • 后来,又有学者提出用于改进 Haar 的类 Haar 方案,为人脸定义了更多特征,进一步提高了人脸检测的效率。

下面用一个简单的例子来叙述上述方案。假设有两幅 4×4 大小的图像,如图 23-2 所示。

针对这两幅图像,我们可以通过简单的计算来判断它们在左右关系这个维度是否具有相关性。

在这里插入图片描述
’用两幅图像左侧像素值之和减去右侧像素值之和:

  • 针对左图,sum(左侧像素) - sum(右侧像素) = (128+96) - (108+76) = 40
  • 针对右图,sum(左侧像素) - sum(右侧像素) = (47+88) - (27+68) = 40

这两幅图像中,“左侧像素值之和”减去“右侧像素值之和”都是 40。所以,可以认为在“左侧像素值之和”减去“右侧像素值之和”这个角度,这两幅图像具有一定的相关性

进一步扩展,我们可以从更多的角度考虑图像的特征。学者 Papageorgiou 等人提出了如图23-3 所示的 Haar 特征,这些特征包含垂直特征、水平特征和对角特征。他们利用这些特征分
别实现了行人检测(Pedestrian Detection Using Wavelet Templates)和人脸检测(A GeneralFramework For Object Detection)。

在这里插入图片描述

Haar 特征反映的是图像的灰度变化,它将像素划分为模块后求差值。Haar 特征用黑白两种矩形框组合成特征模板,在特征模板内,用白色矩形像素块的像素和减去黑色矩形像素块的像素和来表示该模板的特征。

经过上述处理后,人脸部的一些特征就可以使用矩形框的差值简单地表示了。比如,眼睛的颜色比脸颊的颜色要深,鼻梁两侧的颜色比鼻梁的颜色深,唇部的颜色比唇部周围的颜色深。

关于 Harr 特征中的矩形框,有如下 3 个变量。

  • 矩形位置:矩形框要逐像素地划过(遍历)整个图像获取每个位置的差值。
  • 矩形大小:矩形的大小可以根据需要做任意调整。
  • 矩形类型:包含垂直、水平、对角等不同类型。

上述 3 个变量保证了能够细致全面地获取图像的特征信息。但是,变量的个数越多,特征的数量也会越多。

例如,仅一个 24×24 大小的检测窗口内的特征数量就接近 20 万个。由于计算量过大,该方案并不实用,除非有人提出能够简化特征的方案。

后来,Viola 和 Jones 两位学者在论文 Rapid Object Detection Using A Boosted Cascade OfSimple Features 和 Robust Real-time Face Detection 中提出了使用积分图像快速计算 Haar 特征的方法。他们提出通过构造“积分图(Integral Image)”,让 Haar 特征能够通过查表法和有限次简单运算快速获取,极大地减少了运算量。同时,在这两篇文章中,他们提出了通过构造级联分类器让不符合条件的背景图像(负样本)被快速地抛弃,从而能够将算力运用在可能包含人脸的对象上。

为了进一步提高效率,Lienhart 和 Maydt 两位学者,在论文 An Extended Set Of Haar-LikeFeatures For Rapid Object Detection 中提出对 Haar 特征库进行扩展。他们将 Haar 特征进一步划分为如图 23-4 所示的 4 类:

  • 4 个边特征。
  • 8 个线特征。
  • 2 个中心点特征。
  • 1 个对角特征。

在这里插入图片描述
Lienhart 和 Maydt 两位学者认为在实际使用中,对角特征(见图 23-4 底部)和线特征中的“e”和“g”(见图 23-4 的第 2 行,(e)图和(g)图)是相近的,因此通常情况下无须重复计算。
同时,该论文还给出了计算 Haar 特征数的方法、快速计算方法,以及级联分类器的构造方法等内容。

OpenCV 在上述研究的基础上,实现了将 Haar 级联分类器用于人脸部特征的定位。我们可以直接调用 OpenCV 自带的 Haar 级联特征分类器来实现人脸定位。

级联分类器的使用

在 OpenCV
1.边特征
2.线特征
3.中心点特征
4.对角特征中,有一些训练好的级联分类器供用户使用。这些分类器可以用来检测人脸、脸部特征(眼睛、
鼻子)、人类和其他物体。这些级联分类器以 XML 文件的形式存放在 OpenCV 源文件的 data 目录下,加载不同级联分类器的 XML 文件就可以实现对不同对象的检测。

下载地址

https://github.com/opencv/opencv/tree/4.x/data/haarcascades

OpenCV 自带的级联分类器存储在 OpenCV 根文件夹的 data 文件夹下。该文件夹包含三个子文件夹:haarcascades、hogcascades、lbpcascades,里面分别存储的是 Harr 级联分类器、HOG级联分类器、LBP 级联分类器。
其中,Harr 级联分类器多达 20 多种(随着版本更新还会继续增加),提供了对多种对象的检测功能。部分级联分类器如表 23-1 所示。

在这里插入图片描述

加载级联分类器的语法格式为:

<CascadeClassifier object> = cv2.CascadeClassifier( filename )

式中,filename 是分类器的路径和名称。
下面的代码是一个调用实例:

faceCascade =
cv2.CascadeClassifier(‘haarcascade_frontalface_default.xml’)

使用级联分类器时需要注意:如果你是通过在anaconda中使用pip的方式安装的OpenCV,则无法直接获取级联分类器的 XML 文件。可以通过以下两种方式获取需要的级联分类器 XML
文件:

  • 安装 OpenCV 后,在其安装目录下的 data 文件夹内查找 XML 文件。
  • 直接在网络上找到相应 XML 文件,下载并使用。

同样,如果使用 opencv_createsamples.exe 和 opencv_traincascade.exe,也需要采用上述方式获取 XML 文件。

cv2.CascadeClassifier.detectMultiScale() 函数介绍

在 OpenCV 中,人脸检测使用的是 cv2.CascadeClassifier.detectMultiScale()函数,它可以检
测出图片中所有的人脸。该函数由分类器对象调用,其语法格式为:

objects = cv2.CascadeClassifier.detectMultiScale( image[,
scaleFactor[, minNeighbors[, flags[, minSize[, maxSize]]]]] )

式中各个参数及返回值的含义为:

  • image:待检测图像,通常为灰度图像。
  • scaleFactor:表示在前后两次相继的扫描中,搜索窗口的缩放比例。
  • minNeighbors:表示构成检测目标的相邻矩形的最小个数。默认情况下,该值为 3,意味着有 3 个以上的检测标记存在时,才认为人脸存在。如果希望提高检测的准确率,可以将该值设置得更大,但同时可能会让一些人脸无法被检测到。
  • flags:该参数通常被省略。在使用低版本 OpenCV(OpenCV 1.X 版本)时,它可能会被设置为 CV_HAAR_DO_CANNY_PRUNING,表示使用 Canny 边缘检测器来拒绝一些区域。
  • minSize:目标的最小尺寸,小于这个尺寸的目标将被忽略。
  • maxSize:目标的最大尺寸,大于这个尺寸的目标将被忽略。
  • objects:返回值,目标对象的矩形框向量组。

示例:使用函数 cv2.CascadeClassifier.detectMultiScale()检测一幅图像内的人脸

原图:

在这里插入图片描述

import cv2
# 读取待检测的图像
image = cv2.imread('face\\face3.jpg')
# 获取 XML 文件,加载人脸检测器
faceCascade = cv2.CascadeClassifier('haarcascade_frontalface_default.xml')
# 色彩转换,转换为灰度图像
gray = cv2.cvtColor(image,cv2.COLOR_BGR2GRAY)
# 调用函数 detectMultiScale
faces = faceCascade.detectMultiScale(
 gray,
 scaleFactor = 1.15,
 minNeighbors = 5,
 minSize = (5,5)
)
print(faces)
# 打印输出的测试结果
print("发现{0}个人脸!".format(len(faces)))
# 逐个标注人脸
for(x,y,w,h) in faces:
  cv2.rectangle(image,(x,y),(x+w,y+w),(0,255,0),2) #矩形标注
# 显示结果
cv2.imshow("dect",image)
# 保存检测结果
cv2.imwrite("re.jpg",image)
cv2.waitKey(0)

运行结果:
在这里插入图片描述

同时,在控制台会显示检测到的人脸的具体位置信息及个数,具体结果如下:

[[129 59 61 61]
[ 35 76 62 62]
[565 65 61 61]
[443 62 71 71]
[290 13 77 77]]
发现 5 个人脸!

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

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

相关文章

分享一个可以录制限制录屏的方法

随着智能手机的普及&#xff0c;录屏已经成为了很多人记录生活的重要方式。然而&#xff0c;在使用录屏应用时&#xff0c;我们可能会遇到一些限制&#xff0c;例如无法录制某些应用程序的屏幕。下面将介绍一些方法&#xff0c;帮助你在这种情况下仍然能够轻松地录制屏幕。 使用…

3D数据转换工具HOOPS Exchange概览

HOOPS Exchange SDK是一组C软件库&#xff0c;使开发团队能够快速为其应用程序添加可靠的2D和3D CAD导入和导出功能。这允许访问广泛的数据&#xff0c;包括边界表示&#xff08;BREP&#xff09;、产品制造信息&#xff08;PMI&#xff09;、模型树、视图、持久ID、样式、构造…

亚马逊无限买家号如何注册?

如果想要拥有大批量的亚马逊买家号&#xff0c;可以使用亚马逊鲲鹏系统进行自动注册操作。在注册之前我们需要先准备好账号所需要的资料&#xff1b; 1、Ip&#xff1a;软件系统支持11个亚马逊站点使用&#xff0c;因此注册哪一个国家的买家号时就需要购买相应国家的ip&#x…

React请求机制优化思路 | 京东云技术团队

说起数据加载的机制&#xff0c;有一个绕不开的话题就是前端性能&#xff0c;很多电商门户的首页其实都会做一些垂直的定制优化&#xff0c;比如让请求在页面最早加载&#xff0c;或者在前一个页面就进行预加载等等。随着react18的发布&#xff0c;请求机制这一块也是被不断谈起…

docker部署springboot应用

一、下载安装docker curl -fsSL https://get.docker.com | bash -s docker --mirror Aliyun 启动&#xff1a;systemctl start docker 二、配置国内镜像源 &#xff08;1&#xff09;在/etc/docker目录中添加daemon.json文件&#xff0c;内容如下&#xff1a; { …

花生十三 判断推理(二)论证类(归因论证、一般质疑、比例类论证、解释说明类、支持与前提假设、易错选项

论证类 归因论证 形式&#xff1a;既成事实 原因分析 &#xff08;有些题目省略原因分析&#xff09; 题型 对比实验 形式&#xff1a; 有完整的对比实验过程&#xff0c;根据结果给出原因分析、结论 解题思路 质疑 另有他图&#xff1a;画图法&#xff0c;需分组正确…

14 anaconda+pycharm环境管理以及源管理

文章目录 环境管理博主使用的环境环境设置conda常用指令pycharm与环境的连接&#xff08;新2023版本后&#xff09;设置国内镜像&#xff08;源管理&#xff09;常用操作 环境管理 博主使用的环境 Anaconda3-2023.03-Windows-x86_64 pycharm-professional-2023.2 环境设置 …

0基础小白,到底怎样成功转行做软件测试?

软件测试的门槛低没错&#xff0c;但如果100个人竞争同一岗位&#xff0c;企业方一定会选择更优秀的那个应聘者&#xff0c;而没有工作经验、0基础的小白只是充当了陪跑的角色。 所以建议转岗做软件测试的小伙伴&#xff0c;一定要提前做好这些准备&#xff1a; 1、了解软件测…

【数据结构】链表常见题目

文章目录 链表合并两个有序链表反转链表复制带随机指针的链表环形链表环形链表II相交链表移除链表元素链表中倒数第k个节点链表分割链表的回文结构链表的中间节点旋转链表链表排序链表求和 (逆序求)链表求和II (正序求)重排链表奇偶链表反转链表II <==> 链表内指定区间反…

C/C++:C/C++在大数据时代的应用,以及C/C++程序员未来的发展路线

目录 1.C/C在大数据时代的应用 1.1&#xff1a;C/C数据处理 1.2&#xff1a;C/C数据库 1.3&#xff1a;C/C图像处理和计算机视觉 1.3.1&#xff1a;导读 2.C/C程序员未来的发展路线 2.1&#xff1a;图导 1.C/C在大数据时代的应用 C/C在大数据时代中仍然是一种被广泛应用的编…

HttpMessageConverter(消息转换器)

文章目录 1. HttpMessageConverter 的概述2. HttpMessageConverter的使用2.1 RequestBody请求体注解2.2 RequestEntity请求封装对象2.3 ResponseBody响应体注解2.4 ResponseEntity响应封装对象 3. 自定义消息转换器3.1 步骤一&#xff1a;自定义消息转化器3.11 FastJson、Gson …

前馈神经网络正则化例子

直接看代码&#xff1a; import torch import numpy as np import random from IPython import display from matplotlib import pyplot as plt import torchvision import torchvision.transforms as transforms mnist_train torchvision.datasets.MNIST(root…

【云原生】kuberneter中Helm入门到实践

引言 helm是k8s的包管理工具&#xff0c;使用helm&#xff0c;可以使用更为简化和系统化的方式对k8s应用进行部署、升级。 helm是CNCF已毕业的项目&#xff0c;社区也是相当活跃的&#xff0c;在 https://artifacthub.io/ 上&#xff0c;能找到很多现成的helm chart&#xff…

轻松学会网络编程

目录 一、UDP 和 TCP 特点对比 1、有连接和无连接 2、可靠传输和不可靠传输 3、面向字节流和面向数据报 4、全双工和半双工 二、UDP 的 socket.api 1、DatagramSocket 2、DatagramPacket 回显服务器的实现 &#xff08;1&#xff09;服务器代码 &#xff08;2&#…

GaussDB数据库SQL系列-子查询

目录 一、前言 二、GaussDB SQL子查询表达式 1、EXISTS/NOT EXISTS 2、IN/NOT IN 3、ANY/SOME 4、ALL 三、GaussDB SQL子查询实验示例 1、创建实验表 2、EXISTS/NOT EXISTS示例 3、IN/NOT IN 示例 4、ANY/SOME 示例 5、ALL示例 四、注意事项及建议 五、小结 一、…

投资不识筹码峰,炒遍A股也枉然? | 如何用python计算筹码分布数据

你听说过股市上著名的丁蟹效应吗&#xff1f; 你知道丁蟹报仇点到为止&#xff0c;丁蟹报恩家破人亡吗&#xff1f; 你又是否曾在微信群中见过这些表情包&#xff1f; 01 大时代 不知道大家有没有看过《大时代》这部剧&#xff0c;看过的欢迎点我头像交流讨论。 剧中逆天强运…

Java:JVM虚拟机的三种模式

在JVM中有三种模式&#xff1a; 混合模式&#xff1a;解释器热点代码编译 编译模式&#xff1a;启动快&#xff0c;执行慢 解释模式&#xff1a;启动慢&#xff0c;执行快 使用 在我们的JVM虚拟机中一般默认的是混合模式 如上所示&#xff0c;我们可以看到后面有mixed&#xf…

【mysql异常】Specified key was too long; max key length is 1000 bytes

最近在创建数据库的时候&#xff0c;报错内容如下所示&#xff1a; Caused by: java.sql.SQLSyntaxErrorException: Specified key was too long; max key length is 1000 bytesat com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:120) ~[mysql-conn…

Vue中实现自动匹配搜索框内容 关键字高亮文字显示

实现效果如下: 1.首先需要给输入框进行双向绑定 2.拿到搜索的结果去渲染页面 将返回的结果和搜索的关键字进行比对 如果相同的 就变红 上代码 html部分 //输入框<div class"search"><div class"shuru"><input type"请输入要查询的…

软件测试报告有哪些测试内容?

软件测试报告可以包含以下测试内容&#xff1a; 1、功能测试&#xff1a;测试软件的基本功能是否实现&#xff0c;是否符合要求。 2、性能测试&#xff1a;测试软件的响应速度、并发能力、稳定性等性能指标。 3、界面测试&#xff1a;测试软件的用户界面是否友好、易于使用。 …