Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

read successive frames OpenCV using cvQueryframe

I have a basic question in regards to cvQueryFrame() in OpenCV.

I have the following code:

IplImage *frame1,*frame2;
frame1 = cvQueryFrame(capture);
frame2 = cvQueryFrame(capture);

Now my question is: if frame1 is a pointer to the first frame, is frame2 a pointer to the 2nd frame? So will the two cvQueryFrame() calls read successive frames?

I thought I'd check myself first but the pointers frame1,frame2 seem to have the same hex value. :s I just need to capture two frames at a time and then need to process them.

Thanks in advance

EDIT: I found from google that calling cvQueryFrame() twice returns the same pointer. now I am slightly confused. If i use call it only once in a while loop, the frames progress but not if i call it twice? Is there a easy way to grab two frames?

like image 561
AtharvaI Avatar asked Dec 21 '22 19:12

AtharvaI


1 Answers

cvQueryFrame() returns the pointer to OpenCV's "private" internal buffer which it always fills with the last grabbed frame.
If you want 2 frames you will need to cache a copy. Once you allocate (e.g. using cvCloneImage()) space for your previous frame, you can use cvCopy() to copy just the image data. Do not use cvCloneImage() inside the loop as that is very inefficient due to the internal memory allocations (and deallocations, otherwise you'll have memory leaks as well).

Update: the code will look something like this:

IplImage* currFrame = 0;
IplImage* prevFrame = 0;
CvCapture* cap = cvCaptureFromAVI("sample.avi");   
currFrame = cvQueryFrame( cap );

 // Clone the frame to have an identically sized and typed copy
prevFrame  = cvCloneImage( currFrame );

while(currFrame = cvQueryFrame( cap ))
{
    // process the video using currFrame and prevFrame...

    // ...


    // When done, overwrite prevFrame with current copy in preparation
    // for the next frame.
    cvCopy( currFrame , prevFrame); 
} 

cvReleaseImage( &img1 );
cvReleaseCapture( &cap );

Note: Often, you can avoid this "redundant" copying time by doing a conversion instead.
For example, say your display is in color, but your processing is in grayscale. You only need the 2 consecutive copies in grayscale. Since you will need to convert to grayscale anyway, you can do that directly from the captured frame thus avoiding the redundant cvCopy(). To save the previous frame you would just swap pointers between your 2 allocated grayscale images.

like image 148
Adi Shavit Avatar answered Jan 07 '23 17:01

Adi Shavit