- 操作系統: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;
}