OPENCV读取AVI视频失败 视频帧提取以及图片合成视频

前一阵子,实验室老师个了个小命题,就是如何提取一段AVI视频中的图片,或者说视频帧的提取。虽然是第一次接触OPENCV,可是做起来也是不难的,自己的代码就不拿出来了,写的很乱,网上的这个代码比较不错,为了说明我们的主题,姑且拿这段代码做个试验。

#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include <cv.h>
#include <highgui.h>
#define NUM_FRAME 5591 //只处理前300帧,根据视频帧数可修改


int frameH;
int frameW; 
int fps;
int numFrames;

void Video_to_image(char* filename)
{
	printf("------------- video to image ... ----------------\n");
	//初始化一个视频文件捕捉器
	CvCapture* capture = cvCaptureFromAVI(filename);
	//获取视频信息
	cvQueryFrame(capture);
	frameH    = (int) cvGetCaptureProperty(capture, CV_CAP_PROP_FRAME_HEIGHT);
	frameW    = (int) cvGetCaptureProperty(capture, CV_CAP_PROP_FRAME_WIDTH);
	fps       = (int) cvGetCaptureProperty(capture, CV_CAP_PROP_FPS);
	numFrames = (int) cvGetCaptureProperty(capture, CV_CAP_PROP_FRAME_COUNT);
	printf("\tvideo height : %d\n\tvideo width : %d\n\tfps : %d\n\tframe numbers : %d\n", frameH, frameW, fps, numFrames);
	//定义和初始化变量
	int i = 0;
	IplImage* img = 0;
	char image_name[13];
	
	cvNamedWindow( "mainWin", CV_WINDOW_AUTOSIZE );
	//读取和显示
	while(1) 
	{
		
		img = cvQueryFrame(capture); //获取一帧图片
		cvShowImage( "mainWin", img ); //将其显示
		char key = cvWaitKey(20);
		
		sprintf(image_name, "%s%d%s", "image", ++i, ".bmp");//保存的图片名
		
		cvSaveImage( image_name, img);   //保存一帧图片
		
		if(i >=numFrames || i >= NUM_FRAME ) break;

	}
	cvReleaseCapture(&capture);
	cvDestroyWindow("mainWin");
}
void Image_to_video()
{
	int i = 0;
	IplImage* img = 0;
	char image_name[13];
	printf("------------- image to video ... ----------------\n");
	//初始化视频编写器,参数根据实际视频文件修改
	CvVideoWriter *writer = 0;
	int isColor = 1;

	writer=cvCreateVideoWriter("out.avi",CV_FOURCC('X','V','I','D'),fps,cvSize(frameW,frameH),isColor);
	printf("\tvideo height : %d\n\tvideo width : %d\n\tfps : %d\n", frameH, frameW, fps);
	//创建窗口
	cvNamedWindow( "mainWin", CV_WINDOW_AUTOSIZE );
	while(i<NUM_FRAME)
	{
		sprintf(image_name, "%s%d%s", "image", ++i, ".bmp");
		img = cvLoadImage(image_name);
		if(!img)
		{
			printf("Could not load image file...\n");
			exit(0);
		}
		cvShowImage("mainWin", img);
		char key = cvWaitKey(20);
		cvWriteFrame(writer, img);
	}
	cvReleaseVideoWriter(&writer);
	cvDestroyWindow("mainWin");
}

int main(int argc, char *argv[])
{
	char filename[23] = "F:\\1_Xvid.avi";
	Video_to_image(filename); //视频转图片
	Image_to_video();    //图片转视频
	return 0;
}

  配置好OPENCV环境(WIN7 + VS2010)之后,这段代码是可以运行的,可是,实验室师兄师姐们的主流实用VC6开发的,所以老师让我把代码在VC6下调试出来。

结果配置好VC6之后,一运行出现这个错误:Null pointer in function cvGetMat

首先找资料是怎么回事,有的人说是内存不足之类的原因,建议在循环体里面释放窗体资源,我照做了,可是还是不行。

郁闷了老半天,还是没有结果。。。。。

后来我发现一个细节,就是说,视频的信息压根就没有读进来,可以看看控制台。

找到原因之后,后来就相对好办了,其实也花了很长时间去做。

 

网上很多人说是解码器的问题,建议安装K-Lite_Codec_Pack_3.9.5Full,我也试了,在实验室蛋疼的网速之下,苦苦等待,安装,结果不知道为什么还是不行,。

最后阶段,一个偶然的机会,我看到这篇文章http://hqs2892805.blog.163.com/blog/static/379968312010722915630/

结果按照这篇文章这么做,就实现了。。。

 

如果AVI文件打不开,请下载VIRTUALDUB图像处理软件,然后把AVI文件用XVID编码,编码后的文件不会太大。我自己用摄像头拍摄的AVI有5兆,编码后只有不到2兆,而且能够用VC打开。

http://www.xvidmovies.com/codec/    可以从这个网站下载xvid解编码器

方法:file——open video file 

           video——compression——选择XVIDMPEG CODEC

 

哈哈,庆祝一下

posted on 2012-12-01 21:50  苯苯吹雪  阅读(3110)  评论(0)    收藏  举报

导航