You can free IplImage
using cvReleaseImage
. It takes address of a pointer to an IplImage
, i.e. IplImage**
as argument, so you have to do this:
cvReleaseImage(&currframe);
instead of cvReleaseImage(currframe);
.
But keep in mind, the image returned by cvQueryFrame
, (frame
in your case) is a special case and it should not be released or modified. Also, you don't have to preallocate currFrame
if you are going to initialize it using cvCloneImage
eventually.
The final code would look like this:
int main()
{
std::string videofilename;
std::cout << "Please specify the video name (make sure it is in the same folder\nas the application!):" << std::endl;
std::cin >> videofilename;
std::cout << "The name you provided: " << videofilename << std::endl;
VideoCapture video(videofilename);
if(!video.isOpened())
{
std::cout << "Could not open video file" << std::endl;
return -1;
}
std::cout << "Number of frames: " << video.get(CV_CAP_PROP_FRAME_COUNT) << std::endl;
std::cout << "Duration: "<< static_cast<int>(video.get(CV_CAP_PROP_FRAME_COUNT))/(30*60) << "min " << static_cast<int>((video.get(CV_CAP_PROP_FRAME_COUNT)))%(30*60)/30 << "sek" << std::endl;
// Close it before opening for playing
video.release();
CvCapture* capture = cvCaptureFromAVI(videofilename.c_str());
IplImage* frame = cvQueryFrame(capture);
IplImage* currframe;
IplImage* destframe = cvCreateImage(cvGetSize(frame),IPL_DEPTH_8U,3);
if ( !capture )
{
std::cout << "Could not open video file" << std::endl;
return -1;
}
cvNamedWindow("dest", CV_WINDOW_AUTOSIZE);
while(1)
{
frame = cvQueryFrame(capture);
if(!frame)
{
printf("Capture Finished\n");
break;
}
currframe = cvCloneImage(frame); // copy frame to current
frame = cvQueryFrame(capture); // grab frame
if(!frame)
{
printf("Capture Finished\n");
break;
}
cvSub(frame, currframe, destframe); // subtraction between the last frame to cur
cvShowImage("dest", destframe);
cvWaitKey(30);
cvReleaseImage(&currframe);
}
cvDestroyWindow("dest");
cvReleaseCapture(&capture);
return 0;
}