4

I have a vertically flipped RGBA image stored in uchar[] raw_data, but I need it in grayscale cv::Mat. This can be easily achieved using following code:

cv::Mat src(width, height, CV_8UC4, raw_data), tmp, dst;
cvtColor(src, tmp, CV_RGBA2GRAY);
flip(tmp, dst, 0);

However, I found out that following code is up to two times faster:

int linesize = width * 4; // 4 bytes per RGBA pixel
uchar *data_ptr = raw_data + linesize * (height-1); // ptr to last line
cv::Mat tmp(width, height, CV_8UC4, data_ptr, -linesize), dst;
cvtColor(tmp, dst, CV_RGBA2GRAY);

The trick is quite obvious: tmp is created with pointer to last line and negative line size, so it moves back in memory when iterating over lines. This results in cvtColor by-the-way vertical image flip. Image data is iterated over only once instead of twice, which gives aforementioned boost. I've tested it, it works, end of story.

The questions is: is there any reason to do it the first way? I'm aware, that the fourth parameter in used cv::Mat ctor have size_t type, so in fact this is based on pointer overflows. The code goes to different devices, including smartphones and tablets, so performance is important. On the other hand, it will be compiled to different architectures (x86, ARM), so portability must be preserved.

Thanks in advance!

pigeonR
  • 41
  • 3
  • Can you test the first snippet without creating an intermediate matrix? `cvtColor(src, dst, CV_RGBA2GRAY); flip(dst, dst, 0);` – Miki Jun 15 '16 at 19:05
  • However, I'd go with first snipper because: 1) you don't rely on what is probably undefined behaviour, 2) flipping an image **can't** be the bottleneck of you application. You should gain more by optimizing your algorithm – Miki Jun 15 '16 at 19:07
  • Flipping image in place reduces execution time by 5-10%. – pigeonR Jun 16 '16 at 09:50
  • 1
    After gaining some insight, I'd say it should work since it is based on two's complement arithmetics. Algorithm is quite simple and already strongly optimized: this operation is not bottleneck, but it takes about 2-3% of execution time. I'll go with first one, and - if needed - precisely test the second one. Thanks @Miki – pigeonR Jun 16 '16 at 10:11

0 Answers0