接續前文,將訓練好的 PCA、Fisher、LBP、SVM 四種性別分類器集成到 MFC 應用中,實現下拉選單切換、離線模型加載、實時識別顯示。
訓練耗時約 5 分鐘,採用離線訓練、在線加載模式。生成模型文件:
PCA_Model.xmlFisher_Model.xmlLBP_Model.xmlSVM_SEX_Model.txt(含 HOG 特徵參數)IDC_COMBO_FUNCTIONOnInitDialog 初始化選項:
((CComboBox*)GetDlgItem(IDC_COMBO_FUNCTION))->AddString(_T("PCA變換"));
((CComboBox*)GetDlgItem(IDC_COMBO_FUNCTION))->AddString(_T("Fisher變換"));
((CComboBox*)GetDlgItem(IDC_COMBO_FUNCTION))->AddString(_T("LBP變換"));
((CComboBox*)GetDlgItem(IDC_COMBO_FUNCTION))->AddString(_T("支持向量機"));
((CComboBox*)GetDlgItem(IDC_COMBO_FUNCTION))->SetCurSel(1); // 默認 Fisher
屬性設置:取消 Sort、調整 Drop Down 高度 顯示所有選項。
在 GenderRecognitionMFCDlg.cpp 頂部:
static Ptr model_PCA = createEigenFaceRecognizer();
static Ptr model_Fisher = createFisherFaceRecognizer();
static Ptr model_LBP = createLBPHFaceRecognizer();
static CvSVM svm;
void CGenderRecognitionMFCDlg::OnBnClickedButtonInitial() {
// ... 人臉檢測器加載代碼 ...
int index = ((CComboBox*)GetDlgItem(IDC_COMBO_FUNCTION))->GetCurSel();
switch (index) {
case 0: model_PCA->load(modelPath + "PCA_Model.xml"); break;
case 1: model_Fisher->load(modelPath + "Fisher_Model.xml"); break;
case 2: model_LBP->load(modelPath + "LBP_Model.xml"); break;
case 3: svm.load(modelPath + "SVM_SEX_Model.txt"); break;
}
MessageBox(_T("初始化完成")); // 加載耗時 ~5秒,提示友好
}
void CGenderRecognitionMFCDlg::GenderRecognition(IplImage* img) {
Mat image(img);
resize(image, image, Size(92, 112)); // 統一歸一化尺寸
int index = ((CComboBox*)GetDlgItem(IDC_COMBO_FUNCTION))->GetCurSel();
switch (index) {
case 0: m_genderLabel = model_PCA->predict(image); break;
case 1: m_genderLabel = model_Fisher->predict(image); break;
case 2: m_genderLabel = model_LBP->predict(image); break;
case 3: {
Mat trainImg;
resize(image, trainImg, Size(64, 64));
HOGDescriptor hog(Size(64,64), Size(16,16), Size(8,8), Size(8,8), 9);
vector descriptors;
hog.compute(trainImg, descriptors);
Mat svmMat(1, descriptors.size(), CV_32FC1);
for (size_t i = 0; i < descriptors.size(); ++i)
svmMat.at(0, i) = descriptors[i];
m_genderLabel = svm.predict(svmMat);
break;
}
}
// 顯示結果
GetDlgItem(IDC_EDIT_RESULT)->SetWindowText(
m_genderLabel == 1 ? _T("帥哥") : _T("美女")
);
}
在 detect_and_draw 中,檢測到人臉後:
cvSetImageROI 設置人臉區域faceImage,彩色圖 cvCvtColor 灰度化(自動複製 ROI),灰度圖 cvCopy 深拷貝 ROI(避免淺拷貝 BUG,見教程 14)GenderRecognition(faceImage)cvReleaseImage 釋放下一教程將引入攝像頭視頻流實時性別識別。