cvQueryFrame() returns a pointer to the OpenCV "private" internal buffer, which it always fills with the last captured frame.
If you need 2 frames, you will need to cache the copy. Once you have cvCloneImage() (for example, using cvCloneImage() ) the space for your previous frame, you can use cvCopy() to copy only the image data. Do not use cvCloneImage() inside the loop, as it is very inefficient due to the allocation of internal memory (and freeing up memory, otherwise you will also have memory leaks).
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β copy time by doing the conversion instead.
For example, let's say that your display has a color, but your processing is in shades of gray. You only need two consecutive grayscale copies. Since you still need to convert to grayscale, you can do this directly from the captured frame, thereby avoiding excessive cvCopy() . To save the previous frame, you simply swap the pointers between the two selected grayscale images.
source share