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

出现非连续矩阵有两个原因:

  • 图像被填充,所以一行的大小是 4 的倍数。

    (一些bmp图像就是这样)

    处理这些可能会更快,因为行指针现在已正确对齐到 32 位边界。

  • 你的垫子只是一个子垫子,一个投资回报率。

在这两种情况下,您都不能使用指向第一个元素的单个指针,而必须重新计算每一行的行指针。

我不会太担心这里的性能问题(opencv 中的内部算法可以很好地处理这个问题)。

我只是希望,知道这会让你对直接指针操作更加谨慎;)

于 2013-09-17T13:28:13.477 回答