Kinect Infrared gray Pixelformat converting to 8bpp - c#

Our goal is to make a movie from the Infrared images coming from the Kinect. We are using the AForge videowriter, we already have working code to work with a normal RGB stream. (RgbResolution640x480Fps30)
Looking at the documentation ( http://msdn.microsoft.com/en-us/library/microsoft.kinect.colorimageformat.aspx ) the image are in a 16 bits format, but only the first 10 are used? So do we have a 10 bits format image or how does this work?
Looking at the Aforge documentation only the following formats are accepted : 24 or 32 bpp image or grayscale 8 bpp (indexed) image. (http://www.aforgenet.com/framework/docs/html/84a560df-bfd5-e0d6-2812-f810b56a254d.htm)
Why are only 8 bpp indexed images accepted?
Is it possible to transform the 16 (10??) bit images from the Kinect to a 8 bpp indexed image
Or maybe allow AForge to accept 16 bit images as well
Thanks!

Kinect is supposed to produce depth or z with 11 bits of resolution packed in 16bit samples. To work around this problem you can divide the samples by 2^3=8, which would produce blunt results, or use a tone mapping technique like those used in HDR photography. This last one makes sense given the fact that Kinect doesn't have the same resolution for close by objects as for distant ones (see this StackOverflow question) so a non linear mapping can be used between the 11b samples and the 8b reduced resolution as explained in the OpenKinect Wiki.
On the Aforge, I'd say it'd be common to support 8bit gray, 24bit RGB (8bit per plane) and 32bit RGBA (8bit per plane).

AForge can convert to an 8 bit image for you:
Bitmap grayImage8bit = AForge.Imaging.Filters.Grayscale.CommonAlgorithms.BT709.Apply(original_bitmap);
I've been using this to convert 32 bit rgba bitmaps.

Related

Applying LUT on 12 or 16 bit byte array or Mat

Is there an efficient way of applying LUT (look up table of the camera which is derived from a curve that can be configured by user) on 12 or 16 bit image?
Currently I'm using EmguCV for applying noise reduction and edge enhancement. I need to apply LUT on 12 and 16 bit images (stored as byte array).
Currently there is only support for 8bit images.

C++/C# Header of bgr32 bitmap

To my understanding, the srgb32 is only a 24-bit color depth image with 8 bits of padding at the end.
ie, a blue pixel in little endian:
byte1_b = 255
byte2_g = 00
byte3_r = 00
byte4 = 00 //padding
What has got me confused is how should my headers look like to indicate this padded encoding. If I am not mistaken, simply setting the color depth to 32 won't work because that enables alpha channels. How should I encode this?
Edit. This is a project that is done both in C++ and C#. I am using WritableBitmap class to render a fractal image. But the actual image is drawn through the backend api in C++ using P/Invoke. Hence the title is C#/C++ to emphasize that I am working in these two environments.
I found the answer to my question albeit raising more questions. This Microsoft link describes that the high byte is ignored by default. I tested it out and the image seems unchanged regardless of the padded byte.

Why is bmp loading faster than png

I have a sample wpf app here and wondering, why BMP is loading faster than PNG. Here is the exact setup:
- Windows 7
- Visual Studio 2013
- landscape.png, 1920x1080, 2.4mb
- landscape.bmp, 1920x1080, 5.6mb
- wpf-app, class MainWindow.xaml.cs constructor, no other code before
Code:
var sw = Stopwatch.StartNew();
var Bitmap1 = new Bitmap("landscape.bmp");
long t1 = sw.ElapsedMilliseconds;
sw.Restart();
var Bitmap2 = new Bitmap("landscape.png");
long t2 = sw.ElapsedMilliseconds;
So the BMP loads with around 6ms, the PNG needs 40ms.
Why is that so?
First, we need to understand how digital images are stored and shown, a digital image is represented as a matrix where each element of the matrix is the color of the pixel, if you have a grayscale image then each element is a uint8 (unsigned 8-bit integer) number between 0 and 255 and in some cases, it's an int8 (signed 8-bit integer) number between -128 and 127. if the element is 0 (or -128 in int8 version) the color is solid black and if the element is 255 (or 127 in int8 version) the color is solid white.
For RGB images each element of the said matrix takes 24 bit or 3 Byte to store (one Byte for each color), a very common resolution for digital cameras and smartphones is 3264 x 2448 for an 8-megapixel camera, now imagine we want to save a 3264 row matrix where each row has 2448 element and each element is 3 Byte, we need about 24 MegaByte to store that image which is not very efficient for posting on the internet or transferring or most of the other purposes. That is why we should compress the image, we can go for JPEG which is a lossy compression method and that means we do lose some quality or we can choose a lossless compression method like PNG which will give us less compression ratio but instead we are not gonna lose quality.
Whether we chose to compress the image or not, when we want to see the image, we can only show the uncompressed version of the image, if the image is not compressed at all, there is no problem, we show exactly what it is, but if it's compressed, we have to decode it first (uncompress it).
With all that being said, let's answer the question. BMP is a format for somewhat raw images, there is either no compression at all or much fewer compression techniques are used than PNG or JPEG but the file size is bigger. When you want to show a BMP image, because it's bigger, there is more data to read into memory, but when it is read, you can show it very faster because there is either no need for decoding or much less decoding is required, on the other hand when you want to show a PNG image, the image will be read into memory much faster but compared to BMP the decoding is going take more time.
If you have a very slow storage, BMP images will be shown slow.
If you have a very slow CPU or your decoding software is not efficient PNG images will be shown slow.

Convert 24 Bit BMP to Monochrome Bit in C#

How would I go about taking a BMP which is 24 bits and converting it to a Monochrome Bitmap? I am not concerned about losing colors, etc. and I do not want to use another file format.
There are basically two methods. You can use Interop methods to read the raw BMP data and write raw BMP data for a monchrome bitmap. There are googlable functions which will do this.
Or, better, you can use ImageMagickObject to convert the image using a stoichastic dither.
Do the second one.
If you do the first one, you should still use a stocichastic dither, but you will have to implement it by hand.
Edit: You asked "what do the following RGB values become"... the answer is they become what you want them to become. YOU DECIDE.
The obvious choices are to either use a strict threshold, where anything less than X becomes black, anything more becomes white, or you can use a stoichastic dither. Select two thresholds, black Threshold bt and white threshold wt, such that 0 < bt < wt < 255. Then for each point choose a random number q between 0.0. and 1.0. Compare the pixel brightness ((r+g+b)/3) to (q*(wt-bt)+bt). If it is greater or equal, it is white, if less, black. This will give you a nice dithered greyscale. For most purposes 31 and 224 are good values for bt and wt, but for photographic images 0 and 255 might be better.

24 bit data type array to hold 24 bit bitmap file

I am attempting to read a bitmap manually. So I read the bitmap file using a filestream. There wasn't a problem until I had to deal with 24 bit bitmap files. Is there a method to actually read a 24 bitmap image into a 24 bit array ?
I hold a 8 bit bitmap image in a byte array like this
byte[] fileBufferArray = new byte[fileLength];
A few options:
If you're not too worried about memory (you don't have a large number or very large bitmaps open), you can store it as 32-bit numbers instead. Often the fourth byte is then interpreted as "alpha" (a blending specifier when rendering the image on a background.) Most modern image manipulation libraries treat color images in this way now.
You can pack the colors into a byte array and access them individually. RGB and BGR are the two most common packing orders. Usually you also end up putting padding bytes at the end of each row so that the width in bytes lines up with DWORD (4-byte) boundaries.
You can split the image into three separate byte array 'planes', which are basically 8-bit images for Red, Green and Blue respectively. This is another common format when doing image processing, as often your filtering steps operate on channels independently.

Categories

Resources