首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Opencv;如何释放IplImage*?

Opencv;如何释放IplImage*?
EN

Stack Overflow用户
提问于 2013-12-22 19:38:30
回答 2查看 12.9K关注 0票数 3

我正在试着掌握OpenCV的窍门。目前,我正在尝试从两个帧中减去两个帧并显示结果。我已经找到了可以很好地做到这一点的示例代码。我的问题是我得到了一个内存分配错误。好吧,这没什么特别的,因为我给节目提供了高清视频。因此,我的问题是如何释放IplImage*的已分配内存?Mat类型具有类似于Mat.release()的内容。IplImage没有这样的功能,自由(IplImage)也不能工作。

下面是我的代码:

代码语言:javascript
复制
#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;
}
EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2013-12-22 22:39:19

你可以使用cvReleaseImage来释放IplImage。它接受指向IplImage的指针的地址,即IplImage**作为参数,所以你必须这样做:

代码语言:javascript
复制
cvReleaseImage(&currframe);

而不是cvReleaseImage(currframe);

但请记住,cvQueryFrame (在您的示例中为frame)返回的图像是一个特例,不应该发布或修改它。此外,如果最终要使用cvCloneImage对其进行初始化,则不必预先分配currFrame

最终的代码如下所示:

代码语言:javascript
复制
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;
}
票数 1
EN

Stack Overflow用户

发布于 2013-12-22 22:39:11

使用cvReleaseImage()。例如,如果您想要发布IplImage* frame,请使用cvReleaseImage(&frame)

对于Mat,您不需要显式地释放它。它将在超出其代码块时自动释放。

编辑:看看here上关于cvReleaseImage()的更多细节,它解决了一些错误的发布情况。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/20728977

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档