LabWindows/CVI

cancel
Showing results for 
Search instead for 
Did you mean: 

display RGB data with plotscaledintensity

Solved!
Go to solution

Hi,

 

I have a data buffer which originates from a standard visible camera.    The data buffer is populate with the R, G, and B components of each pixel.    Meaning the R compponent are in array positions 0, 3, 6, 9 etc, the G components are in 1, 4, 7, 10 etc and the B components are in 2,5,8,11 etc

 

I can display any of the color components R, G, or B as simple black and white images using PlotScaledIntesnity with a colormap built with the colors black and white.    I am trying to reconstruct each of the components back into an RGB image by using MakeColor (R[i], G[i], B[i]) which appears to work correctly but when I try to display this new image on my UI with PlotScaledIntensity, the colors are all wrong.    Can anyone tell me how to build the correct Colormap component to pass into PlotScaledIntensity?     

 

Thank you.

 

Phil

0 Kudos
Message 1 of 9
(6,085 Views)

Hi mulhall,

 

The first thing I would like to flush out is what format your RGB values are in.  The following table shows different possible RGB representations for Red:

 

Notation RGB triplet
Arithmetic (1.0, 0.0, 0.0)
Percentage (100%, 0%, 0%)
Digital 8-bit per channel (255, 0, 0) or sometimes
#FF0000 (hexadecimal)
Digital 16-bit per channel (65535, 0, 0)

 

Which of these formats are you using for your RGB values?

 

 

Regards,
0 Kudos
Message 2 of 9
(6,064 Views)

Hello AC,

 

Thank you for that table.   Each component R, G, and B are populated as unsigned chars so the values I am working with are between 0 and 255.

 

From your table:   Digital 8-bit per channel(255, 255, 255) 

 

I need to create the RGB pixels from those values.    Here is a code snippet which shows how I have tried to build single pixels from each of the RGB components.

 

unsigned char *data;

int *pixel;

...

...

...

 

j=0;

for (i=0; i<numpts; i+=3) {

    //Try this 
    pixel[j] = MakeColor ((int)data[i], (int)data[i+1], (int)data[i+2]);

    //Try this
   pixel[j] = 65536 * data[i] + 256 * data[i+1] + data[i+2];
   j++;
}

 

Then I try to build a color map:


for(i=0;i<256;i++) {
   cMap[i].dataValue.valInt = i;
   cMap[i].color = MakeColor(i,i,i);
}
maxcolor = MakeColor(255,255,255);

 

Then I plot the pixel buffer using PlotScaledIntensity.

 

Phil

 

 

0 Kudos
Message 3 of 9
(6,059 Views)
Solution
Accepted by topic author mulhall

Since your data is already in 24-bit mode, wouldn't it be simpler to plot it directly onto a canvas (or a picture control) using PlotBitmap ? instead of as a more CPU/memory intensive 2D plot on a graph control ?

0 Kudos
Message 4 of 9
(6,022 Views)

That sounds feasible but I don't have 24-bit pixels, I have 3 individual 8 bit R, G, and B values for each pixel.   How can I re-combine those three to create 24-bit pixels?

 

Thank  you.

 

Phil

0 Kudos
Message 5 of 9
(6,018 Views)

...also known as 24-bit RGB ! Read up on bitmap and in particular the rowbyte parameter.

0 Kudos
Message 6 of 9
(6,015 Views)

Thanks gdargaud.  I will look into that.

 

Phil

0 Kudos
Message 7 of 9
(6,010 Views)

 

 I just wanted to update this post with my working function which displays the contents of a camera image whose pixels were broken out into their respective RGB components.

 

// width = 1280
// height = 800
// numbytes = width*height*3 (R,G, & B components)
// data = (unsigned char *)calloc (numbytes, sizeof (char))

 

void DisplayRGBImage (int numbytes, unsigned char *data) {


unsigned int *RGBbuf;

static int image;

int numpts, i, j, k, m;

int numColors = 256;

numpts = numbytes/3;

RGBbuf = (unsigned int *)calloc (numpts, sizeof(int));

 

j=0;
for (i=0; i<numbytes; i+=3) {
    //try this Native CVI method to build RBG integer pixels
    RGBbuf[j] = MakeColor ((int)data[i], (int)data[i+1], (int)data[i+2]); 

 

    //or try this Native C method to build RBG integer pixels (found online references to this method)
    RGBbuf[j] = 65536 * data[i] + numColors * data[i+1] + data[i+2];
    j++;
}

//Create a new bitmap with the data
NewBitmap (-1, PIXELDEPTH, width, height, NULL, (unsigned char *)RGBbuf, NULL, &image);

//Copy bitmap to clipboard
ClipboardPutBitmap(image);

CanvasDrawBitmap (panelHandle, PANEL_CANVAS, image, VAL_ENTIRE_OBJECT, VAL_ENTIRE_OBJECT);

//Clear bitmap reference
DiscardBitmap(image);

 

free (RGBBuf);

 

}

 

Thanks gdargaud for your suggestions and Tanner at NI for his assistance!

 

0 Kudos
Message 8 of 9
(5,915 Views)

You change your data from 24 bits to 32 bits, you then put it in the clipboard and then put it into a canvas. That's really ressource consuming !

 

Just use the following 2 commands to get your data into a bitmap and then draw it.

 

int BitmapID;

NewBitmap (3*Width, 24, Width, Height, NULL, data, NULL, &BitmapID);

CanvasDrawBitmap (Pnl, CANVAS, BitmapID, VAL_ENTIRE_OBJECT, VAL_ENTIRE_OBJECT);

 

Change VAL_ENTIRE_OBJECT to possibly fit your width/height if you don't want stretching.

Possibly round up 3*Width to the nearest 4 if your rows are int-aligned

0 Kudos
Message 9 of 9
(5,738 Views)