我正在尝试掌握 OpenCV。目前我正在尝试将两帧相减并显示结果。我找到了可以很好地做到这一点的示例代码。 我的问题是出现内存分配错误。 好吧,这没什么特别的,因为我正在为节目提供高清视频。 所以我的问题是如何释放分配给 IplImage* 的内存? Mat 类型类似于 Mat.release()。 IplImage 没有,free(IplImage) 也没有。
这是我的代码:
#include <opencv2\opencv.hpp>
#include <opencv2\highgui\highgui.hpp>
#include <opencv2\highgui\highgui_c.h>
using namespace cv;
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 = cvCreateImage(cvGetSize(frame),IPL_DEPTH_8U,3);
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);
//cvReleaseImage(currframe); // doesn't work
//free(currframe); // doesnt work either
//delete(currframe); //again, no luck
cvWaitKey(30);
}
cvDestroyWindow("dest");
cvReleaseCapture(&capture);
return 0;
}
最佳答案
您可以使用cvReleaseImage
释放IplImage
。它采用指向 IplImage
的指针地址,即 IplImage**
作为参数,因此您必须这样做:
cvReleaseImage(&currframe);
代替 cvReleaseImage(currframe);
。
但请记住,cvQueryFrame
返回的图像(在您的情况下为 frame
)是一种特殊情况,不应发布或修改。此外,如果您最终要使用 cvCloneImage
对其进行初始化,则不必预先分配 currFrame
。
最终代码如下所示:
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;
}
关于c++ - 打开简历;如何释放 IplImage*?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20728977/