- 操作系统:ubuntu22.04
- OpenCV版本:OpenCV4.9
- IDE:Visual Studio Code
- 编程语言:C++11
算法描述
cv::FaceDetectorYN 是 OpenCV 中用于人脸检测的一个类,它基于深度学习模型实现。这个类是 OpenCV DNN(Deep Neural Network module)模块的一部分,利用预先训练好的深度神经网络模型来执行高效的人脸检测任务。
主要特性
- 高效的检测:FaceDetectorYN 使用了 Yunet 模型,这是一个轻量级且高效的卷积神经网络(CNN),专门设计用于快速准确地在图像或视频帧中检测人脸 1。
- 支持多种输入格式:可以处理静态图像、视频流以及实时摄像头输入。
- 可配置性:允许用户调整置信度阈值、非极大值抑制(NMS)阈值等参数,以适应不同的应用场景5。
- 硬件加速支持:可以通过选择不同的后端和目标设备(如 CPU、GPU 或 NPU)来加速推理过程
成员函数介绍
- create:创建一个 FaceDetectorYN 对象。
- model, config: 分别是模型文件路径和配置文件路径。对于大多数预训练模型,仅需提供模型文件路径即可。
- input_size: 输入图像的尺寸(宽度, 高度)。这通常与模型训练时使用的输入尺寸相匹配。
- score_threshold: 置信度阈值,低于此分数的人脸将被忽略,默认值为0.9。
- nms_threshold: 非极大值抑制(NMS)阈值,用于去除重叠的人脸框,默认值为0.3。
- top_k: 保留的最高得分边界框数量,默认值为5000。
- setInputSize:设置输入图像的尺寸。
- width, height: 输入图像的宽度和高度。
- detect:执行人脸检测,并返回检测到的人脸信息。
- image: 要检测的图像。
- faces: 输出参数,包含检测到的所有人脸的位置信息和其他相关数据。具体的数据结构取决于实现细节,但通常每个条目会包含一个人脸的位置(如边界框)、置信度分数以及其他可能的关键点位置。
- setScoreThreshold:设置置信度分数阈值。
- threshold: 新的置信度分数阈值。
- setNMSThreshold:设置非极大值抑制(NMS)阈值。
- threshold: 新的NMS阈值。
- setTopK:设置保留的最高得分边界框数量。
- k: 新的最大边界框数量。
- setPreferableBackend:设置首选的DNN后端。
- backend: 后端标识符,例如 cv::dnn::DNN_BACKEND_OPENCV 或 cv::dnn::DNN_BACKEND_CUDA。
- setPreferableTarget:设置首选的目标设备。
- target: 目标设备标识符,例如 cv::dnn::DNN_TARGET_CPU 或 cv::dnn::DNN_TARGET_CUDA。
代码示例
#include <iostream>
#include <opencv2/dnn.hpp>
#include <opencv2/opencv.hpp>
int main()
{
// 模型文件路径
std::string model_path = "face_detection_yunet_2023mar.onnx";
// 创建 FaceDetectorYN 对象
cv::Ptr< cv::FaceDetectorYN > detector = cv::FaceDetectorYN::create( model_path, "", cv::Size( 320, 320 ), // 输入尺寸,可以根据实际情况调整
0.9f, // 置信度阈值
0.3f, // NMS 阈值
5000 // top_k 参数
);
// 加载测试图像
cv::Mat img = cv::imread( "/media/dingxin/data/study/OpenCV/sources/images/zhou.png" );
if ( img.empty() )
{
std::cerr << "无法读取图像" << std::endl;
return -1;
}
// 设置输入尺寸为图像的实际尺寸
detector->setInputSize( img.size() );
// 进行人脸检测
cv::Mat faces;
detector->detect( img, faces );
// 绘制检测到的人脸框和关键点
for ( int i = 0; i < faces.rows; ++i )
{
float x = faces.at< float >( i, 0 );
float y = faces.at< float >( i, 1 );
float w = faces.at< float >( i, 2 );
float h = faces.at< float >( i, 3 );
float score = faces.at< float >( i, 14 ); // 分数
// 绘制人脸框
cv::rectangle( img, cv::Point( x, y ), cv::Point( x + w, y + h ), cv::Scalar( 0, 255, 0 ), 2 );
// 打印分数
std::cout << "Face " << i << ": Score = " << score << std::endl;
cv::putText( img, "Face " +std::to_string( i )+": Score =" + std::to_string( score ), cv::Point( x, y - 10 ), cv::FONT_HERSHEY_SIMPLEX, 0.6, cv::Scalar( 0, 255, 0 ), 1 );
// 绘制人脸关键点(如果有的话)
for ( int j = 4; j <= 13; j += 2 )
{
int keypoint_x = static_cast< int >( faces.at< float >( i, j ) );
int keypoint_y = static_cast< int >( faces.at< float >( i, j + 1 ) );
cv::circle( img, cv::Point( keypoint_x, keypoint_y ), 3, cv::Scalar( 0, 0, 255 ), -1 );
}
}
// 显示结果图像
cv::imshow( "Detected Faces", img );
cv::waitKey( 0 );
return 0;
}