Generating an RGB image from 3 mono images

Hi, since this forum seems to answer my questions pretty well, I have another question. :wink:

in an older project I worked with CVB arithmetic and rgb images. However, the arithmetic tool works only with single planes of the color image. Hence, I got three seperate monochromatic images as the result and afterwards I needed another step to stitch them back together to one rgb image. Therefore I used the cvb function CopyImageArea, but this function has been taken a really long time (in my application about 40ms).
Is there a better (faster) way available with CVB to do this?

My application is working fine at the moment, but the 40ms are the bottleneck and I would like to acquire with higher framerates.

CopyImageArea can be a bit of a performance hog because it always assumes the worst case scenario (no linear VPAT plus a nontrivial image coordinate system). This of course makes it a fairly flexible function, but there are many cases where copying could be done with fewer calculations involved, and that’s where CopyImageRect comes in handy (see also this post): CopyImageRect will analyze the memory layout of the source and target image region and then pick the most efficient approach for copying the data. It will, however, also ignore the coordinate system that might have been set on the image.

However, the question is if copying is necessary at all. If you have three monochrome images and want to build an RGB image from them, you might as well use CreateConcatenatedImage: CreateConcatenatedImage accepts an array of image handles and will - if possible - create a new image that contains the sequence of images in that array as the image planes. So assuming your red, green and blue plane have been stored in imgRed, imgGreen and imgBlue, then following code will produce an RGB image from them:

IMG imgRGB = nullptr;
IMG tmpArray[3] = { imgRed, imgGreen, imgBlue };
CreateConcatenatedImage(tmpArray, 3, true, imgRGB);

The true in that function call indicates that you do not want the function to allocate new memory and copy the pixel data: In that case, the resulting image uses the same memory as the three input images, which means

  • the time-consuming copying of image data is not necessary any more
  • an update of the pixel data of the three input images will automatically also update the concatenated RGB image (which can be very convenient when working with live image sources)

This is easily the fastest possible approach - if the fact that the result image uses the same memory as the three input images is not a problem for you and if the input images may actually be used with CreateConcatenatedImage (basically they must have the same width and height each).

:bulb: By the way: This also works the other way round. If you have an RGB image and want to extract one of the planes without copying, CreateImageSubList will do the job:

IMG imgRed, imgGreen, imgBlue;
imgRed = imgGreen = imgBlue; 
CreateImageSubList(imgRGB, 0, 1, false, imgRed);
CreateImageSubList(imgRGB, 1, 1, false, imgGreen);
CreateImageSubList(imgRGB, 2, 1, false, imgBlue);

:exclamation: As always: Call ReleaseObject on any images created by you that you won’t be needing any longer.

1 Like

Copying wasn’t necessary in my application, I just wasn’t aware of CreateConcatenatedImage. This shared memory will speed up the whole process a lot I guess.

However, as the software is already integrated in a running system I won’t be able to test it in the next days. But this seems to be what I was looking for. Thank you @illusive for the detailed description.