首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> C++ >> 關於C++

C++ 人臉性別識別教程(六):HOG 特徵 + SVM 完整實現

     編輯:關於C++

一、背景與動機

上篇使用 OpenCV FaceRecognizer 快速基線,本文介紹經典 HOG + SVM 管線:HOG 提取梯度方向直方圖特徵,SVM 解決二分類(男/女)。OpenCV 對兩者均有成熟封裝,調用便捷。

二、核心知識點

  • SVM:尋找最優分離超平面,核技巧映射高維空間。OpenCV CvSVM 支持 C_SVC、RBF 核等。
  • HOG:將圖像劃分 Cell,統計梯度方向直方圖,再按 Block 歸一化,具備較強幾何/光照不變性。

三、數據準備

  • CAS-PEAL 數據集:400 男 + 400 女訓練樣本,另備測試集。
  • CSV 索引文件:路徑;標籤(0/1)。

四、關鍵步驟與代碼

1. 批量讀取路徑(節省內存)

void read_csv(const string& csvPath, vector& paths, vector& labels, char sep=';') {
    ifstream f(csvPath);
    string line, path, label;
    while (getline(f, line)) {
        stringstream ss(line);
        getline(ss, path, sep);
        getline(ss, label);
        if (!path.empty() && !label.empty()) {
            paths.push_back(path);
            labels.push_back(stoi(label));
        }
    }
}

2. HOG 特徵提取並構建訓練矩陣

const int NUM_TRAIN = 800;
Mat trainDataHog, trainLabel = Mat::zeros(NUM_TRAIN, 1, CV_32FC1);
HOGDescriptor hog(Size(64,64), Size(16,16), Size(8,8), Size(8,8), 9);

for (int i = 0; i < NUM_TRAIN; ++i) {
    Mat img = imread(paths[i], 1);
    resize(img, img, Size(64,64));
    vector desc;
    hog.compute(img, desc, Size(1,1), Size(0,0));
    if (i == 0) trainDataHog = Mat::zeros(NUM_TRAIN, desc.size(), CV_32FC1);
    for (size_t j = 0; j < desc.size(); ++j)
        trainDataHog.at(i, j) = desc[j];
    trainLabel.at(i, 0) = labels[i];
}

3. SVM 訓練與保存

CvSVM svm;
CvSVMParams params(CvSVM::C_SVC, CvSVM::RBF, 10.0, 0.09, 1.0, 10.0, 0.5, 1.0, NULL,
                   cvTermCriteria(CV_TERMCRIT_EPS, 1000, FLT_EPSILON));
svm.train(trainDataHog, trainLabel, Mat(), Mat(), params);
svm.save("SVM_SEX_Model.txt");

4. 測試預測

Mat test = imread("test_female.bmp", 1);
resize(test, test, Size(64,64));
vector desc; hog.compute(test, desc);
Mat testHog(1, desc.size(), CV_32FC1);
for (size_t j = 0; j < desc.size(); ++j) testHog.at(0, j) = desc[j];
int pred = svm.predict(testHog); // 0/1 對應性別

五、工程經驗總結

  1. 命名規範:匈牙利法 vecTrainPath、matTrainData,類型前綴+語義駝峰,大型項目必備。
  2. 為何要特徵提取:像素直餵 SVM 效果差,SVM 無自動特徵學習能力;HOG、深度特徵均為顯式表達語義信息。
  3. vector vs 陣列:vector 動態擴容、RAII、迭代器遍歷,優於手動 new[]。
  4. OpenCV 類型別名:cv::String/cv::Vector 等為 STL 別名,勿混淆。

六、完整工程代碼

見正文 GenderSVM.cpp,含讀取、訓練、保存、測試全流程,可直接編譯運行(需配置 OpenCV 環境)。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved