Reputation: 175
At the moment I'm trying to understand some of the differences between continuous and non-continuous matrices in openCV. It was suggested to me that continuous matrices provide better performance because the program doesn't have to jump back to the begining of the next row at the end of each column.
In a word what is the comparable performance difference between continuous and non-continuous matrices?
Upvotes: 1
Views: 951
Reputation: 39796
non-continuous matrices happen for 2 reasons:
the image was padded, so the size of one line is a multiple of 4 .
(some bmp images come like that)
it might be even faster to process those, because the row pointers are now properly aligned to 32bit boundaries.
your Mat is only a submat, a ROI.
in both cases, you can't use a single pointer to the first element, but have to relcalculate the line pointer for every row.
i wouldn't worry too much about performance issues here (the internal algos in opencv handle this quite well).
i just hope, knowing this will make you a bit more cautios with direct pointer manipulation ;)
Upvotes: 1
Reputation: 1675
Well, it mostly depends on how you'll use your matrices. If you're doing a lot of "jumping" anyways - it won't make much difference, but in 'continuous' use cases, it will matter a few dozens of percents.
The following example (which simply shifts the matrices values) gives me an output:
image.isContinuous() = 1
roi.isContinuous() = 0
image: 0.0162504 s
roi: 0.0219723 s
Sanity check: OK
Which is about 30% difference. Your millage will vary depending on the hardware and actual use cases.
Source (notice how the first loop is much simpler in that case):
#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;
}
Upvotes: 5