cvQueryFrame()
возвращает указатель на «закрытый» внутренний буфер OpenCV, который он всегда заполняет последним захваченным кадром.
Если вы хотите 2 кадра, вам нужно будет кэшировать копию.Как только вы выделите (например, cvCloneImage()
) место для предыдущего кадра, вы можете использовать cvCopy()
, чтобы скопировать только данные изображения. не используйте cvCloneImage()
внутри цикла, поскольку это очень неэффективно из-за выделения внутренней памяти (и освобождения, иначе у вас также будут утечки памяти).
Обновление: код будет выглядеть примерно так:
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 );
Примечание: Часто вы можете избежать этого "избыточного" времени копированиявыполнив преобразование вместо этого.
Например, скажем, ваш дисплей цветной, но ваша обработка в оттенках серого.Вам нужны только 2 последовательных копии в оттенках серого.Так как вам все равно потребуется преобразовать в оттенки серого, вы можете сделать это прямо из захваченного кадра, избегая, таким образом, избыточного cvCopy()
.Чтобы сохранить предыдущий кадр, нужно просто поменять местами указатели между двумя выделенными изображениями в оттенках серого.