我正在使用Kinect传感器开发3D模型重建应用程序。我使用Microsoft SDK获取深度数据,我想计算现实世界中每个点的位置。我已经阅读了几篇关于它的文章,我已经实现了几种深度校准方法,但它们都不能在我的应用程序中工作。最接近的校准是http://openkinect.org/wiki/Imaging_Information 但我在Meshlab的结果是不可接受的。 我通过这种方法计算深度值:
private double GetDistance(byte firstByte, byte secondByte)
{
double distance = (double)(firstByte >> 3 | secondByte << 5);
return distance;
}
然后我用下面的方法来计算真实世界的距离
public static float RawDepthToMeters(int depthValue)
{
if (depthValue < 2047)
{
return (float)(0.1 / ((double)depthValue * -0.0030711016 + 3.3309495161));
}
return 0.0f;
}
public static Point3D DepthToWorld(int x, int y, int depthValue)
{
const double fx_d = 5.9421434211923247e+02;
const double fy_d = 5.9104053696870778e+02;
const double cx_d = 3.3930780975300314e+02;
const double cy_d = 2.4273913761751615e+02;
double depth = RawDepthToMeters(depthValue);
Point3D result = new Point3D((float)((x - cx_d) * depth / fx_d),
(float)((y - cy_d) * depth / fy_d), (float)(depth));
return result;
}
这些方法效果不佳,生成的场景不正确。然后我用下面的方法,结果比以前的方法更好但是还不行。
public static Point3D DepthToWorld(int x, int y, int depthValue)
{
const int w = 640;
const int h = 480;
int minDistance = -10;
double scaleFactor = 0.0021;
Point3D result = new Point3D((x - w / 2) * (depthValue + minDistance) * scaleFactor * (w/h),
(y - h / 2) * (depthValue + minDistance) * scaleFactor,depthValue);
return result;
}
我想知道您是否让我知道如何根据我的方法计算的深度像素值来计算实际位置。
答案 0 :(得分:1)
您用来计算真实深度的getDistance()
函数是指kinect播放器检测。因此,请检查您是否相应地打开了kinect流,或者您应该只获取原始深度数据
Runtime nui = Runtime.Kinects[0] ;
nui.Initialize(RuntimeOptions.UseDepth);
nui.DepthStream.Open(
ImageStreamType.Depth,
2,
ImageResolution.Resolution320x240,
ImageType.Depth);
然后通过简单地将第二个字节移位8来计算深度:
距离(0,0)=(int)(位[0] |位[1]&lt;&lt; 8);
即使您可以做一点改进,第一种校准方法也可以正常工作 使用StéphaneMagnenat给出的更好的近似值:
距离= 0.1236 * tan(rawDisparity / 2842.5 + 1.1863)米(
)
如果您确实需要更准确的校准值,您应该使用例如matlab kinect校准等工具来校准您的kinect:
http://sourceforge.net/projects/kinectcalib/
并仔细检查Nicolas Burrus提供的目前使用的值。
修改强>
再次阅读您的问题我发现您使用的是 Microsoft SDK ,因此值
从kinect传感器返回的已经实际距离(mm)。您不需要使用RawDepthToMeters()
函数,它只能用于非官方sdk。
硬件创建深度图,它是视差值的非线性函数,并且具有11位精度。 kinect sdk驱动程序将此差异值转换为mm,并将其舍入为整数。 MS Kinect SDK具有 800mm至4000mm 深度范围。