Microsoft Kinect SDK深度校准 [英] Microsoft Kinect SDK Depth calibration

查看:106
本文介绍了Microsoft Kinect SDK深度校准的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用Kinect传感器进行3D模型重建应用程序.我使用Microsoft SDK来获取深度数据,我想计算现实中每个点的位置.我已经阅读了几篇有关它的文章,并且已经实现了几种深度校准方法,但是所有这些方法都不适用于我的应用程序.最接近的校准是 http://openkinect.org/wiki/Imaging_Information 但是我在Meshlab中的结果是不可接受的. 我通过这种方法计算深度值:

I am working on a 3D model reconstruction application with Kinect sensor. I use Microsoft SDK to get depth data, I want to calculate the location of each point in the real-world. I have read several articles about it and I have implemented several depth-calibration methods but all of them do not work in my application. the closest calibration was http://openkinect.org/wiki/Imaging_Information but my result in Meshlab was not acceptable. I calculate depth value by this method:

    private double GetDistance(byte firstByte, byte secondByte)
    {
        double distance = (double)(firstByte >> 3 | secondByte << 5);
        return distance;
    }

然后我使用下面的方法来计算真实世界的距离

and then I used below methods to calculate distance of real-world

    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;
    }

这些方法效果不佳,生成的场景不正确.然后我使用下面的方法,结果比以前的方法要好,但是还不能接受.

these methods did not work well and generated scene was not correct. then I used below method, the result is better than previous method but it is not acceptable yet.

    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;
    } 

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

I was wondering if you let me know how can I calculate real-world position based on my depth pixel values calculating by my method.

推荐答案

您用于计算真实深度的getDistance()函数称为kinect播放器检测.因此,请检查您是否相应地打开了kinect流,或者也许您应该只获取原始深度数据

The getDistance() function you're using to calculate real depth is referred to kinect player detection. So check that you are opening your kinect stream accordingly or maybe you should get only the raw depth data

Runtime nui = Runtime.Kinects[0] ;
nui.Initialize(RuntimeOptions.UseDepth);
nui.DepthStream.Open(
   ImageStreamType.Depth, 
   2, 
   ImageResolution.Resolution320x240, 
   ImageType.Depth);

然后通过将第二个字节简单地移位8位来计算深度:

and then compute depth by simply bitshifting second byte by 8:

距离(0,0)=(int)(位[0] |位[1]<< 8);

Distance (0,0) = (int)(Bits[0] | Bits[1] << 8);

即使可以做一些改进,第一种校准方法也应该可以 使用StéphaneMagnenat给出的更好的近似值:

The first calibration methods should work ok even if you could do a little improvement using a better approximation given by Stéphane Magnenat:

距离= 0.1236 * tan(rawDisparity/2842.5 + 1.1863)以米为单位

distance = 0.1236 * tan(rawDisparity / 2842.5 + 1.1863) in meters

如果您确实需要更准确的校准值,则应该使用例如matlab kinect校准之类的工具来真正校准kinect:

If you really need more accurate calibration values you should really calibrate your kinect using for example a tool such as the matlab kinect calibration:

http://sourceforge.net/projects/kinectcalib/

然后使用Nicolas Burrus提供的当前值再次仔细检查获得的值.

And double check obtained values with the ones you are currently using provided by Nicolas Burrus.

编辑

再次阅读您的问题,我注意到您正在使用 Microsoft SDK ,因此 kinect传感器返回的距离已经以毫米为单位的实际距离.您不需要使用RawDepthToMeters()函数,它仅应与非官方sdk一起使用.

Reading your question again I noticed that you are using Microsoft SDK, so the values that are returned from kinect sensor are already real distances in mm. You do not need to use the RawDepthToMeters() function, it should be used only with non official sdk.

硬件创建深度图,它是视差值的非线性函数,并且具有11位精度. kinect sdk驱动程序立即将视差值转换为mm,并将其四舍五入为整数. MS Kinect SDK的深度范围为 800mm至4000mm .

The hardware creates a depth map, that it is a non linear function of disparity values, and it has 11 bits of precision. The kinect sdk driver convert out of the box this disparity values to mm and rounds it to an integer. MS Kinect SDK has 800mm to 4000mm depth range.

这篇关于Microsoft Kinect SDK深度校准的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆