views:

64

answers:

1

My camera gives me 14bit grayscale images, but the API's function returns a long* to the image data. (so i'm assuming 4 bytes for each pixel)

My application is written in C++/CLI, and the pictureBox is of .NET type.
I am currently using the BitmapData.LockBits() mechanism to gain pointer access to the image data, and using
memcpy(bmpData.Scan0.ToPointer(), imageData, sizeof(long)*height*width)
to copy the image data to the Bitmap.
For now, the only PixelFormat that is working is 32bit RGB, and the image appears in shades of blue with contours.

Trying to initialize the Bitmap as 16bppGrayscale isn't working.
I would ideally want to cast the array from long to word and using a 16bit format (hoping the the 14bit data will be displayed properly) but I'm not sure if this works. Also, I don't want to iterate over the image data, so finding the min/max and then histogram stretching to [0..255] isnt an option for me (the display must be as efficient as possible)

Thanks

+1  A: 

Yes, that will look very blue, some shades of green for high intensity pixels. You've got a pixel format mismatch, 32bppRgb has one byte for blue, one for green, one for red and one unused byte. Copying the gray image directly will set the blue byte, up to 6 bits of green.

16bppGrayScale would be great, if only GDI+ actually supported it. The problem is that no main-stream video adapter handles this format. You'll need to translate the pixel values to a RGB triplet. To make it look gray, you'll need to set the blue, green and red bytes to the same value. That will be a lossy conversion since you need to squeeze 14 bits into 8 bits. That doesn't really matter, the human eye isn't nearly good enough to be able to distinguish 16,384 distinct gray levels. Simply right-shift the pixel value by 6, assuming the camera produces a pixel value of 16383 for high luminosity pixels. Either a 24bppRgb or 32bppRgb pixel format will work, the latter will be quicker since it fits an int and you don't have to monkey with stride.

Note that false-color images are possible too. You could arbitrarily map a 14 bit gray value to a color. Quickest way to do this is by using a int[16384] mapping table. What you stick in the table is entirely up to you, common mappings are deep red for low intensity, violet for high intensity values.

That's good enough for image display. However, if you do any image processing then you'll probably want to take advantage of the camera's resolution. You'll need to stay away from Bitmap. Check out a graphics library vendor like LeadTools.

Hans Passant
Itsik
Yes, mapping each individual pixel will be required.
Hans Passant
Maybe I can only change the ColorPalette in the Bitmap? Regarding libraries, I have IPP, but don't really know if any of its features can help me.
Itsik
Indexed pixel formats are a problem too, not well supported until GDI+ version 1.10 (Vista and up). 8bpp still requires you to map each pixel. Yes, IPP should definitely help, leveraging the CPU vector processing instructions. Four pixels at a time. Beware of alignment problems. The cost of a graphics library won't be a match for your time though.
Hans Passant
Ok Thanks, I'll check out all the options tomorrow.
Itsik