1

我试图在视频帧上绘制 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() 函数,内存问题就会出现(当然它不会再画线了)。所以我的问题是为什么分配操作会导致内存泄漏问题?

4

3 回答 3

2

processGrayFrame是对的,这就是你应该如何使用它。我认为的问题是您没有传入x并且y值在界限内。您的电话processGrayFrame不要通过界内点。至少MatrixStartPointY + matrixHeight肯定是越界了。

还要确保您正确分配矩阵(uchar分配时元素类型是 - 我认为CV_8UC1至少如果您有 8-bit chars)。

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

于 2012-07-24T04:36:26.923 回答
0

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

它要么是一个误报,在 Windows 系统上经常发生(参见opencv 函数中的内存泄漏)要么是程序其他部分的泄漏。

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

于 2012-07-24T06:29:07.140 回答
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)。

备注:
我知道这不是重点,但您更愿意熟悉opencv 绘图功能(如果还没有这样做的话)。
cv::line(mat, p1, p2, color,...)、和for 填充cv::rectangle(...),仅举几例。这些方式效率更高,因为它们具有更有效的内存访问(不使用并且还可以优化和并行化访问顺序)。cv::ellipse(...)cv::floodFill(...).at<>()

于 2012-11-23T14:13:33.823 回答