1

現時点では、openCV の連続行列と非連続行列の違いを理解しようとしています。プログラムが各列の最後で次の行の先頭に戻る必要がないため、連続行列の方がパフォーマンスが向上することが示唆されました。

一言で言えば、連続行列と非連続行列の同等のパフォーマンスの違いは何ですか?

4

2 に答える 2

5

まあ、それは主に行列をどのように使用するかによって異なります。とにかく多くの「ジャンプ」を行っている場合は、大きな違いはありませんが、「継続的な」ユースケースでは、数十パーセント重要になります.

次の例 (行列の値を単純にシフトする) から出力が得られます。

image.isContinuous() = 1
roi.isContinuous() = 0
image: 0.0162504 s
roi: 0.0219723 s
Sanity check: OK

これは約30%の違いです。ミレージは、ハードウェアと実際のユースケースによって異なります。

ソース (その場合、最初のループがいかに単純であるかに注意してください):

#include <opencv2/core/core.hpp>
#include <iostream>

using namespace cv;
using namespace std;

int main( int argc, char** argv )
{
    int cols = 4096;
    int rows = 4096;
    int scale = 2;

    Mat image(rows, cols, CV_8UC1);
    Mat image_big(rows * scale, cols * scale, CV_8UC1);
    Mat roi = image_big(Rect(0, 0, cols, rows));

    randu(image, 0, 255);
    image.copyTo(roi);

    cout << "image.isContinuous() = " << image.isContinuous() << "\n" << "roi.isContinuous() = " << roi.isContinuous() << endl;

    {
        cout << "image: ";
        double start = getTickCount();
        for (int i = 1; i < image.total(); i++)
        {
            image.data[i - 1] = image.data[i];
        }
        cout << (getTickCount() - start)/getTickFrequency() << " s" << endl;
    }

    {
        cout << "roi: ";
        double start = getTickCount();
        for (int y = 0; y < roi.cols; y++)
        {
            if (y != 0) {
                roi.ptr<char>(y-1)[roi.cols-1] = roi.ptr<char>(y)[0];
            }

            for (int x = 1; x < roi.rows; x++)
            {
                roi.ptr<char>(y)[x - 1] = roi.ptr<char>(y)[x];
            }
        }
        cout << (getTickCount() - start)/getTickFrequency() << " s" << endl;
    }

    cout << "Sanity check: " << (countNonZero(image - roi) ? "FAIL" : "OK") << endl;
}
于 2013-09-17T13:15:27.710 に答える
1

非連続行列は、次の 2 つの理由で発生します。

  • 画像はパディングされているため、1 行のサイズは 4 の倍数です。

    (一部のbmp画像はそのようになります)

    行ポインターが 32 ビット境界に適切に配置されるようになったため、それらを処理する方がさらに高速になる可能性があります。

  • あなたのマットは単なるサブマット、ROIです。

どちらの場合も、最初の要素への単一のポインターを使用することはできませんが、行ごとに行ポインターを再計算する必要があります。

ここではパフォーマンスの問題についてあまり心配しません (opencv の内部アルゴリズムはこれをうまく処理します)。

これを知っていれば、ポインタの直接操作に少し注意を払うことができると思います ;)

于 2013-09-17T13:28:13.477 に答える