1

我正在使用 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;
    } 

我想知道您是否让我知道如何根据我的方法计算的深度像素值来计算真实世界的位置。

4

1 回答 1

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)(Bits[0] | Bits[1] << 8);

即使您可以使用 Stéphane Magnenat 给出的更好的近似值进行一些改进,第一种校准方法也应该可以正常工作:

距离 = 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的深度范围为 800 毫米至 4000 毫米。

于 2012-01-01T15:37:36.187 回答