首页 > 代码库 > OpenCV基础篇——视频显示

OpenCV基础篇——视频显示

Opencv的视频显示,其实质是图片显示,只不过是连续显示不同的图片。其中如果涉及GUI,还要用多线程。现在讲自己所用的视频显示写出来供大家参考,主要涉及opencv在win32和mfc中显示视频。

一:Win32+OpenCV

#include "highgui.h"
int main()
{
	const char *showwindow= "image";//窗口名字
	CvCapture *capture = NULL;
	capture=cvCaptureFromAVI("E:\\1.avi");//加载视频
	int framesum = (int) cvGetCaptureProperty( capture, CV_CAP_PROP_FRAME_COUNT );//获取帧的总数
	int numfrm = 0;
	IplImage* frame =NULL;
	IplImage * newframe= NULL;
	cvNamedWindow(showwindow,0);//生成窗口
	while(numfrm < framesum)
	{
		frame = cvQueryFrame(capture);//获取一帧
		numfrm ++;
		if(numfrm==1)//以后可以反复利用新创建的内存,创建一次即可
		{
			newframe=cvCreateImage(cvSize(frame->width,frame->height),IPL_DEPTH_8U,3);//创建与视频帧大小一样的一个frame
		}
		cvCopyImage(frame,newframe);//将视频帧复制到newframe中,以后就可以直接对newframe处理了
		if(cvWaitKey(1)==27)
			break;
		cvShowImage(showwindow, newframe);//在窗口中显示视频帧
		//cvReleaseImage(&newframe);//这里不需要释放
	}
	cvDestroyWindow(showwindow);
	cvReleaseCapture(&capture);


	return 0;
}



二:MFC+OpenCV


对应mfc其实质的操作和win32一样,但是这有界面,要注意多线程否则会卡死无法操作。另外就是这需要显示在控件内。

只贴出关键代码,看后自然会明白。

.h文件

public:
	CRect rect;              
	CWnd *pwnd;             
	CDC *pdc;
    	HDC hdc; 
	CWinThread * hTread2;
	

	void showpicture(IplImage* img); 
	static	UINT videorun(LPVOID IpParamater);
	afx_msg void OnBnClickedplay();



.cpp文件:


struct PARAMATER
{
	CString path;
	CRect rect;              
    HDC hdc; 
	IplImage* image;
	
};
void CtestDlg::OnBnClickedplay()//播放按键
{
			CString vpath = "E:\\1.avi";
			PARAMATER *IpParamater2 = new PARAMATER;
			pwnd=GetDlgItem(IDC_STATIC);   //获取显示视频图像的控件ID
			pdc =pwnd->GetDC();
			hdc=pdc->GetSafeHdc();          //获取句柄
			GetDlgItem(IDC_STATIC)->GetClientRect(rect);  //获取控件的RECT
			IpParamater2->hdc = hdc;
			IpParamater2->path =  vpath;
			IpParamater2->rect = rect; 

			hTread2=AfxBeginThread(videorun,(LPVOID)IpParamater2,0,0,0,NULL);
	//这里使用mfc的多线程函数来实现
}
UINT CtestDlg:: videorun(LPVOID IpParamater)//线程函数,主要是静态的
{
	CtestDlg *pDlg  = (CtestDlg*)IpParamater;
	CString filename = ((PARAMATER*)IpParamater)->path;

	CvCapture *capture = NULL;
	capture=cvCaptureFromAVI(filename);
	int framesum = (int) cvGetCaptureProperty( capture, CV_CAP_PROP_FRAME_COUNT );
	int numfrm = 0;
	IplImage* frame =NULL;
	while(numfrm < framesum-1)
	{
		frame = cvQueryFrame(capture);
        	newframeout = cvCloneImage(frame);
		pDlg->showpicture(newframeout);
		numfrm ++;
		cvReleaseImage(&newframeout);	
	 }
	cvReleaseCapture(&capture);
	//cvReleaseImage(&newframeout);
	}
	return 0;
}
//用来显示每帧的函数,显示到指定的控件内
void Ctest::showpicture(IplImage* img)// ID 是Picture Control控件的ID号
{
         CDC* pDC=GetDlgItem(IDC_STATIC)->GetDC();// 获得显示控件的 DC
         HDC hDC=pDC->GetSafeHdc();// 获取 HDC(设备句柄) 来进行绘图操作

         CvvImage cimg;
         cimg.CopyOf(img);    // 复制图片
	cimg.DrawToHDC(hDC,&m_rect);
         ReleaseDC(pDC);
}

这样就差不多了,主要是在mfc的视频显示的多线程实现,这样的多线程实现以后还可以用在mfc中的其它地方,也是一样的好用,编译的时候可能还需要加部分头文件。希望能帮到需要它的朋友,如果有错还请指出,共同学习交流。