Getting the number of frames of an AVI video file for OpenCV

I’ve been using the OpenCV (ver. 1.0.0) lately and I noticed that under Linux, using the “cvCaptureFromAVI” does not detect the correct number of frames from an AVI video file. So this code returns 0 as the number of frames:

CvCapture  *capture = cvCaptureFromAVI( path2Video );
cvQueryFrame( capture );
int nFrames = (int) cvGetCaptureProperty( capture , CV_CAP_PROP_FRAME_COUNT );

So I wrote a small piece of code which reads the number of frames directly from the AVI file. Please use it and let me know if you had any problem.

int  nFrames;
char tempSize[4];

// Trying to open the video file
ifstream  videoFile( path2Video , ios::in | ios::binary );
// Checking the availablity of the file
if ( !videoFile ) {
cout << "Couldn't open the input file " << path2Video << endl;
exit( 1 );
}

// get the number of frames
videoFile.seekg( 0x30 , ios::beg );
videoFile.read( tempSize , 4 );
nFrames = (unsigned char ) tempSize[0] + 0x100*(unsigned char ) tempSize[1] + 0x10000*(unsigned char ) tempSize[2] +    0x1000000*(unsigned char ) tempSize[3];

videoFile.close(  );

20 thoughts on “Getting the number of frames of an AVI video file for OpenCV

  1. Hi!I’m chinese.Nice to know you,I am eager to make friends with you and know you more!
    I also use opencv lately,and I find your blog when I search “opencv+get the number of frames in an avi” in google.
    I use a loop to know the number of frames in an AVI,
    for(int i= 0; i<1000; i++){
    if(cvGrabFrame(capture))
    printf(“frame%d\n”,i);
    cvRetrieveFrame(capture);
    }
    Do you have another better way to implement it.
    I hope that you can email me!
    thanks!

  2. int numFrames = (int)cvGetCaptureProperty(capture,CV_CAP_PROP_FRAME_COUNT)
    it does not detect the correct number of frames from an AVI video file.
    it is one less frame.

    “for loop” gets 223 frames,but CV_CAP_PROP_FRAME_COUNT only gets 222!

  3. Well Hi,

    As I said, since the OpenCV doesn’t give you the correct number of frames, you can just use my code to read the correct one from the AVI file directly. Just replace the path2Video with the path to your video file. For using it, you don’t need the OpenCV for it, just copy and paste the code into your own C++ program and compile it. Hope this would solve your problem.

    Amir

  4. Hi!

    Sorry, but your code doesn’t work. For an avi File with 74 seconds your functions returns me over 7000000 Frames. Can you explain me why you multiply the the values with 100^x ?
    Can you also explain me how such an avi File looks internally?

    Thank you.

    Luke

  5. Hi Luke,

    I don’t know exactly why it doesn’t work on your AVI file, however, if you could send me your AVI file, I might be able to see what’s going wrong.

    Regarding the AVI file format, you can check this documentation:
    “http://msdn.microsoft.com/en-us/library/ms779631(VS.85).aspx”

    From there if you go to AVI RIFF File Reference , and from there to AVIMAINHEADER , you can see that total number of frames are specified as “DWORD dwTotalFrames” in the header of an AVI file. And the last time I calculated it, the address of it in the header section of the AVI file was in 0×30 . So what my code is doing is that it simply jumps there and reads 4 bytes (DWORD) and converts it to an integer.

    Again if you found out why my code is not able to get the number of frames right out of your AVI, please let me know or simply write a comment there so it would be useful for other people too.

    Cheers
    Amir

  6. Hi!

    I tried and found another easy way to get the number of frames being based on your solution. I’ve tested it on 3 files and I always got the right frame number.

    int nFrames;
    char tempSize[4];

    ifstream videoFile(filename, ios::in|ios::binary);
    videoFile.seekg(0x30, ios::beg);

    videoFile.read(tempSize, 4);

    videoFile.close();
    nFrames = tmpSize[0] + 256 * tempSize[1] + 256^2 * tempSize[2] + 256^3 * tempSize[3];

    Thank you for your inspiration!

    Cheers,

    Luke

  7. Hi Luke,

    Thanks for your feedback, the only difference that I see between your code and mine is the unsinged char casting which I have, as 0x100 = 256, 0x10000 = 256^2, etc. So that might be the source of the problem there, I will try to take a look into it.

    Cheers
    Amir

  8. Hi,

    I am Florin and I am from Romania.

    I have a problem when I use cvCaptureFromAVI function. The return value is NULL. I have installed ffmpeg codec (my OS is Linux).

    Do you know what else do I need to capture from a video file (AVI) ?

    Thanks a lot !

  9. Hi Amir,

    Thanks for the code, it helped me get the video running, although the number of frames seems to be a bit larger than what it’s supposed to be. It looks like it’s double the frame count.

    But I wanted to ask you about something slightly different. I need to get other info out of the file header. Namely the width and height. In the AVI Ref you mentioned it says at what order they come in and that they’re DWords. I tried calculating the position from which to read these values from the stream but I’m not getting the expected results.
    Could you please tell me how you got to 0x30?

    Thanks

  10. Hi Youssef, what I did was to open a few AVI files (small ones) in a hex editor and try to find out the location of the information in the header.Probably you can do the same and check sequentially the header information and see where the height and width size is stored.

    Cheers
    Amir

  11. Hi, I have a question about using cvVideoWriter. I tried to save a video stream using that function, it worked well but, the saved file contains 0 bytes…I tried change the codec properties, but the result still the same. Then i tried to get free code….I get it and still cant save video. The file was there but, contains nothing. I cant open it . Why? If you know about this..let me know..thanks

  12. Hi Amir,
    I am trying a simple code to just read a video file using cvCaptureFromFile/cvCapturefromAVI and then using cvGrabFrame and cvRetrieveFrame, but the problem is cvGrabFrame keeps failing. I have checked the various file formats(avi, mpg,mpeg etc..) and the file path is correct.
    Can you tell what I might be doing wrong?
    Thank you

    1. Hi Sabya,

      Unfortunately without code and video it’s hard to say why something is not working for you. Do you know if you have the codecs and stuff like that installed correctly?

      Also I think it might be a better idea if you post your questions at OpenCV mailing-list as there you might find more people that had the same problem.

      Cheers, Amir

  13. Hi Amir,
    I have a similar problem with camera.
    Do you know how we can get capturing rate (fps) of camera?
    I used cvGetICaptureProperty(capture,CV_CAP_PROP_FPS) but it doesn’t work!
    Cheers,
    Hamed

    1. Hi Hamed,

      Sorry but I don’t know exactly what might a solution to your problem, opencv forums might be a good place to check for it.

      Cheers

  14. Hi amir,
    i have a code for capturing frames from avi video. but the code is working only for 320×240 resolurion videos. i want it to work for any resolution. can u please help me on it?? and also it will helpful if u can tell me how can i capture frames for other video formats like wmv……

  15. hey amir..
    can you kindly help in storing storing the frame in some array after reading it from an avifile.it is important.thankyou

Leave a Reply