Thursday, May 5, 2011

Writing AVI files in OpenCV

There example on the net and code given in Learn OpenCv,Orielly.

After many attempts the out.avi file is written with 0 bytes. I wonder where i went wrong.

The following are the code i used...

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);

}
From stackoverflow
  • Maybe you could try inserting a printf("Frame found\n") inside the for(;;) to see if it is actually capturing frames. Or even better:

    if(colourImage == NULL) {
        printf("Warning - got NULL colourImage\n");
        continue;
    }
    cvNamedWindow( "test", 1);
    cvShowImage( "test", colourImage );
    cvWaitKey( 0 );
    cvDestroyWindow( "test" );
    

    Then see if you get any windows, and if they contain the right contents.

  • My bet is that cvCreateVideoWriter returns NULL. Just step through it to see if it's true. In that case, the problem is probably with CV_FOURCC(..) which doesnt find the codec and force a return 0;

    you can try using -1 instead of CV_FOURCC. There is gonna be a prompt during runtime for you to chose the appropriate codec

    : Thanks Eric you are right
  • I've a problem under MacOs 10.4. When I try to execute this row

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

    i've this problem:

    OpenCV ERROR: Internal error (Cannot create data reference from file name) in function icvCreateVideoWriter, cvcap_qt.cpp(1291) Terminating the application...

    any idea?

    Eric : if you have another problem please make a separate question
  • When i google this problem i meet an answer: "OpenCV on mac os x don`t support avi write until it will be compiled with a ffmpeg"

    For me seem to wrok this solution http://article.gmane.org/gmane.comp.lib.opencv/16005

    You need to provide the full path to the file with the movie in cvCreateVideoWriter. I don't know whether it's only an Mac OS X port issue, but might be, since QTNewDataReferenceFromFullPathCFString from the QT backend is used.

  • Friends I faced the same problem; the methods suggested by Eric does work. The problem, i think lies with the availability of the codecs. Thanks to all of you....

  • Hi ,

    I have the following code , and NONE of the functions are returning NULL, so I guess everything is proper.

    But still the file size of the test.avi file is 0 bytes

            CvCapture *pCapturedImage = cvCreateCameraCapture(0); // get the default camera, for me it is a webcam
    

    // Get the avi file name CString strFileName = objFileDlg.GetPathName()+".avi"; // test.avi

            int isColor = 1;
            int fps     = 25;  // or 30
            int frameW  = 640; // 744 for firewire cameras
            int frameH  = 480; // 480 for firewire cameras
            CvVideoWriter *pVideoWriter = cvCreateVideoWriter(strFileName.GetBuffer(),
    

    -1, // I am choosing the uncompressed format** fps,cvSize(frameW,frameH),isColor);

    // pVideoWriter does not return NULL , that means its succesful

            cvNamedWindow("mainWin",CV_WINDOW_AUTOSIZE);
            IplImage *pImage = 0;
    
            int nFrames = 50;
            for(int i=0;i<nFrames;i++)
            {
                  cvGrabFrame(pCapturedImage);          // capture a frame
                  pImage=cvRetrieveFrame(pCapturedImage);  // retrieve the captured frame
                  cvWriteFrame(pVideoWriter,pImage);      // add the frame to the file
    
                  cvShowImage("mainWin",pImage);     // NO IMAGE SHOWS UP
                  cvWaitKey(20);
    
            }
    
            cvDestroyWindow("mainWin");
            cvReleaseVideoWriter(&pVideoWriter);
    

    Please let me know what am I missing out.

    Thanks, Sujay

  • hey This code works in DevC++ try it:

      #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;
      }
    

    I compiled it and ran it, works fine. (I did not see above whether you got your answer or not .. but for this particular thing I worked very hard earlier and suddenly I just did it, from some code snippets.)

  • This code worked fine:

    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;
    

    }

  • I think the problem you're encountering is that your "for" loop never ends; therefore, "cvReleaseVideoWriter(&writer);" and "cvReleaseCapture(&input);" never get called. Try something like "for(int i=0; i<200; i++)" and see if you end up with a working video.

    Often video is written to a temporary files before being finalized on disk. If your file isn't finalized, there won't be anything to see.

    Hope that helps.

0 comments:

Post a Comment