1

I am trying to get the RGB values of each CameraSpacePoint in Kinect v2. I an able to acquire the CameraSpacePoints and Color pixels. But it seems that the mapping from CameraSpacePoints to Color pixel is broken in my code, which is leading me to IndexOutOfRangeException.

Please see the code snippet below showing data collection part:

var depthWidth = depthFrame.FrameDescription.Width;
var depthHeight = depthFrame.FrameDescription.Height;
ushort[] depthData = new ushort[depthWidth * depthHeight];

var colorWidth = colorFrame.FrameDescription.Width;
var colorHeight = colorFrame.FrameDescription.Height;
byte[] pixels = new byte[colorWidth * colorHeight * 4];

CameraSpacePoint[] cameraSpacePoints = new CameraSpacePoint[depthData.Length];
ColorSpacePoint[] colorSpacePoints = new ColorSpacePoint[depthData.Length];

depthFrame.CopyFrameDataToArray(depthData);
coordinateMapper.MapDepthFrameToCameraSpace(depthData, cameraSpacePoints);
coordinateMapper.MapDepthFrameToColorSpace(depthData, colorSpacePoints);

// Assuming RGBA format here
colorFrame.CopyConvertedFrameDataToArray(pixels, ColorImageFormat.Rgba);

Please see the code below showing the RGB values from ColorSpacePoints:

for (var index = 0; index < depthData.Length; index++)
{
    var u = colorSpacePoints[index].X;
    var v = colorSpacePoints[index].Y;
    int pixelsBaseIndex = (int)(v * depthWidth + u);

    byte red   = pixels[4 * pixelsBaseIndex + 0];
    byte green = pixels[4 * pixelsBaseIndex + 1];
    byte blue  = pixels[4 * pixelsBaseIndex + 2];
    byte alpha = pixels[4 * pixelsBaseIndex + 3];
}

The above code snippet is throwing following error:

IndexOutOfRangeException: Index was outside the bounds of the array.

To debug the issue, I monitored each index then calculated minimum and maximum index value as following:

List<int> allIndex = new List<int>();
for (var index = 0; index < depthData.Length; index++)
{
    var u = colorpoints[index].X;
    var v = colorpoints[index].Y;
    int pixelsBaseIndex = (int)(v * depthWidth + u);

    allIndex.Add(pixelsBaseIndex);
}

var maxIndex = allIndex.Max();
var minIndex = allIndex.Min();
Console.WriteLine(minIndex);//Prints -2147483648
Console.WriteLine((maxIndex < pixels.Length) && (minIndex >= 0));//Prints False

Surprisingly the minimum index is -2147483648. Any guess? Am I missing something obvious here?

Ravi Joshi
  • 5,124
  • 15
  • 58
  • 123
  • Possible duplicate of [What causes a java.lang.ArrayIndexOutOfBoundsException and how do I prevent it?](https://stackoverflow.com/questions/5554734/what-causes-a-java-lang-arrayindexoutofboundsexception-and-how-do-i-prevent-it) – Progman Nov 26 '17 at 10:15

2 Answers2

1
   for (var index = 0; index < depthData.Length; index++) {
     int u = (int) Math.Floor(colorPoints[index].X);
     int v = (int) Math.Floor(colorPoints[index].Y);

     /*
     1. not every depth pixel has a corresponding color pixel.
        So always check whether u,v are valid or not
     */
     if ((0 <= u) && (u < colorWidth) && (0 <= v) && (v < colorHeight)) {

      /*
      2. now u,v are pixel coordinates in colorspace,
         so to get the index of the corresponding pixel,
         you need to multiply v by colorWidth instead of depthwidth
       */
      int pixelsBaseIndex = v * colorWidth + u;

      byte red = pixels[4 * pixelsBaseIndex + 0];
      byte green = pixels[4 * pixelsBaseIndex + 1];
      byte blue = pixels[4 * pixelsBaseIndex + 2];
      byte alpha = pixels[4 * pixelsBaseIndex + 3];
     }


   }

If you need more reference, please check the following, It is an another implementation of registration in C++. but you can understand the concept.

Kinect Registration

Surprisingly the minimum index is -2147483648. Any guess?

If you check the values of raw depth frame, you will find some invalid depth values. Depth range of Kinect v2 is 0.5m to 4.5m. All the objects outside of this range causes invalid depth values. These values causes the -2147483648. You can either preprocess these invalid values or ignore them.

Ravi Joshi
  • 5,124
  • 15
  • 58
  • 123
Shanil Fernando
  • 1,176
  • 9
  • 13
0

try this

     bool flag = true;

   for (int i = 1; (i <= ((depthData.Length)- 1)) && flag; i++)
        {
            flag = false;
            for (int j = 0; j < ((depthData.Length)- 1); j++)
            {
            //You Statements Goes here
            flag = true;

            }
Muhammad Ali
  • 129
  • 7
  • This is not so interesting. I would better do following: `int pixelsBaseIndex = (int)(v * depthWidth + u); if pixelsBaseIndex < 0: continue;` – Ravi Joshi Nov 23 '17 at 10:05