【问题标题】:IndexOutOfRange Exception while trying to get color values from Kinect v2 in C#尝试从 C# 中的 Kinect v2 获取颜色值时出现 IndexOutOfRange 异常
【发布时间】:2017-12-15 05:53:19
【问题描述】:

我正在尝试获取 Kinect v2 中每个 CameraSpacePoint 的 RGB 值。在尝试访问转换后的帧数据时,代码正在抛出 IndexOutOfRangeException。我发现以下几行抛出了这个错误:

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

请看下面的完整代码:

int depthWidth = kinectSensor.DepthFrameSource.FrameDescription.Width;
int depthHeight = kinectSensor.DepthFrameSource.FrameDescription.Height;
int colorWidth = kinectSensor.ColorFrameSource.FrameDescription.Width;
int colorHeight = kinectSensor.ColorFrameSource.FrameDescription.Height;

ushort[] depthData = new ushort[depthWidth * depthHeight];
CameraSpacePoint[] cameraPoints = new CameraSpacePoint[depthData.Length];
ColorSpacePoint[] colorPoints = new ColorSpacePoint[depthData.Length];

// Assuming RGBA format here
byte[] pixels = new byte[colorWidth * colorHeight * 4];

depthFrame = multiSourceFrame.DepthFrameReference.AcquireFrame();
colorFrame = multiSourceFrame.ColorFrameReference.AcquireFrame();

if ((depthFrame == null) || (colorFrame == null))
{
    return;
}

depthFrame.CopyFrameDataToArray(depthData);
coordinateMapper.MapDepthFrameToCameraSpace(depthData, cameraPoints);
coordinateMapper.MapDepthFrameToColorSpace(depthData, colorPoints);

// We are using RGBA format
colorFrame.CopyConvertedFrameDataToArray(pixels, ColorImageFormat.Rgba);

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

    if (u < 0 || u >= colorWidth || v < 0 || v >= colorHeight) continue;

    int pixelsBaseIndex = (int)(v * colorWidth + u);
    try
    {
        byte red = pixels[4 * pixelsBaseIndex + 0];
        byte green = pixels[4 * pixelsBaseIndex + 1];
        byte blue = pixels[4 * pixelsBaseIndex + 2];
        byte alpha = pixels[4 * pixelsBaseIndex + 3];
    }
    catch (IndexOutOfRangeException ex)
    {
        int minValue = 4 * pixelsBaseIndex;
        int maxValue = 4 * pixelsBaseIndex + 3;
        Console.WriteLine((minValue > 0) + ", " + (maxValue < pixels.Length));
    }
}

代码看起来不错,但是我不确定我在这里缺少什么! 如何避免IndexOutOfRangeException 异常?有什么建议吗?

【问题讨论】:

  • 您是否尝试控制台记录pixelBaseIndex 和pixels.Length,我猜colorPoints 可能会导致奇怪的索引,据我了解CopyConvertedFrameDataToArray 使字节数组为4 个字节
  • @whoisthis:非常感谢。我做到了。请看这个Console.WriteLine("pixelsBaseIndex:" + pixelsBaseIndex + ", pixels.Length:" + pixels.Length + ", minValue:" + minValue + ", maxValue:" + maxValue); prints pixelsBaseIndex:2074817, pixels.Length:8294400, minValue:8299268, maxValue:8299271 pixelsBaseIndex 正在改变,因此上面的输出只是一个 sn-p
  • @whoisthis:有什么建议吗?

标签: c# kinect kinect-v2


【解决方案1】:

第一件事pixelsBaseIndex =&lt; 2070601(2070601 = 1919 * 1079)

2074817pixelsBaseIndex 的无效值。

这个错误可能在这里。

if (u < 0 || u >= colorWidth || v < 0 || v >= colorHeight) continue;

int pixelsBaseIndex = (int)(v * colorWidth + u);

最好的办法是控制台日志u, v, colorWidth, colorHeight 并验证它们。

编辑

正如我所怀疑的,它是由浮点运算引起的。 将一帧映射到另一帧需要复杂的矩阵计算,因此 u,v 得到浮点值。请记住,u,v 是颜色空间的像素坐标。它们必须是非负整数。

我推荐的解决方案是

...
    int u = (int) Math.Floor(colorPoints[index].X);
    int v = (int) Math.Floor(colorPoints[index].Y);

    if (u < 0 || u >= colorWidth || v < 0 || v >= colorHeight) continue;
...

仅供参考

查看以下代码行以了解为什么 u、v 像素坐标获取浮点值。决定是发言还是丢弃无效值取决于开发人员,因为在任何一种情况下,您都会丢失某种信息。例如,取地板意味着您正在取最近像素的颜色。

在我个人的选择中,输出更精确的值(因此浮点值)对于对输出值进行更多计算的开发人员很重要。例如,点云注册。

depth_to_color

calculating x offset for rgb image based on depth value

【讨论】:

  • 我记录了所有 uv 变量并打印了最大/最小值。看到这个min u:169.4572, max u:1750.199, min v:0.009765625, max v:1079.988, colorWidth:1920, colorHeight:1080 如果我计算pixelsBaseIndex,基于这些值,它会产生IndexOutOfRange1079.988 * 1920 + 1750.199 = 2075327.159
  • 这行得通。后来我意识到问题是因为casting而发生的。 但是,我无法理解ColorSpacePoint 的像素坐标在float 中的事实!
猜你喜欢
  • 2014-04-30
  • 1970-01-01
  • 1970-01-01
  • 2023-04-09
  • 2021-09-13
  • 1970-01-01
  • 1970-01-01
  • 2021-10-05
  • 1970-01-01
相关资源
最近更新 更多