在OpenCV中编写AVI文件

11

网上有例子,并且在“学习OpenCv,Orielly”中也给出了相应的代码。

经过多次尝试,out.avi文件写入后大小为0字节。我不知道哪里出了问题。

以下是我使用的代码...

int main(int argc, char* argv[]) {
    CvCapture* input = cvCaptureFromFile(argv[1]);
    IplImage* image = cvRetrieveFrame(input);

    if (!image) {
        printf("Unable to read input");
        return 0;
    }


    CvSize imgSize;
    imgSize.width = image->width;
    imgSize.height = image->height;



    double fps = cvGetCaptureProperty(
            input,
            CV_CAP_PROP_FPS
            );

    CvVideoWriter *writer = cvCreateVideoWriter(
            "out.avi",
            CV_FOURCC('M', 'J', 'P', 'G'),
            fps,
            imgSize
            );


    IplImage* colourImage;
    //Keep processing frames...
    for (;;) {

        //Get a frame from the input video.
        colourImage = cvQueryFrame(input);
        cvWriteFrame(writer, colourImage);

    }

    cvReleaseVideoWriter(&writer);
    cvReleaseCapture(&input);

}

6
如果Eric提供了正确的答案,你是否可以接受他的回答作为问题的正确答案呢? - Mihai Limbășan
你在哪个平台上运行?我在Windows上无法正常使用MJPG。 - teeks99
7个回答

13

我猜测cvCreateVideoWriter会返回NULL。您可以逐步调试以查看是否为真。如果是这种情况,问题可能出现在CV_FOURCC(..)上,它找不到编解码器并强制返回0;

您可以尝试使用-1代替CV_FOURCC。运行时会出现提示供您选择适当的编解码器。


3
当我在谷歌上搜索这个问题时,我遇到了一个答案:“在Mac OS X上,OpenCV不支持AVI写入,直到它与FFmpeg编译为止”。
对我来说,这个解决方案似乎有效:http://article.gmane.org/gmane.comp.lib.opencv/16005 “在cvCreateVideoWriter中,您需要提供电影文件的完整路径。我不知道这是否只是Mac OS X端口问题,但可能是,因为QT后端使用了QTNewDataReferenceFromFullPathCFString。”

它支持在Windows上进行编写吗? - praxmon

1

这是一个编解码器问题,尝试使用所有可能的编解码器(在cvCreateVideo中使用选项-1)。在我的情况下,Microsoft Video 1效果不错。


1

嘿,这段代码在 DevC++ 中可以运行,请试一下:

  #include<cv.h>
  #include<highgui.h>
  #include<cvaux.h>
  #include<cvcam.h>
  #include<cxcore.h>

  int main()
  {
  CvVideoWriter *writer = 0;
  int isColor = 1;
  int fps     = 5;  // or 30
  int frameW  = 1600; //640; // 744 for firewire cameras
  int frameH  = 1200; //480; // 480 for firewire cameras
  //writer=cvCreateVideoWriter("out.avi",CV_FOURCC('P','I','M','1'),
  //                           fps,cvSize(frameW,frameH),isColor);
  writer=cvCreateVideoWriter("out.avi",-1,
                       fps,cvSize(frameW,frameH),isColor);
  IplImage* img = 0; 

  img=cvLoadImage("CapturedFrame_0.jpg");
  cvWriteFrame(writer,img);      // add the frame to the file
  img=cvLoadImage("CapturedFrame_1.jpg");
  cvWriteFrame(writer,img);
  img=cvLoadImage("CapturedFrame_2.jpg");
  cvWriteFrame(writer,img);
  img=cvLoadImage("CapturedFrame_3.jpg");
  cvWriteFrame(writer,img);
  img=cvLoadImage("CapturedFrame_4.jpg");
  cvWriteFrame(writer,img);
  img=cvLoadImage("CapturedFrame_5.jpg");
  cvWriteFrame(writer,img);

  cvReleaseVideoWriter(&writer);
  return 0;
  }

我编译并运行了它,工作得很好。 (我没有看到上面是否已经得到了你的答案..但对于这个特定的事情,我之前非常努力地工作过,突然间我只是从一些代码片段中做到了这一点。)


0

我认为你遇到的问题是你的“for”循环永远不会结束,因此cvReleaseVideoWriter(&writer);cvReleaseCapture(&input);从未被调用。尝试使用for(int i=0; i<200; i++)之类的东西,看看是否最终得到一个工作视频。

通常在将视频写入磁盘之前,视频会被写入临时文件中。如果您的文件没有完成,就不会有任何东西可供查看。

希望这可以帮助你。


0

这段代码运行良好:

 cv.h 
 highgui.h 
 cvaux.h 
 cvcam.h 
 cxcore.h 

int main(){

    CvVideoWriter *writer = 0;
    int isColor = 1;
    int fps     = 5;  // or 30
    IplImage* img = 0; 
    img=cvLoadImage("animTest_1.bmp");
    int frameW  = img->width; //640; // 744 for firewire cameras
    int frameH  = img->height; //480; // 480 for firewire cameras

    writer=cvCreateVideoWriter("out.avi",-1,
        fps,cvSize(frameW,frameH),1);

    cvWriteFrame(writer, img);      // add the frame to the file

    char *FirstFile,fF[20]="",*fileNoStr,fns[4]="";
    fileNoStr=fns;
    for(int fileNo;fileNo<100;fileNo++){
        FirstFile=fF;   
        itoa(fileNo,fileNoStr,10);
        FirstFile=strcat ( FirstFile,"animTest_");
        FirstFile=strcat ( FirstFile,fileNoStr);
        FirstFile=strcat ( FirstFile,".bmp");

        printf(" \n%s .",FirstFile);
        img=cvLoadImage(FirstFile);

        cvWriteFrame(writer, img);

    }
    cvReleaseVideoWriter(&writer);

    return 0;
}

0
也许你可以尝试在 for(;;) 中插入 printf("Frame found\n") 来查看是否实际捕获了帧。或者更好的方法是:
if(colourImage == NULL) {
    printf("Warning - got NULL colourImage\n");
    continue;
}
cvNamedWindow( "test", 1);
cvShowImage( "test", colourImage );
cvWaitKey( 0 );
cvDestroyWindow( "test" );

然后看看是否会弹出任何窗口,以及它们是否包含正确的内容。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接