人工智能实验:人脸检测

一、实现目的:

  1. 了解人脸检测的主要方法;
  2. 了解 detectMultiScale 函数的功能及用法;
  3. 掌握使用 OpenCV 提供的分类器和检测器进行人脸检测的方法。

二、实验设备:

  1. 计算机一台;
  2. 视觉实验软件环境及资源一套(visual studio 2022,opencv-4.8)。

环境配置请参考以下文章:

  1. http://t.csdnimg.cn/ku3rS
  2. http://t.csdnimg.cn/owEsG
  3. http://t.csdnimg.cn/vEe72

三、实验原理:

人脸检测(Face Detection),就是给一幅图像,找出图像中的所有人脸位置, 通常用一个矩形框框起来,如下图所示。其输入是一幅图像 image,输出是若 干个包含人脸的矩形框位置(x,y,w,h)。人脸检测属于计算机视觉的范畴,早期人 们的主要研究方向是人脸识别,即根据人脸来识别人物的身份,后来在复杂背景 下的人脸检测需求越来越大,人脸检测也逐渐作为一个单独的研究方向发展起来。 目前人脸检测的方法主要有以下两大类。

287b39fd3705482f9a25f6881eb784d5.png

基于知识的方法:主要利用先验知识将人脸看作器官特征的组合,根据眼睛、 眉毛、嘴巴、鼻子等器官的特征以及相互之间的几何位置关系来检测人脸。主要 包括模板匹配、人脸特征、形状与边缘、纹理特性、颜色特征等方法。

基于统计的方法:将人脸看作一个整体的模式——二维像素矩阵,从统计的 观点通过大量人脸图像样本构造人脸模式空间,根据相似度来判断人脸是否存在。 主要包括主成分分析与特征脸、神经网络方法、支持向量机、隐马尔可夫模型、 Adaboost 算法等。

本次实验将使用Haar+AdaBoost 的算法,实现任意图像中人脸的检测。OpenCV 自带了训练器和检测器,还包含了人脸检测的 XML 文件, 如下图所示。这些文件位于:

D:\software\other\opencv\build\etc\haarcascades
# 其中:D:\software\other是我自己的安装目录

文件夹, 主要保存相关的特征矩阵,以及各个弱分类器相关的信息,可用于检测静止图像、 视频和摄像头所得到图像中的人脸。除此之外还有一个同级文件夹是 lbpcascades, 它不是通过 Haar 特征进行人脸检测,而是采用的 LBP 特征,这里仅作了解,不再细究。

d97716a0f9b14081b62c8220cbed1d37.png

四、算法接口:

CascadeClassifier 是 OpenCV 中用来做目标检测的级联分类器的一个类。早期 OpenCV 版本仅支持 Haar 特征的目标检测,新版本开始支持 LBP 和 HOG 特 征的目标检测。CascadeClassifier 类有一个 detectMultiScale 的成员函数用于调整检测参数,检测目标图像并得到检测结果。

void detectMultiScale( InputArray image,
 std::vector<Rect>& objects,
 double scaleFactor = 1.1, 
 int minNeighbors = 3,
 int flags = 0,
 Size minSize = Size(), Size maxSize = Size());

【image】:输入图像。

【objects】:检测到的目标的矩形框向量组。

【scaleFactor】:在前后两次相继的扫描中搜索窗口的比例系数。默认为 1.1,即每次搜索    窗口依次扩大 10%。

【minNeighbors】:每个目标至少要被检测到不低于该值的次数才算是真的目标。

【flags】:旧版本的 OpenCV 1.x 使用的参数,当前版本已被忽略。

【minSize 和 maxSize】:限制检测到的目标尺寸。

五、实验任务:

1 基础任务:

  1. 搭建实验环境;
  2. 根据指导书示例完成人脸检测实验;
  3. 完成实验报告。

2 拓展任务:

  1. 调整 minNeighbors 参数的值,观察对人脸检测结果的影响。
  2. 调整 minSize 和 maxSize 参数的值,观察对人脸检测结果的影响。
  3. 修改程序,实现在视频流中进行动态的人脸检测。

六、实验内容:

1 搭建实验环境:

见上述推荐的参考文章。

2 人脸检测示例运行:

2.1 人脸识别:

2.1.1 测试代码:

//人脸检测
#include <vector>
#include <opencv2/opencv.hpp>
int main()
{
	// 创建级联分类器对象,并加载 OpenCV 自带的人脸分类器
	cv::CascadeClassifier faceDetector("D:/software/other/opencv/build/etc/haarcascades/haarcascade_frontalface_alt2.xml");
		cv::Mat image = cv::imread("D:/Projects/visio projects/opencv_test1/test_picture/test1.jpg");
	// 用于储存检测结果的矩形框向量组
	std::vector<cv::Rect> objects;
	// 使用分类器进行目标检测,并设置相关参数
	faceDetector.detectMultiScale(image, objects, 1.1, 3);
	// 在原图上绘制检测得到的矩形框,并显示出来
	for (int i = 0; i < objects.size(); ++i) {
		cv::rectangle(image, objects[i], cv::Scalar(0, 0, 255));
	}
	cv::imshow("face_detection", image);
	cv::waitKey(0);
	return 0;
}

2.1.2 运行结果:

ea8944a32a7f4ffe8053e54daa06fe93.png

注意这里左下角有个柱子被错误的检测为人脸,后面有用。

2.2 猫脸识别:

2.2.1 测试代码:

//猫脸识别
#include <vector>
#include <opencv2/opencv.hpp>
int main()
{
	// 创建级联分类器对象,并加载 OpenCV 自带的猫脸分类器
	cv::CascadeClassifier faceDetector("D:/software/other/opencv/build/etc/haarcascades/haarcascade_frontalcatface.xml");
	cv::Mat image = cv::imread("D:/Projects/visio projects/opencv_test1/test_picture/test3.jpg");
// 用于储存检测结果的矩形框向量组
std::vector<cv::Rect> objects;
// 使用分类器进行目标检测,并设置相关参数
faceDetector.detectMultiScale(image, objects, 1.1, 3);
// 在原图上绘制检测得到的矩形框,并显示出来
for (int i = 0; i < objects.size(); ++i) {
cv::rectangle(image, objects[i], cv::Scalar(0, 255, 0));
}
cv::imshow("cat_face_detection", image);
cv::waitKey(0);
return 0;
		}

2.2.2 运行结果:

c817f56c13c748f2ad9ec806df2378e4.png

3 拓展任务:

(1)调整人脸识别代码中的 minNeighbors 参数的值从3调整为30:

	faceDetector.detectMultiScale(image, objects, 1.1, 30);
974bb592516e44c59e106381f86ff8a4.png

可以观察到,原来被误识别为人脸的柱子的检测框不见了。

 

(2)调整猫脸识别代码中的 minSize 和 maxSize 参数的值:

因为测试代码中没有定义minSize 和 maxSize 参数的值,所以我们加入以下代码:

// 调整 minSize 和 maxSize 参数的值
cv::Size minSize(10, 10); // 设置最小尺寸
cv::Size maxSize(50, 50); // 设置最大尺寸

// 使用分类器进行目标检测,并设置相关参数
faceDetector.detectMultiScale(image, objects, 1.1, 3, 0, minSize, maxSize);

新的完整代码如下:

//猫脸识别
#include <vector>
#include <opencv2/opencv.hpp>
int main()
{
	// 创建级联分类器对象,并加载 OpenCV 自带的猫脸分类器
	cv::CascadeClassifier faceDetector("D:/software/other/opencv/build/etc/haarcascades/haarcascade_frontalcatface.xml");
	cv::Mat image = cv::imread("D:/Projects/visio projects/opencv_test1/test_picture/test3.jpg");
// 用于储存检测结果的矩形框向量组
std::vector<cv::Rect> objects;
// 调整 minSize 和 maxSize 参数的值
cv::Size minSize(10, 10); // 设置最小尺寸
cv::Size maxSize(50, 50); // 设置最大尺寸

// 使用分类器进行目标检测,并设置相关参数
faceDetector.detectMultiScale(image, objects, 1.1, 3, 0, minSize, maxSize);
// 在原图上绘制检测得到的矩形框,并显示出来
for (int i = 0; i < objects.size(); ++i) {
cv::rectangle(image, objects[i], cv::Scalar(0, 255, 0));
}
cv::imshow("cat_face_detection", image);
cv::waitKey(0);
return 0;
		}
3a431888a5294e6f821aa1bdec70dc97.png

可以看到脸大的猫猫都检测不到了

(3)修改程序,实现在视频流中进行动态的人脸检测:

要在视频流中进行动态人脸检测,需要使用 OpenCV 读取实时视频流(例如,从网络摄像头获取的视频)并对每一帧进行人脸检测,代码如下:

#include <opencv2/opencv.hpp>
#include <vector>

int main()
{
    // 创建级联分类器对象,并加载 OpenCV 自带的人脸分类器
    cv::CascadeClassifier faceDetector("D:/software/other/opencv/build/etc/haarcascades/haarcascade_frontalface_alt2.xml");

    // 创建视频捕获对象,从默认摄像头读取视频
    cv::VideoCapture cap(0); // 0 表示默认摄像头

    if (!cap.isOpened()) {
        std::cerr << "Error: Unable to open camera" << std::endl;
        return -1;
    }

    // 循环读取视频流的每一帧
    while (true) {
        cv::Mat frame;
        cap >> frame; // 获取当前帧

        if (frame.empty()) {
            std::cerr << "Error: Empty frame" << std::endl;
            break;
        }

        // 用于储存检测结果的矩形框向量组
        std::vector<cv::Rect> faces;

        // 使用分类器进行人脸检测,调整缩放因子和最小邻近数等参数
        faceDetector.detectMultiScale(frame, faces, 1.1, 3, 0, cv::Size(30, 30));

        // 在帧上绘制检测得到的矩形框
        for (const auto& face : faces) {
            cv::rectangle(frame, face, cv::Scalar(0, 0, 255), 2); // 红色矩形框,线宽为 2
        }

        // 显示带有人脸检测框的当前帧
        cv::imshow("Face Detection", frame);

        // 检查是否按下 'q' 键退出
        if (cv::waitKey(1) == 'q') {
            break;
        }
    }

    cap.release(); // 释放摄像头
    cv::destroyAllWindows(); // 关闭所有 OpenCV 窗口

    return 0;
}

8a39b85f1244425694f65ce4e45d8f7c.jpeg

调用的摄像头检测我自己的大脸

 

  • 26
    点赞
  • 30
    收藏
    觉得还不错? 一键收藏
  • 5
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值