opencv配置详见上一边文章
同样在MFCApplication1Dlg中新增一个按钮
对话框继承于哪个类不重要,反正只用到客户区,因为失误继承于htmldialog
h文件中添加VideoCapture
#include<opencv2\opencv.hpp>
#include<opencv2\highgui.hpp>
using namespace cv;
// CMFCApplication1Dlg 对话框
class CMFCApplication1Dlg : public CDHtmlDialog
{
// 构造
public:
CMFCApplication1Dlg(CWnd* pParent = nullptr); // 标准构造函数
// 对话框数据
#ifdef AFX_DESIGN_TIME
enum { IDD = IDD_MFCAPPLICATION1_DIALOG, IDH = IDR_HTML_MFCAPPLICATION1_DIALOG };
#endif
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV 支持
HRESULT OnButtonOK(IHTMLElement *pElement);
HRESULT OnButtonCancel(IHTMLElement *pElement);
// 实现
protected:
HICON m_hIcon;
VideoCapture capture;
// 生成的消息映射函数
virtual BOOL OnInitDialog();
afx_msg void OnSysCommand(UINT nID, LPARAM lParam);
afx_msg void OnPaint();
afx_msg HCURSOR OnQueryDragIcon();
DECLARE_MESSAGE_MAP()
DECLARE_DHTML_EVENT_MAP()
public:
afx_msg void OnBnClickedButton1();
afx_msg void OnBnClickedButton2();
afx_msg void OnTimer(UINT_PTR nIDEvent);
};
如上重要的是VideoCapture capture;和afx_msg void OnTimer(UINT_PTR nIDEvent);
分别为定义VideoCapture用来处理视频中每一帧,OnTimer用来播放每一帧
cpp文件中加入定时器定时器的响应
BEGIN_MESSAGE_MAP(CMFCApplication1Dlg, CDHtmlDialog)
ON_WM_SYSCOMMAND()
ON_BN_CLICKED(IDC_BUTTON1, &CMFCApplication1Dlg::OnBnClickedButton1)
ON_BN_CLICKED(IDC_BUTTON2, &CMFCApplication1Dlg::OnBnClickedButton2)
ON_WM_TIMER()
END_MESSAGE_MAP()
如上如上重要的是
ON_BN_CLICKED(IDC_BUTTON2, &CMFCApplication1Dlg::OnBnClickedButton2)
ON_WM_TIMER()
用来响应button2的dian点击事件的响应和定时器的响应
cpp文件中继续添加响应函数
int Mat2CImage(Mat *mat, CImage &img) {
if (!mat || mat->empty())
return -1;
int nBPP = mat->channels() * 8;
img.Create(mat->cols, mat->rows, nBPP);
if (nBPP == 8)
{
static RGBQUAD pRGB[256];
for (int i = 0; i < 256; i++)
pRGB[i].rgbBlue = pRGB[i].rgbGreen = pRGB[i].rgbRed = i;
img.SetColorTable(0, 256, pRGB);
}
uchar* psrc = mat->data;
uchar* pdst = (uchar*)img.GetBits();
int imgPitch = img.GetPitch();
for (int y = 0; y < mat->rows; y++)
{
memcpy(pdst, psrc, mat->cols*mat->channels());//mat->step is incorrect for those images created by roi (sub-images!)
psrc += mat->step;
pdst += imgPitch;
}
return 0;
}
void CMFCApplication1Dlg::OnBnClickedButton2()
{
// TODO: 在此添加控件通知处理程序代码
capture.open("C:\\Users\\Dell\\Desktop\\a\\b.mp4");//随便指定一个视频所在路径
if (capture.isOpened()) {
}
else {
AfxMessageBox(_T("打开失败"));
return;
}
SetTimer(1, (unsigned int)(1000 * 1.0 / capture.get(CV_CAP_PROP_FPS)), NULL);//按视频帧率设置定时器,所以 ON_WM_TIMER()的设置很重要,不然不会响应定时事件
}
void CMFCApplication1Dlg::OnTimer(UINT_PTR nIDEvent)
{
if (1 == nIDEvent)
{
Mat matImg;
capture >> matImg; //取出一帧图像
if (matImg.empty())
{
KillTimer(1);
MessageBox(_T("视频结束"), _T("提示"));
capture.release();
}
else
{
CImage img;
RECT rt;
Mat2CImage(&matImg, img);
GetClientRect(&rt);
rt.bottom -= 40;
img.Draw(this->GetDC()->GetSafeHdc(), rt);
}
}
CDHtmlDialog::OnTimer(nIDEvent);
}
还没有加入开始、暂停,拖动进度条的控制控制,主要用到
capture.set(CV_CAP_PROP_POS_FRAMES,XXX.GetPos()); //设置视频的起始帧
XXX就是一个进度条