LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

How IMAQ images hold RGB values?

Solved!
Go to solution

Hello, how can i process my image in a dll library to change RGB values of it? I could not exactly understand how IMAQ images store RGB values.

0 Kudos
Message 1 of 8
(203 Views)

The "Help" for the IMAQ Create function includes this helpful table:

IMAQ Image Types.pngBob Schor

0 Kudos
Message 2 of 8
(154 Views)

Hello, thank you for the answer, I now get it as each pixel has 4 bytes for the RGB values. If I want to convert an RGB image to a grayscale image, I need to process RGB pixel bytes then assign it to a grayscale pointer image where it points( From a C language point of view because I need to do this in my DLL where image is exported from Labview). However, when I look at the help section of IMAQ GetImagePixelPtr VI I see that border sections. Hence, I got confused about how should adjust the indexes of pointers for assigning.

berkay123_0-1620724974495.png

 

0 Kudos
Message 3 of 8
(140 Views)

Image Processing can be challenging enough when sticking with one Programming Paradigm (e.g. LabVIEW/IMAQ or C/C++).  If you want to "mix" the two, you would be advised to be almost an "expert" in both Paradigms, or to have on-hand Expert Consultants.

 

My recommendation would be to hire a LabVIEW Vision consultant.

 

Bob Schor

0 Kudos
Message 4 of 8
(128 Views)

IMAQ GetImagePixelPtr returns a number of parameters that are all important to access the memory buffer.

 

The returned PixelPointer out is the pointer to the first visible pixel in the image buffer upper left corner of the shaded area in the middle). LineWidth (Pixels) * Pixel Size (Bytes) is the number of bytes an entire image line consumes. This is usually longer than the bytes used for the actual visible pixels in an image, which is Image Width (Pixels) * Pixel Size (Bytes).

 

So while you copy data into the image you have to add Line No * LineWidth (Pixels) * Pixel Size (Bytes) to the initial pixel pointer for a specific Line No, but you only need to copy Image Width (Pixels) * Pixel Size (Bytes) per line. And of course you need to also know the pixel format and store that correctly into the Pixel. Image processing knows a myriad of Pixel Formats and copying image data between different software systems almost always will require you to convert pixel formats from one system to the other, so it is seldom a line by line byte copy and almost never a full image buffer copy since the so called line padding is per software very different. Most software uses padding to 16-bit or 32-bit boundaries. IMAQ Vision has typically a bigger padding since there is also the size for the borders on each size, which allows IMAQ Vision to do various analysis functions a lot more performant since the routine has not to do special handling at the image border but can simply write over the left or right end of the image into the border area.This can save some performance as the algorithme doesn't have to check at each pixel if it is a pixel at the start or end of a line. 

Rolf Kalbermatter
Averna BV
0 Kudos
Message 5 of 8
(113 Views)

Hi, I think my understanding of the LineWidth is more clear now. I will be dealing with only colors, so I set the border size as 0 and make LineWidth equal to Image Width. However, it seems it does not work for a reason that I can't make LineWidth the same as Image Width. I am attaching my VI file. Could it be a reason where some additional information is held? I am trying the convert an RGB U32 image to a GrayScale Image in a Dll. In case if it is necessary for the future, I am attaching them also. I tried IMAQ ImageBorderSize VI, but it did not work for GrayScale Image.

Download All
0 Kudos
Message 6 of 8
(81 Views)
Solution
Accepted by topic author berkay123

It's very simple. You can of course try to move a mountain to where you are, but it is a lot easier to go where the mountain is. Same about this: You generally can NOT force software to use the same Padded Width for an image than its Image Width * Pixel Size. Sometimes it happens to come out that way but usually it doesn't. And even if you can force it that way, it almost never works for both the source and destination image buffer, which means you have to process the image line per line anyhow.

 

So instead make your code such that it can deal with this.

 

char *srcPixelPointer;
int srcPaddedByteWidth = xx;// whatever your source format defines for the pixel format, and yes the padding can vary between pixel formats
char *dstPixelPointer;
int dstPaddedByteWidth = LineWidth * PixelSize;
int imageByteWidth = ImageWidth * PixelSize;

// Copy data from src image to dst image
for (int line = 0; line < ImageHeight; line++)
{
    memcpy(dstPixelPointer + line * dstPaddedByteWidth, srcPixelPointer + line * srcPaddedByteWidth, imageByteWidth);
}

 But please note this only works like that if your source pixel format is exactly the same as your destination pixel format. Otherwise you have to replace the memcpy() call with an additional loop that converts pixel for pixel for ImageWidth pixels. 

Rolf Kalbermatter
Averna BV
0 Kudos
Message 7 of 8
(65 Views)

Thank you very much.

0 Kudos
Message 8 of 8
(58 Views)