OpenCV 人脸分析------面部关键点检测类cv::face::FacemarkLBF
- 操作系统:ubuntu22.04
- OpenCV版本:OpenCV4.9
- IDE:Visual Studio Code
- 编程语言:C++11
算法描述
使用 Local Binary Features (LBF) 算法进行面部关键点检测(facial landmark detection)。该算法通过级联回归树预测人脸的 68 个关键点,具有较高的精度和速度。
公共成员函数
static Ptr<FacemarkLBF> create(const Params ¶meters = Params())
作用:创建一个 FacemarkLBF 实例。
参数:
parameters: 可选的 LBF 参数配置。
返回值:返回 FacemarkLBF 的智能指针对象。
virtual bool loadModel(const String& filename) override
作用:加载预训练的 LBF 模型文件(.yaml 或 .yml 格式)。
参数:
filename: 模型文件路径。
返回值:成功返回 true,失败返回 false。
注意:模型文件通常是 lbfmodel.yaml。
virtual bool fit(InputArray image, const std::vector<cv::Rect>& faces, CV_OUT std::vector<std::vector<cv::Point2f>>& landmarks) override
作用:对图像中的一张或多张人脸进行面部关键点拟合。
参数:
- image: 输入图像(建议为灰度图)。
- faces: 包含每张人脸的边界框(std::vectorcv::Rect)。
- landmarks: 输出结果,是一个二维向量,每个子向量对应一张人脸的关键点集合。
返回值:成功返回 true,否则 false。
`void setParameters(const Params& parameters)`
作用:设置 LBF 算法的参数。
参数:
- parameters: LBF 参数结构体。
const Params& getParameters() const
作用:获取当前设置的 LBF 参数。
参数结构体 cv::face::FacemarkLBF::Params
这是 FacemarkLBF 的参数结构体,可以自定义以下参数:
成员变量 | 类型 | 默认值 | 含义 |
---|---|---|---|
scale_factor | float | 1.0f | 图像缩放因子,影响检测速度与精度 |
n_landmarks | int | 68 | 关键点数量(通常为 68) |
n_trees | int | 500 | 使用的回归树数量 |
tree_depth | int | 5 | 每棵树的最大深度 |
valid_radius | float | 1.0f | 特征采样半径范围 |
oversampling_ceil | int | 30 | 过采样上限 |
use_eye_centers | bool | false | 是否使用眼睛中心作为初始点 |
示例代码
#include <opencv2/face.hpp>
#include <opencv2/opencv.hpp>using namespace cv;
using namespace cv::face;
using namespace std;int main()
{// 加载 Haar 分类器CascadeClassifier faceCascade( "haarcascade_frontalface_default.xml" );if ( faceCascade.empty() ){cerr << "无法加载 Haar 分类器!" << endl;return -1;}// 创建 FacemarkLBF 实例Ptr< FacemarkLBF > facemark = FacemarkLBF::create();facemark->loadModel( "lbfmodel.yaml" );// 加载图像Mat img = imread( "/media/dingxin/data/study/OpenCV/sources/images/Lenna.png" );if ( img.empty() ){cerr << "图像加载失败!" << endl;return -1;}Mat gray;cvtColor( img, gray, COLOR_BGR2GRAY );// 检测人脸vector< Rect > faces;faceCascade.detectMultiScale( gray, faces, 1.1, 3, 0, Size( 100, 100 ) );if ( faces.empty() ){cout << "未检测到人脸。" << endl;return -1;}// ✅ 改为二维向量存储关键点vector< vector< Point2f > > landmarks;// 拟合关键点if ( facemark->fit( img, faces, landmarks ) ){// 遍历每个人脸的关键点集合并绘制for ( const auto& face_landmarks : landmarks ){for ( const auto& point : face_landmarks ){circle( img, point, 2, Scalar( 0, 255, 0 ), FILLED );}}imshow( "Facial Landmarks", img );waitKey( 0 );}else{cout << "未能拟合面部关键点。" << endl;}return 0;
}