简体   繁体   English

Kinect v2 + Unity-> MapDepthFrameToColorSpaceUsingIntPtr

[英]Kinect v2 + Unity -> MapDepthFrameToColorSpaceUsingIntPtr

I'm trying to map the Depth Data from KinectV2 to the Color Space in a Unity-Script. 我正在尝试在Unity脚本中将深度数据从KinectV2映射到色彩空间。 It worked as expected with the usual coordinate mapper function 使用通常的坐标映射器功能可以正常工作

_sensor.CoordinateMapper.MapDepthFrameToColorSpace(_depthData, _colorSpacePoints)

But it reduced my Framerate by 11 - wich is not acceptable =) 但这将我的帧率降低了11-不可接受=)

Therefore i took a look in the unity examples provided by Microsoft and found some piece for Mapping working with Pointer. 因此,我查看了Microsoft提供的统一示例,并发现了一些与Pointer一起使用Mapping的示例。

var pDepthData = GCHandle.Alloc(pDepthBuffer, GCHandleType.Pinned);
var pDepthCoordinatesData = GCHandle.Alloc(m_pDepthCoordinates, GCHandleType.Pinned);

m_pCoordinateMapper.MapColorFrameToDepthSpaceUsingIntPtr(
        pDepthData.AddrOfPinnedObject(), 
        (uint)pDepthBuffer.Length * sizeof(ushort),
        pDepthCoordinatesData.AddrOfPinnedObject(), 
        (uint)m_pDepthCoordinates.Length);

pDepthCoordinatesData.Free();
pDepthData.Free();

The equivalent method for my needs exist as well. 也存在满足我需求的等效方法。 I tried the pointer version of MapDepthFrameToColorSpace 我尝试了MapDepthFrameToColorSpace的指针版本

var pDepthData = GCHandle.Alloc(pDepthBuffer, GCHandleType.Pinned);
var pColorData = GCHandle.Alloc(m_pColorSpacePoints, GCHandleType.Pinned);

m_pCoordinateMapper.MapDepthFrameToColorSpaceUsingIntPtr(
        pDepthData.AddrOfPinnedObject(), 
        pDepthBuffer.Length * sizeof(ushort),
        pColorData.AddrOfPinnedObject(),
        (uint)m_pColorSpacePoints.Length * sizeof(float) * 2);

pColorData.Free();
pDepthData.Free();

The pDepthBuffer has valid data at method call and m_pColorSpacePoints is initialized and has the same length as pDepthBuffer (as recommended in the MSDN Documentation) Im still working with 1408 SDK version. pDepthBuffer在方法调用时具有有效数据,并且m_pColorSpacePoints已初始化,并且具有与pDepthBuffer相同的长度(如MSDN文档中的建议)。Im仍在使用1408 SDK版本。 The Result after the Function is an Array with Empty/NegativeInfinity Float values and no valid ColorSpacePoints. 函数之后的结果是一个数组,其值为Empty / NegativeInfinity Float,并且没有有效的ColorSpacePoints。 No Error-Message as well. 也没有错误消息。 Any suggestions? 有什么建议么?

I got it working. 我知道了 After updating to the latest SDK Version 1409 the messageall returned the error message 更新到最新的SDK版本1409后,messageall返回错误消息

ArgumentException: Value does not fall within the expected range. Rethrow as ArgumentException: This API has returned an exception from an HRESULT: 0x80070057

So i played a little bit with the parameters and now i'm getting valid Data. 所以我使用了一些参数,现在我得到了有效的数据。

Here are my modifications to the CoordinateMapperManager of the GreenScreen Example. 这是我对GreenScreen示例的CoordinateMapperManager的修改。 I added a buffer for the mapped color values to get a pixel position in the HD Color Stream by a depth value position, 我为映射的颜色值添加了一个缓冲区,以通过深度值位置获取HD Color Stream中的像素位置,

//added declaration and initialization
private ColorSpacePoint[] m_pColorSpacePoints;

//in awake method
m_pColorSpacePoints = new ColorSpacePoint[pDepthBuffer.Length];

//accesor to the colorspacepoints
public ColorSpacePoint[] GetColorSpacePointBuffer()
{
  return m_pColorSpacePoints;
}

//the new process frame method
void ProcessFrame()
{
  var pDepthData = GCHandle.Alloc(pDepthBuffer, GCHandleType.Pinned);
  var pDepthCoordinatesData = GCHandle.Alloc(m_pDepthCoordinates, GCHandleType.Pinned);
  var pColorData = GCHandle.Alloc(m_pColorSpacePoints, GCHandleType.Pinned);

  m_pCoordinateMapper.MapColorFrameToDepthSpaceUsingIntPtr(
    pDepthData.AddrOfPinnedObject(), 
    (uint)pDepthBuffer.Length * sizeof(ushort),
    pDepthCoordinatesData.AddrOfPinnedObject(), 
    (uint)m_pDepthCoordinates.Length);


  m_pCoordinateMapper.MapDepthFrameToColorSpaceUsingIntPtr(
    pDepthData.AddrOfPinnedObject(),
    pDepthBuffer.Length * sizeof(ushort),
    pColorData.AddrOfPinnedObject(),
    (uint)m_pColorSpacePoints.Length);

  pColorData.Free();
  pDepthCoordinatesData.Free();
  pDepthData.Free();

  m_pColorRGBX.LoadRawTextureData(pColorBuffer);
  m_pColorRGBX.Apply ();
}

And here an example how to use it. 这里是一个如何使用它的例子。 I used Untiy to do the rendering in GPU Shader. 我使用Untiy在GPU Shader中进行渲染。 The following Code is a shortened untested piece of code for demonstration how to get the data: 以下代码是经过简化的未经测试的代码段,用于演示如何获取数据:

//Size of the Kinect V2 Depth Stream
var _width = 512;
var _height = 424;
var _particleCount = _width * _height;

//Initialize an Array to store position data for particles
var _particleArray = new Vector3[_particleCount];
var _colorArray = new Color[_particleCount];

//Get Depth Data
var _depthData = _coordinateMapperManager.GetDepthPointBuffer();

//Get Mapped Color Space Points
var _colorSpacePoints = _coordinateMapperManager.GetColorSpacePointBuffer();

//Get the Colorstream as Texture
var _texture = _coordinateMapperManager.GetColorTexture();

var c = 0;
for (var i = 0; i < _height; ++i)
{
  for (var j = 0; j < _width; ++j)
  {
    _particleArray[c++] = new Vector3(j, i);
  }
}

for (var i = 0; i < _depthData.Length; ++i)
{
    _colorArray[i] = _texture.GetPixel((int)_colorSpacePoints[i].X, (int)_colorSpacePoints[i].Y);
    _particleArray[i].z = _depthData[i];
}

//Now we have all Data to build a colored 3D PointCloud

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM