Exchange 2 memory positions

I work with OpenCV and Qt, Opencv uses BGR, and Qt uses RGB, so I have to change these 2 bytes to very large images.

Is there a better way to do the following? I can't think of anything faster, but it looks so simple and lame ...

    int width = iplImage->width;
 int height = iplImage->height;

 uchar *iplImagePtr = (uchar *) iplImage->imageData;
 uchar buf;
 int limit = height * width;

 for (int y = 0; y < limit; ++y) {
  buf = iplImagePtr[2];
  iplImagePtr[2] = iplImagePtr[0];
  iplImagePtr[0] = buf;
  iplImagePtr += 3;
 }

 QImage img((uchar *) iplImage->imageData, width, height,
     QImage::Format_RGB888);
+3
source share
8 answers

We are currently addressing this issue in the Qt application. We found that Intel performance primitives are the fastest way to do this. They have extremely optimized code. In the html help files in the Intel ippiSwapChannels Documentation , they have an example of exactly what you are looking for.

There are several disadvantages.

  • , .
  • AMD. Intel . www.agner.org/optimize/asmlib.zip, , .
+5

, . , , - . , std::swap:

std::swap(iplImagePtr[0], iplImagePtr[2]);

:

 uchar* end = iplImagePtr + height * width * 3;
 for ( ; iplImagePtr != end; iplImagePtr += 3) {
    std::swap(iplImagePtr[0], iplImagePtr[2]);
 }
+4
+2

?

void QImage::invertPixels ( InvertMode mode = InvertRgb )

QImage QImage::rgbSwapped () const

, !

+2

- , , RGB .

int i = 0;
int limit = (width * height); // / 3;
while(i != limit)
{
  buf = iplImagePtr[i]; // should be blue colour byte
  iplImagePtr[i] = iplImagaePtr[i + 2]; // save the red colour byte in the blue space
  iplImagePtr[i + 2] = buf; // save the blue color byte into what was the red slot
  // i++;
  i += 3;
}

, "", , .

+1

:

int width = iplImage->width;
int height = iplImage->height;
uchar *start = (uchar *) iplImage->imageData;
uchar *end = start + width * height;

for (uchar *p = start ; p < end ; p += 3)
{
   uchar buf = *p;
   *p = *(p+2);
   *(p+2) = buf;
}

.

.

Windows, , , , BitBlt DIB. , .

+1

, IPP (. photo_tom) , ( ):

uchar *iplImagePtr = (uchar *) iplImage->imageData;
uchar buf;
size_t limit = height * width;

for (size_t y = 0; y < limit; ++y) {
    std::swap(iplImagePtr[y * 3], iplImagePtr[y * 3 + 2]);
}

, , , " !" , , , , , . iplImagePtr . ; y , "count from 0 to N-1", .

, , , (?). , ...

PS If you really compare this, I would also like to see how well the following works:

uchar *iplImagePtr = (uchar *) iplImage->imageData;
uchar buf;
size_t limit = height * width;

for (size_t y = 0; y < limit; ++y) {
    uchar *pixel = iplImagePtr + y * 3;
    std::swap(pix[0], pix[2]);
}

Again, it is pixeldefined in the cycle in order to limit its scope and prevent the optimizer from thinking about the dependence on the cycle to the cycle. If the compiler increments and decrements the stack pointer every time through the loop to “create” and “destroy” pixel, well, that’s stupid, and I apologize for wasting your time.

0
source
cvCvtColor(iplImage, iplImage, CV_BGR2RGB);
0
source

Source: https://habr.com/ru/post/1739431/


All Articles