内存泄漏处理cv :: opencv中的mat数组

时间:2012-07-24 03:52:49

标签: c++ opencv

我试图在视频帧上绘制10 * 10矩阵,这是绘图函数:

void AddMatrixToVideo::process(cv::Mat &videoFrameInput)
{
    int MatrixStartPointX = 0;
    int MatrixStartPointY = 0;
    int m,n;

    for(int i = 0; i < matrixNumInRow; ++i) {
        for(int j = 0; j < matrixNumInColm; ++j) {
            //draw horizontal line
            for(m = MatrixStartPointX; m < MatrixStartPointX + matrixWidth; ++m) {
                    processGrayFrame(m,MatrixStartPointY,videoFrameInput);
                    processGrayFrame(m,MatrixStartPointY + matrixHeight,videoFrameInput);
            }
            //draw vertical line
            for(n = MatrixStartPointY; n < MatrixStartPointY + matrixHeight; ++n) {
//                    processGrayFrame(MatrixStartPointX,n,videoFrameInput);
//                    processGrayFrame(MatrixStartPointX + matrixWidth,n,videoFrameInput);
            }
            MatrixStartPointX += matrixWidth;
        }
        MatrixStartPointX = 0;
        MatrixStartPointY += matrixHeight;
    }
}

这是processGrayFrame():

void AddMatrixToVideo::processGrayFrame(int x,int y,cv::Mat &videoFrameInput)
{
    videoFrameInput.at<uchar>(y,x) = 255;
}

运行程序后,似乎绘图进度正常,内存使用量不断增加,最终耗尽内存。 如果我评论processGrameFrame()函数,内存问题就会消失(当然它不会再画线)。所以我的问题是为什么分配操作会导致内存泄漏问题?

3 个答案:

答案 0 :(得分:2)

你的processGrayFrame是正确的,这就是你应该如何使用它。我认为问题是你没有传入限制范围内的xy值。您对processGrayFrame的呼叫未通过入境点。至少MatrixStartPointY + matrixHeight肯定是出界的。

还要确保正确分配矩阵(分配时元素类型为uchar - 我认为这将是CV_8UC1,至少如果你有8位char } S)。

在调试模式下运行OpenCV,它应该告诉你何时坐标超出范围。

答案 1 :(得分:0)

使用C ++接口时很难发生内存泄漏。实际上,你必须是专家才能做到这一点:)

这是一种误报,通常在Windows系统上发生(请参阅memory leak in opencv functions),或者在程序的其他部分发生泄漏。

为了确保它不是泄漏,您应该使用检漏仪对其进行分析。

答案 2 :(得分:0)

使用assert(0<=x&&x<m.cols&&0<=y&&y<m.rows)宏来检查边界条件。 (如果设置了DEBUG标志或者您使用IDE处于调试模式,则检查仅出现在实际代码中。)


如果您没有克隆视频帧,也可能发生潜在的泄漏。

视频帧cv :: Mat(你可能来自cv::VideoCapture cap(0); cap>>frame;)必须克隆出来。否则根据我的经验,你会不时泄漏,而不是每一帧。 (我想只有当缓冲区的位置发生变化时才会发生变化。)

因此解决方案为cap>>frame_raw; Mat frame = frame_raw.clone();(我认为您实际上是致电frame videoFrameInput)。

REMARK:
我知道这不是重点,但你更熟悉opencv drawing functions(如果还没有这样做的话) 填充cv::line(mat, p1, p2, color,...)cv::rectangle(...)cv::ellipse(...)cv::floodFill(...)只是为了填写。这些更有效,因为它们具有更高效的内存访问(不使用.at<>(),也可以优化和并行化访问顺序)。