http://blog.csdn.net/chenyusiyuan/article/details/4744097
http://blog.csdn.net/yang_xian521/article/details/7050398
http://blog.sina.com.cn/s/blog_661159d50100id86.html
opencv [c 版] 学习笔记(2) 在MFC基于对话框界面上播放视频
弄了一天的opencv都快崩溃了。内存泄漏的让人无语,然后自适应阈值分析的时候,发现那个算法实在是慢到让人想把电脑狠狠地往地上砸,块匹配的时候也是问题多多。
先把MFC(vc6.0)与opencv结合的代码发上来以备用。
1. 建立基于对话框(dialog based)的MFC工程。(最好用静态的Using static……),设工程名为test。
2. 添加一个picture控件(ID假设为IDC_SHOWAVI),4个button控件(设ID分别为ID_BTNOPEN , ID_BTNPLAY , ID_BTNPAUSE, ID_BTNSTOP,分别对应4个响应函数OnBtnOpen, OnBtnPlay ,OnBtnPause, OnBtnStop)。
3. 工程->设置->link添加好需要的*.lib文件(cv.lib highgui.lib cxcore.lib等等)。
4. 在CtestDlg.h开头加上下面两行
// CtestDlgg.h : header file
//
#include "highgui.h"
#include "cv.h"
#if !defined(AFX_LENSDIVIDEDLG_H__180CC67F_3199_4F65_9CBC_4414B309D13B__INCLUDED_)
#define AFX_LENSDIVIDEDLG_H__180CC67F_3199_4F65_9CBC_4414B309D13B__INCLUDED_
5. 进入CtestDlg.cpp文件中定义以下全局变量
/ // CLensdivideDlg dialog CvvImage m_CvvImage; CWnd *pwnd; CRect rect; CDC *pDC; HDC hDC; BOOL isAviFile = FALSE, isPlaying = FALSE, paused = FALSE; int totalFrameNumber = 0, currentFrameIndex = 0, speed = 20, fps = 0; CString filePath = ""; CvCapture *capture = NULL; IplImage *currentFrame = NULL;
6. open按钮写入下面代码
void CtestDlg::OnBtnOpen() { // TODO: Add your control notification handler code here filePath = "视频类型(*.avi) | *.avi |"; CFileDialog dlg(TRUE, NULL, "*.avi", OFN_FILEMUSTEXIST | OFN_HIDEREADONLY, filePath, this); if (dlg.DoModal() == IDOK) { if(isPlaying) { OnBtnStop(); } if(isAviFile) { closeAviFile(); } KillTimer(1); pwnd = GetDlgItem(IDC_SHOWAVI); //获取显示视频的控件ID pDC = pwnd->GetDC(); hDC = pDC->GetSafeHdc(); //句柄 GetDlgItem(IDC_SHOWAVI)->GetClientRect(rect); //获取控件的RECT capture = cvCreateFileCapture(dlg.GetPathName()); //捕获视频 if(!capture) { AfxMessageBox("打开文件失败!"); return; } //帧总数: totalFrameNumber = (int)cvGetCaptureProperty(capture, CV_CAP_PROP_FRAME_COUNT); if(totalFrameNumber == 0) { AfxMessageBox("不能打开该格式文件!"); return; } fps = (int)cvGetCaptureProperty(capture, CV_CAP_PROP_FPS); //帧率 isAviFile = TRUE; currentFrameIndex = 0; //第一帧播放 OnBtnPlay(); //自动播放 } }
7. play按钮:
void CtestDlg::OnBtnPlay() { // TODO: Add your control notification handler code here isPlaying = TRUE; if(fps > 0 && fps < 1000) //获取视频本身的播放速度 { speed = (int)(1000/fps); //每一帧多少毫秒 } else speed = 0; SetTimer(1, speed, NULL); //每隔一段时间读出一帧视频图像 if(currentFrameIndex > totalFrameNumber) return; //设置播放帧位置: cvSetCaptureProperty(capture, CV_CAP_PROP_POS_FRAMES, (currentFrameIndex % totalFrameNumber)); currentFrame = cvQueryFrame(capture); //获取一帧 if(currentFrame) { m_CvvImage.CopyOf(currentFrame,1); m_CvvImage.DrawToHDC(hDC,&rect); //视频显示到控件 } }
8. pause按钮
void CtestDlg::OnBtnPause() { // TODO: Add your control notification handler code here if(isPlaying) { KillTimer(1); isPlaying = FALSE; paused = TRUE;//暂停 } }
9. stop按钮
void CtestDlg::OnBtnStop() { // TODO: Add your control notification handler code here if(isPlaying||paused) { currentFrameIndex = 1; //回到第一帧位置 OnBtnPlay();//预览第一帧图像 KillTimer(1); isPlaying = FALSE; } }
10. 涉及到的closeAviFile()
void CtesteDlg::closeAviFile() { if(capture) { cvReleaseCapture(&capture); } }
11. 最后要加上timer才行
void CtestDlg::OnTimer(UINT nIDEvent) { // TODO: Add your message handler code here and/or call default if(isAviFile) {//选择播放视频 if(currentFrameIndex > totalFrameNumber) {//判断视屏是否已经是最后一帧,即是否播完 currentFrameIndex = 0; //回到第一帧,继续播放 KillTimer(1); OnBtnStop(); } else { OnBtnPlay(); //播放第currentFrame帧 currentFrameIndex ++; //下一帧的位置 } } currentFrameIndex = (int)cvGetCaptureProperty(capture, CV_CAP_PROP_POS_FRAMES); CDialog::OnTimer(nIDEvent); }
12. 双击取消(Cancel)按钮,响应函数:
void CtestDlg::OnCancel