專案已推進 30 天,本文實作兩個輔助工能:圖片批量重命名 與 分類方法準確率驗證,為後續總結做準備。
核心流程:遍歷讀取 → 產生新檔名 → 另存覆蓋。邏輯與上篇「人臉批量分割」幾乎相同,此處略過 UI 綁定細節,僅給出關鍵代碼片段:
// 1. 選擇資料夾 (SHBrowseForFolder)
BROWSEINFO bi = {0};
bi.hwndOwner = GetSafeHwnd();
bi.lpszTitle = _T("選擇圖片資料夾");
LPITEMIDLIST idl = SHBrowseForFolder(&bi);
if (!idl) return;
TCHAR path[MAX_PATH];
SHGetPathFromIDList(idl, path);
// 2. 遍歷並重命名
CString dir(path);
if (dir.Right(1) != _T("\\")) dir += _T("\\");
DIR* dp = opendir(dir);
dirent* ep;
int counter = 0;
while ((ep = readdir(dp))) {
if (ep->d_name[0] == '.') continue; // 跳過 . ..
CString oldName = dir + ep->d_name;
CString ext = PathFindExtension(oldName);
CString newName;
newName.Format(_T("%simg_%04d%s"), dir, counter++, ext);
MoveFile(oldName, newName); // 或 CopyFile + DeleteFile
}
closedir(dp);
IDC_Effect_Man(男性準確率)、IDC_Effect_Wom(女性準確率)檔名包含 man 視為男性樣本,包含 women 視為女性樣本。例如:man_001.jpg, women_002.bmp。
void CGenderRecognitionMFCDlg::OnBnClickedButtonVerify() {
// 選資料夾(同上)
// ...
float totalMan = 0, totalWomen = 0;
float correctMan = 0, correctWomen = 0;
while ((ep = readdir(dp))) {
if (!isImage(ep->d_name)) continue;
CString full = dir + ep->d_name;
IplImage* img = cvLoadImage(full);
detect_and_draw(img); // 內部設定 m_genderLabel (1=男, 2=女)
// 真實標籤
bool isManGT = (strstr(ep->d_name, "man") != nullptr);
bool isWomenGT = (strstr(ep->d_name, "women") != nullptr);
if (isManGT) totalMan++;
if (isWomenGT) totalWomen++;
// 預測結果
if (m_genderLabel == 1) correctMan++;
else if (m_genderLabel == 2) correctWomen++;
cvReleaseImage(&img);
}
// 顯示準確率(百分比整數)
char buf[16];
if (totalMan > totalWomen) { // 假設測試集以男性為主
int acc = (int)(correctMan / totalMan * 100);
_itoa_s(acc, buf, 10);
GetDlgItem(IDC_Effect_Man)->SetWindowTextA(buf);
} else {
int acc = (int)(correctWomen / totalWomen * 100);
_itoa_s(acc, buf, 10);
GetDlgItem(IDC_Effect_Wom)->SetWindowTextA(buf);
}
}
detect_and_draw 未檢測到人臉,m_genderLabel 可能保持舊值,導致統計偏差。三種修復:
\\,SHBrowseForFolder 返回 PIDL 需 SHGetPathFromIDList 轉換,記得 IMalloc::Free 釋放 PIDL。CString 配合 GetBuffer/ReleaseBuffer 最穩妥。剩餘兩篇將完成:完整專案打包部署 與 核心代碼模塊解析總結。