VS 2010在MFC中用opencv实现对视频中动态目标的追踪
Visual Studio2010在MFC中用opencv实现对视频中动态目标的追踪
第二步,建立一个MFC的对话框程序,做两个按钮,一个“打开视频文件”,一个“运动跟踪处理”。
具体操作:
1 建立MFC对话框程序的框架:File ->New -> MFC AppWizard(exe),选取工程路径,并取工程名“VideoProcesssing”-> Next -> 选择Dialog based后,去掉使用Unicode库的勾,选择在静态库中使用 MFC,点Finish,点OK.
2 添加按钮:直接Delete掉界面默认的两个“确定”“取消”按钮。然后添加两个button,分别名为“打开视频”,“运动跟踪处理”,其ID分别设为IDC_OPEN_VIDEO,IDC_TRACKING.
3 添加消息响应函数:双击按钮“打开视频文件”,自动生成响应函数名OnOpenVideo,点Ok。然后添加如下代码:
CFileDialog dlg(true,"*.avi",NULL,NULL,"*.avi|*.avi||");
if (dlg.DoModal()==IDOK)
{
strAviFilePath = dlg.GetPathName();
}else
{
return;
}
同样,双击“运动跟踪处理”按钮,选择默认的响应函数名,然后添加代码:
//声明IplImage指针
IplImage* pFrame = NULL;
IplImage* pFrImg = NULL;
IplImage* pBkImg = NULL;
CvMat* pFrameMat = NULL;
CvMat* pFrMat = NULL;
CvMat* pBkMat = NULL;
CvCapture* pCapture = NULL;
int nFrmNum = 0;
//打开AVI视频文件
if(strAviFilePath=="") //判断文件路径是否为空
{
MessageBox("请先选择AVI视频文件!");
return;
}else
{
if(!(pCapture = cvCaptureFromFile(strAviFilePath))) {
MessageBox("打开AVI视频文件失败!");
return;
}
}
//创建窗口
cvNamedWindow("Video", 1);
cvNamedWindow("Background",1);
cvNamedWindow("Foreground",1);
//使窗口有序排列,窗口宽330
cvMoveWindow("Video", 30, 0);
cvMoveWindow("Background", 360, 0);
cvMoveWindow("Foreground", 690, 0);
//逐帧读取视频
while(pFrame = cvQueryFrame( pCapture ))
{
nFrmNum++;
//如果是第一帧,需要申请内存,并初始化
if(nFrmNum == 1)
{
pBkImg = cvCreateImage(cvSize(pFrame->width, pFrame->height), IPL_DEPTH_8U,1); // 存放背景图像(灰度)
pFrImg = cvCreateImage(cvSize(pFrame->width, pFrame->height), IPL_DEPTH_8U,1); // 存放中间图像(灰度)
pBkMat = cvCreateMat(pFrame->height, pFrame->width, CV_32FC1);
pFrMat = cvCreateMat(pFrame->height, pFrame->width, CV_32FC1);
pFrameMat = cvCreateMat(pFrame->height, pFrame->width, CV_32FC1);
//转化成单通道图像再处理(灰度)
cvCvtColor(pFrame, pBkImg, CV_BGR2GRAY);
cvCvtColor(pFrame, pFrImg, CV_BGR2GRAY);
cvConvert(pFrImg, pFrameMat);
cvConvert(pFrImg, pFrMat);
cvConvert(pFrImg, pBkMat);
}
else
{
cvCvtColor(pFrame, pFrImg, CV_BGR2GRAY); //转化成单通道图像再处理(灰度)
cvConvert(pFrImg, pFrameMat);
//高斯滤波先,以平滑图像
//cvSmooth(pFrameMat, pFrameMat, CV_GAUSSIAN, 3, 0, 0);
//当前帧跟背景图相减(求背景差并取绝对值)
cvAbsDiff(pFrameMat, pBkMat, pFrMat);
//二值化前景图(这里采用特定阈值进行二值化)
cvThreshold(pFrMat, pFrImg, 60, 255.0, CV_THRESH_BINARY);
//进行形态学滤波,去掉噪音
cvErode(pFrImg, pFrImg, 0, 1);
cvDilate(pFrImg, pFrImg, 0, 1);
//滑动平均更新背景(求平均)
cvRunningAvg(pFrameMat, pBkMat, 0.003, 0);
//将背景转化为图像格式,用以显示
cvConvert(pBkMat, pBkImg);
// 保持原图像的旋转方向
pBkImg->origin = pFrImg->origin = pFrame->origin;
//显示图像
cvShowImage("Video", pFrame);
cvShowImage("Background", pBkImg);
cvShowImage("Foreground", pFrImg);
//如果有按键事件,则跳出循环
//此等待也为cvShowImage函数提供时间完成显示
//等待时间可以根据CPU速度调整
if( cvWaitKey(200) >= 0 )
break;
}
}
//销毁窗口
cvDestroyWindow("Video");
cvDestroyWindow("Background");
cvDestroyWindow("Foreground");
//释放图像和矩阵
cvReleaseImage(&pFrImg);
cvReleaseImage(&pBkImg);
cvReleaseMat(&pFrameMat);
cvReleaseMat(&pFrMat);
cvReleaseMat(&pBkMat);
cvReleaseCapture(&pCapture);
4 选fileview选项卡中VideoProcessingDlg.h,在CVideoProcessingDlg类中添加公有类成员:
CString strAviFilePath;
5 选fileview选项卡中VideoProcessingDlg.cpp,添加opencv头文件
#include "cv.h"
#include "highgui.h"
#include "cxcore.h"
6 编译执行,成功!
还可以添加一个”录制视频”的按钮,修改ID号为IDC_RECORD,双击“录制视频”按钮,选择默认的响应函数名,然后添加代码:
CvCapture* capture=cvCaptureFromCAM(-1); //打开摄像头
CvVideoWriter* video=NULL;
IplImage* frame=NULL;
int n;
if(!capture) //如果不能打开摄像头给出警告
{
cout<<"Can not open the camera."< return ; } else { frame=cvQueryFrame(capture); //首先取得摄像头中的一帧 video=cvCreateVideoWriter("camera.avi", CV_FOURCC('X', 'V', 'I', 'D'), 25, cvSize(frame->width,frame->height)); //创建CvVideoWriter对象并分配空间 //保存的文件名为camera.avi,编码要在运行程序时选择,大小就是摄像头视频的大小,帧频率是32 if(video) //如果能创建CvVideoWriter对象则表明成功 { cout<<"VideoWriter has created."< } cvNamedWindow("Camera Video",1); //新建一个窗口 int i = 0; while(i <= 200) // 让它循环200次自动停止录取 { frame=cvQueryFrame(capture); //从CvCapture中获得一帧 if(!frame) { cout<<"Can not get frame from the capture."< break; } n=cvWriteFrame(video,frame); //判断是否写入成功,如果返回的是1,表示写入成功 cout< cvShowImage("Camera Video",frame); //显示视频内容的图片 i++; if(cvWaitKey(2)>0) break; //有其他键盘响应,则退出 } cvReleaseVideoWriter(&video); cvReleaseCapture(&capture); cvDestroyWindow("Camera Video"); } return ; 第二步,建立一个编程环境,然后加载opencv的库路径等等。具体步骤如下。 PATH D:\OpenCV2.3.1\build OPENCV D:\OpenCV2.3.1\build\x86\vc10\bin 如下图所示。 配置VS2010,选择“视图”——“其他窗口”——“属性管理器”,如下图所示。 双击Debug | Win32下的“https://www.360docs.net/doc/192841386.html,er”,如下图所示。 在弹出的配置框中配置,选择“VC++目录”。 1、在“包含目录”中的结尾处(若结尾处无英文状态下的“;”则需自行添加“;”,下同)加入以下内容添加以下内容: $(opencv)\include\opencv;$(opencv)\include\opencv2;$(opencv)\include; 2、在库目录中的结尾处加入以下内容添加: $(opencv)\x86\vc10\lib; 注:$(opencv)\include\opencv是告诉VC去“opencv”这个变量中的文件夹下的\include\opencv路径中找OpenCV的库文件目录。 如下图所示。 在“链接器”-“输入”-“附加依赖选项”中的结尾处加入以下内容:$(opencv)\x86\vc10\lib\opencv_core231d.lib;$(opencv)\x86\vc10\lib\opencv_highgu i231d.lib;$(opencv)\x86\vc10\lib\opencv_video231d.lib;$(opencv)\x86\vc10\lib\op encv_ml231d.lib;$(opencv)\x86\vc10\lib\opencv_legacy231d.lib;$(opencv)\x86\vc10 \lib\opencv_imgproc231d.lib; 注:lib可根据实际情况进行删减。 如下图所示。 点击确定,至此OpenCV的配置完成。 第三步,编译,然后调试运行,运行截图如下: