在cvFindContours中使用CvSeq时内存泄漏

时间:2011-12-22 01:12:10

标签: opencv

我是OpenCV的新手,在使用它时遇到了一些问题。

目前我正在研究二进制分区树(BPT)算法。基本上我需要将图像分成许多区域,并基于一些参数。 2个区域将合并,形成1个新区域,由这2个区域组成。

我设法通过使用cvWatershed获取初始区域。我还创建了一个矢量来存储这些区域,每个区域都在1个矢量块中。但是,当我尝试将轮廓信息移动到矢量中时,我得到了内存泄漏。它说,内存泄漏。

for (int h = 0; h <compCount; h++)  // compCount - Amount of regions found through cvWaterShed
{
    cvZero(WSRegion);               // clears out an image, used for painting 
    Region.push_back(EmptyNode);    // create an empty vector slot
    CvScalar RegionColor = colorTab[h]; // the color of the region in watershed

    for (int i = 0; i <WSOut->height; i++)
    {
        for (int j = 0; j <WSOut->width; j++)
        {
            CvScalar s = cvGet2D(WSOut, i, j);  // get pixel color in watershed image
            if (s.val[0] == RegionColor.val[0] && s.val[1] == RegionColor.val[1] && s.val[2] == RegionColor.val[2])
            {
                cvSet2D(WSRegion, i, j, cvScalarAll(255));  // paint the pixel to white if it has the same color with the region[h]

            }
        }
    }

    MemStorage = cvCreateMemStorage();   // create memory storage
    cvFindContours(WSRegion, MemStorage, &contours, sizeof(CvContour), CV_RETR_LIST);
    Region[h].RegionContour = cvCloneSeq(contours);  // clone and store in vector Region[h]
    Region[h].RegionContour->h_next = NULL;
}

我能以任何方式解决这个问题吗?或者有什么替代方案我不需要为每个区域向量创建新的内存存储?提前谢谢

1 个答案:

答案 0 :(得分:2)

你应该在循环之前只创建一次内存存储,cvFindContours可以使用它,在循环之后你应该用以下内容释放存储:

void cvReleaseMemStorage(CvMemStorage** storage)

您还可以在这里查看CvMemStorage规范: http://opencv.itseez.com/modules/core/doc/dynamic_structures.html?highlight=cvreleasememstorage#CvMemStorage

编辑:

您的下一个问题是cvCloneSeq()。以下是一些规范:

CvSeq* cvCloneSeq(const CvSeq* seq, CvMemStorage* storage=NULL )
Parameters: 

seq – Sequence
storage – The destination storage block to hold the new sequence header and the copied data, if any. If it is NULL, the function uses the storage block containing the input sequence.

正如您所看到的,如果您没有指定不同的内存存储,它将在与输入相同的内存块中克隆序列。当您在循环之后释放内存存储时,您还将释放最后一个轮廓,并且它是您在列表中推送的克隆。