Ask Your Question
5

cv::Vec<...,...> vs direct access performance for multi-channel matrices

asked 2013-06-02 11:09:15 -0600

czerhtan gravatar image

updated 2013-06-02 16:34:15 -0600

I'm currently trying to reduce the overhead cost of accessing cv::Mat elements in semi-critical code; when manipulating CV_8UC1 (grayscale) images, I can directly access the element I want by using one of the following lines:

uchar val = img.at<uchar>(row,col);
    or
uchar val = img.data[img.step.p[0]*row + col];

So far, all is well, performance is good. These two lines are actually identical, as the .at<...> function is actually an inlined data access. The problem comes up when trying to access elements in multi-channel matrices: the following line, unlike what I assumed, crashes at run-time, since the matrix is still considered 2-dimensions.

uchar val = img.at<uchar>(row,col,cn)       (DOES NOT WORK)

Looking around for an 'official' solution revealed that using the following lines was the most common way to go:

const Vec3b vec = img.at<Vec3b>(row,col);
uchar val = vec[cn];
    or
uchar val = img.at<Vec3b>(row,col)[cn];

Thing is, going through the Vec<...,...> structure to access a single channel value is extremely time-consuming: in fact, some quick profiling showed that it was at least 10 times slower than a direct 'data' access.

Am I wrong in assuming this is the most common solution? The performance hit is actually quite important, and falling back to a manual data access (by guessing the underlying data structure) is actually a major improvement:

uchar val = img.data[img.step.p[0]*row + img.step.p[1]*col + cn];

Is there any reason why the Vec<...,...> approach does not offer a better performance, or why the .at<...> function doesn't support multi-channel access?

edit retag flag offensive close merge delete

1 answer

Sort by ยป oldest newest most voted
0

answered 2013-07-31 18:19:48 -0600

If your are concern about speed in image scan, look at this page, which compare different method. I think, the most important thing to try is the memory contiguity.

edit flag offensive delete link more

Question Tools

Stats

Asked: 2013-06-02 11:09:15 -0600

Seen: 2,138 times

Last updated: Jul 31 '13