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

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

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

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

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

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

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

 

网上很多人说是解码器的问题,建议安装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

 

哈哈,庆祝一下

你可能感兴趣的:(opencv)