10-07-2015 03:59 PM
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
Solved! Go to Solution.
10-08-2015 01:41 PM
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?
10-08-2015 02:22 PM
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
10-12-2015 07:33 AM - edited 10-12-2015 07:34 AM
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 ?
10-12-2015 07:41 AM
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
10-12-2015 08:04 AM
...also known as 24-bit RGB ! Read up on bitmap and in particular the rowbyte parameter.
10-12-2015 08:23 AM
Thanks gdargaud. I will look into that.
Phil
10-25-2015 05:36 PM
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!
11-03-2015 08:57 AM
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