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がそれを使用することになっている方法です。私が思う問題は、あなたが渡していないことと、範囲内xyある値です。processGrayFrameインバウンドポイントを通過しないように呼び出します。少なくともMatrixStartPointY + matrixHeight確実に範囲外です。

また、行列を正しく割り当てていることを確認してください (要素の型が割り当てられているとき -少なくとも 8 ビットの s がある場合は、 にucharなると思います)。CV_8UC1char

デバッグ モードで OpenCV を実行すると、座標が範囲外になったことが通知されます。

于 2012-07-24T04:36:26.923 に答える
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,...)cv::rectangle(...)、があります。これらは、より効率的なメモリアクセスがあるため、より効率的です(使用せず、アクセス順序を最適化および並列化することもできます)。cv::ellipse(...)cv::floodFill(...).at<>()

于 2012-11-23T14:13:33.823 に答える
0

C++ インターフェイスを使用すると、メモリ リークが発生しにくくなります。実際には、それを行うには専門家である必要があります:)

これは、Windows システムで頻繁に発生する誤報 (「opencv 関数のメモリ リーク」を参照) またはプログラムの他の部分でのリークです。

漏れでないことを確認するには、漏れ検出器でプロファイリングする必要があります。

于 2012-07-24T06:29:07.140 に答える