opencv4.5.0 VS2019C++ 怎么把人脸检测的摄像头实时画面显示在picture control控件上面
时间: 2024-02-19 21:00:27 浏览: 152
要将 OpenCV 的人脸检测摄像头实时画面显示在 MFC 的 picture control 控件上,可以遵循以下步骤:
1. 在 MFC 对话框的资源编辑器中添加一个 picture control 控件,设置好控件的属性。
2. 在控制台应用程序的 solution 中,添加 MFC 应用程序项目。
3. 将 OpenCV 的库文件添加到 MFC 应用程序项目中,包括头文件和库文件。
4. 在 MFC 应用程序项目中添加一个 C++ 源代码文件,编写程序代码。
以下是一个简单的示例代码,可以实现将人脸检测的摄像头实时画面显示在 picture control 控件上:
```cpp
// 头文件
#include <opencv2/opencv.hpp>
#include <opencv2/highgui.hpp>
// 控件ID
#define IDC_PIC_FACEDETECT 1001
// CFaceDetectDlg 类
class CFaceDetectDlg : public CDialogEx
{
public:
CFaceDetectDlg(CWnd* pParent = nullptr);
// 对话框数据
#ifdef AFX_DESIGN_TIME
enum { IDD = IDD_FACEDETECT_DIALOG };
#endif
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持
// 实现
protected:
HICON m_hIcon;
CStatic m_picFaceDetect; // 图片控制变量
cv::Mat m_frame; // 图像帧变量
cv::CascadeClassifier m_cascadeClassifier; // 级联分类器
cv::VideoCapture m_videoCapture; // 视频捕获对象
virtual BOOL OnInitDialog();
afx_msg void OnPaint();
afx_msg HCURSOR OnQueryDragIcon();
DECLARE_MESSAGE_MAP()
private:
void LoadCascadeClassifier(); // 加载级联分类器
void DrawFaceRect(cv::Mat& frame, const cv::Rect& faceRect); // 绘制人脸矩形框
void UpdatePictureControl(); // 更新图片控制
public:
afx_msg void OnTimer(UINT_PTR nIDEvent);
};
// CFaceDetectDlg 方法实现
void CFaceDetectDlg::LoadCascadeClassifier()
{
// 加载级联分类器
m_cascadeClassifier.load("haarcascade_frontalface_alt.xml");
}
void CFaceDetectDlg::DrawFaceRect(cv::Mat& frame, const cv::Rect& faceRect)
{
// 绘制矩形框
cv::rectangle(frame, faceRect, cv::Scalar(0, 0, 255), 2, 8, 0);
}
void CFaceDetectDlg::UpdatePictureControl()
{
// 将图像帧显示在图片控制上
CRect rect;
m_picFaceDetect.GetClientRect(&rect);
cv::Mat dst;
cv::resize(m_frame, dst, cv::Size(rect.Width(), rect.Height()));
HDC hdc = ::GetDC(m_picFaceDetect.GetSafeHwnd());
cv::Mat img(cv::Size(rect.Width(), rect.Height()), CV_8UC3, hdc);
cv::cvtColor(dst, img, cv::COLOR_BGR2RGB);
::ReleaseDC(m_picFaceDetect.GetSafeHwnd(), hdc);
m_picFaceDetect.SetBitmapBits(0, img.data);
}
void CFaceDetectDlg::OnTimer(UINT_PTR nIDEvent)
{
// 定时器事件处理
if (nIDEvent == 1)
{
m_videoCapture >> m_frame;
if (m_frame.empty())
{
AfxMessageBox(_T("视频捕获失败!"));
return;
}
// 将图像帧转换成灰度图像
cv::Mat grayFrame;
cv::cvtColor(m_frame, grayFrame, cv::COLOR_BGR2GRAY);
// 检测人脸
std::vector<cv::Rect> faces;
m_cascadeClassifier.detectMultiScale(grayFrame, faces, 1.1, 2, 0 | cv::CASCADE_SCALE_IMAGE, cv::Size(30, 30));
// 绘制人脸矩形框
for (auto& faceRect : faces)
{
DrawFaceRect(m_frame, faceRect);
}
// 更新图片控制
UpdatePictureControl();
}
CDialogEx::OnTimer(nIDEvent);
}
BOOL CFaceDetectDlg::OnInitDialog()
{
CDialogEx::OnInitDialog();
// 设置图标
SetIcon(m_hIcon, TRUE); // 设置大图标
SetIcon(m_hIcon, FALSE); // 设置小图标
// 加载级联分类器
LoadCascadeClassifier();
// 打开摄像头
m_videoCapture.open(0);
if (!m_videoCapture.isOpened())
{
AfxMessageBox(_T("无法打开摄像头!"));
return FALSE;
}
// 启动定时器
SetTimer(1, 50, nullptr);
// 获取图片控制变量
m_picFaceDetect = dynamic_cast<CStatic*>(GetDlgItem(IDC_PIC_FACEDETECT));
return TRUE;
}
void CFaceDetectDlg::OnPaint()
{
if (IsIconic())
{
CPaintDC dc(this); // 用于绘制的设备上下文
SendMessage(WM_ICONERASEBKGND, reinterpret_cast<WPARAM>(dc.GetSafeHdc()), 0);
// 将图标居中绘制
int cxIcon = GetSystemMetrics(SM_CXICON);
int cyIcon = GetSystemMetrics(SM_CYICON);
CRect rect;
GetClientRect(&rect);
int x = (rect.Width() - cxIcon + 1) / 2;
int y = (rect.Height() - cyIcon + 1) / 2;
// 绘制图标
dc.DrawIcon(x, y, m_hIcon);
}
else
{
CDialogEx::OnPaint();
}
}
HCURSOR CFaceDetectDlg::OnQueryDragIcon()
{
return static_cast<HCURSOR>(m_hIcon);
}
void CFaceDetectDlg::DoDataExchange(CDataExchange* pDX)
{
CDialogEx::DoDataExchange(pDX);
DDX_Control(pDX, IDC_PIC_FACEDETECT, m_picFaceDetect);
}
BEGIN_MESSAGE_MAP(CFaceDetectDlg, CDialogEx)
ON_WM_PAINT()
ON_WM_QUERYDRAGICON()
ON_WM_TIMER()
END_MESSAGE_MAP()
// WinMain 函数
// WinMain 函数
int APIENTRY _tWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPTSTR lpCmdLine, int nCmdShow)
{
UNREFERENCED_PARAMETER(hPrevInstance);
UNREFERENCED_PARAMETER(lpCmdLine);
// 初始化 MFC 库
AfxWinInit(hInstance, nullptr, ::GetCommandLine(), 0);
// 创建对话框
CFaceDetectDlg dlg;
dlg.DoModal();
return 0;
}
```
在上述代码中,通过定时器事件处理函数 OnTimer() 捕获摄像头的实时视频帧,通过 OpenCV 的级联分类器检测人脸区域,并绘制人脸矩形框,最后将图像帧显示在 picture control 控件上。请注意,示例代码中使用的级联分类器文件 haarcascade_frontalface_alt.xml 应该事先下载并存储在工程目录下。
阅读全文
相关推荐
![rar](https://img-home.csdnimg.cn/images/20241231044955.png)
![7z](https://img-home.csdnimg.cn/images/20241231044736.png)
![rar](https://img-home.csdnimg.cn/images/20241231044955.png)
![rar](https://img-home.csdnimg.cn/images/20241231044955.png)
![zip](https://img-home.csdnimg.cn/images/20241231045053.png)
![zip](https://img-home.csdnimg.cn/images/20241231045053.png)
![rar](https://img-home.csdnimg.cn/images/20241231044955.png)
![pdf](https://img-home.csdnimg.cn/images/20241231044930.png)
![zip](https://img-home.csdnimg.cn/images/20241231045053.png)
![rar](https://img-home.csdnimg.cn/images/20241231044955.png)
![zip](https://img-home.csdnimg.cn/images/20241231045053.png)
![zip](https://img-home.csdnimg.cn/images/20241231045053.png)
![rar](https://img-home.csdnimg.cn/images/20241231044955.png)
![zip](https://img-home.csdnimg.cn/images/20241231045053.png)
![zip](https://img-home.csdnimg.cn/images/20241231045053.png)