Search code examples
c#colorskinect-sdkdepthkinect-v2

C# and Kinect v2: Get RGB values that fit to depth-pixel


I played a bit around with the Kinect v2 and C# and tried to get a 512x424 pixel-sized image array that contains depth data aswell as the regarding color information (RGBA).

Therefore I used the MultiSourceFrameReader class to receive a MultiSourceFrame from which I got the ColorFrame and DepthFrame. With the methods ColorFrame.CopyConvertedFrameDataToArray() and DepthFrame.CopyFrameDataToArray() I received the arrays that hold color and depth information:

// Contains 4*1920*1080 entries of color-info: BGRA|BGRA|BGRA..
byte[] cFrameData = new byte[4 * cWidth * cHeight];
cFrame.CopyConvertedFrameDataToArray(cFrameData, ColorImageFormat.Bgra);

// Has 512*424 entries with depth information
ushort[] dFrameData = new ushort[dWidth* dHeight];
dFrame.CopyFrameDataToArray(dFrameData);

Now I would have to map the color-quadruples that live within the ColorFrame-data-array cFrameData to each of the entries of the DepthFrame-data-array dFrameData but that's where I'm stuck. Output should be an array that is 4 times (RGBA/BGRA) the size of the dFrameData array and contains the color information to each pixel of the depth-frame:

// Create the array that contains the color information for every depth-pixel
byte[] dColors = new byte[4 * dFrameData.Length];
for (int i = 0, j = 0; i < cFrameData.Length; ++i)
{
    // The mapped color index. ---> I'm stuck here:
    int colIx = ?;

    dColors[j]     = cFrameData[colIx];     // B
    dColors[j + 1] = cFrameData[colIx + 1]; // G
    dColors[j + 2] = cFrameData[colIx + 2]; // R
    dColors[j + 3] = cFrameData[colIx + 3]; // A
    j += 4;
}

Does anyone have any suggestions?

I also took a look at the Kinect-SDK's CoordinateMappingBasics example but they did it vice versa for the 1920x1080 pixel-sized image which I already got to work.

Edit
I recognized that I should be able to get the mapped color information by using the ColorSpacePoint-struct which contains the X and Y coordinates to the specific color pixel. Therefore I set up the points like..

// Lookup table for color-point information
ColorSpacePoint[] cSpacePoints = new ColorSpacePoint[dWidth * dHeight];    
this.kinectSensor.CoordinateMapper.MapDepthFrameToColorSpace(dFrameData, cSpacePoints);

.. and tried to access the color information like ..

int x = (int)(cSpacePoints[i].X + 0.5f);
int y = (int)(cSpacePoints[i].Y + 0.5f);
int ix = x * cWidth + y;
byte r = cFrameData[ix + 2];
byte g = cFrameData[ix + 1];
byte b = cFrameData[ix];
byte a = cFrameData[ix + 3];

.. but I'm still getting the wrong colors. Mostly white ones.


Solution

  • Well, I figured it out by myself. The error was trivial. As the array is not a pixel-array where one entry contains RGBA information but a byte array where each entry represents either R, G, B or A I had to multiply the index by the bytes-per-pixel value which in this case is 4. So the solution looks like:

    int ix = (x * cWidth + y) * 4;
    byte r = cFrameData[ix + 2];
    byte g = cFrameData[ix + 1];
    byte b = cFrameData[ix];
    byte a = cFrameData[ix + 3];