在前幾篇文章中,我們已經完成了針對靜態圖片的人臉性別識別功能。本篇將引入攝像頭設備,為程序添加第二大核心功能:即時視頻人臉性別識別。
為了實現視頻識別,需要新增兩個控件:「打開視頻」按鈕(ID 為 IDC_OpenVideo)與「暫停」按鈕。為了避免主窗口按鈕過多,採用控件復用策略:將視頻模式下的「暫停」功能與圖片文件夾識別模式下的「下一張」功能合併,由同一按鈕根據當前模式切換行為。

CVideoInfo在類視圖中右鍵專案名稱 → Add Class → 選擇 C++ Class,命名為 CVideoInfo,無繼承關係,存取屬性預設為 public。完成後解決方案資源管理器會出現 VideoInfo.h 與 VideoInfo.cpp。

CVideoInfo 封裝攝像頭視頻流、當前幀影像、幀寬高,便於後續統一管理與擴充。
VideoInfo.h
#pragma once
#include "opencv2/opencv.hpp"
class CVideoInfo {
public:
CvCapture* m_pCapture; // 攝像頭輸入視頻流
IplImage* m_pFrameImage; // 當前幀影像
int m_FrameWidth; // 幀寬度
int m_FrameHeight; // 幀高度
public:
CVideoInfo(void); // 預設建構函式
~CVideoInfo(void); // 預設解構函式
};
VideoInfo.cpp
#include "StdAfx.h"
#include "VideoInfo.h"
CVideoInfo::CVideoInfo(void) {
m_pCapture = NULL;
m_pFrameImage = NULL;
}
CVideoInfo::~CVideoInfo(void) {
// 暫時使用預設解構,後續可加入資源釋放邏輯
}
在主對話框類 CGenderRecognitionMFCDlg 中新增成員變數 CVideoInfo* m_pVideoInfo,並先在 CGenderRecognitionMFCDlg.h 包含 VideoInfo.h。

雙擊「打開視頻」按鈕產生事件處理函數 OnBnClickedButton1Video()。

先檢查分類器是否已初始化:
if (m_boolInitOK == FALSE) {
MessageBox(_T("請先進行初始化"));
return;
}
呼叫 OpenCV cvCreateCameraCapture(0) 開啟預設攝像頭,並將回傳的 CvCapture* 指派給 m_pVideoInfo->m_pCapture。
m_pVideoInfo->m_pCapture = cvCreateCameraCapture(0); // 建立攝像頭捕捉物件
注意: 此時直接執行會報錯,因為 m_pVideoInfo 尚未配置記憶體。需在 OnInitDialog() 中以 new 配置:
/********* 為 m_pVideoInfo 配置記憶體 *********/ m_pVideoInfo = new CVideoInfo;
採用 定時器 輪詢幀畫面。在「打開視頻」按鈕處理函數中啟動定時器:
SetTimer(1, 1, NULL); // 間隔 1 毫秒觸發,回調中繪製幀畫面
在類視圖中為 CGenderRecognitionMFCDlg 新增 WM_TIMER 訊息對應函數 OnTimer():

OnTimer() 實作:
void CGenderRecognitionMFCDlg::OnTimer(UINT_PTR nIDEvent) {
// 取得下一幀
m_pVideoInfo->m_pFrameImage = cvQueryFrame(m_pVideoInfo->m_pCapture);
// 將 IplImage 繪製到 Picture Control 的 HDC
CvvImage cvvImage;
cvvImage.CopyOf(m_pVideoInfo->m_pFrameImage);
cvvImage.DrawToHDC(m_pPicCtlHdc, m_PicCtlRect);
CDialogEx::OnTimer(nIDEvent);
}
執行程式,Picture Control 即可即時顯示攝像頭畫面。下一篇將介紹如何在視頻流中加入性別識別邏輯。

CvCapture*,但隨功能增加(如幀屬性查詢、前處理),以類別封裝可集中管理、避免主框架程式碼膨脹。private,提供 public 存取函式,符合封裝原則。SetTimer/OnTimer 文件。