Kinect Point云彩错位

时间:2013-01-28 16:31:26

标签: kinect camera-calibration calibration point-clouds kinect-sdk

我正在开发Kinect Point Cloud Application vi kinect SDK 1.5。到目前为止,我能够将kinect深度设置为真实世界坐标并获得点云。为了达到这个目的,我使用Matthew Fisher的代码将kinect深度传感器相机校准到2d rgb帧,该代码在以下链接中共享(http:/ /graphics.stanford.edu/~mdfisher/Kinect.html)。我在C#上修改了kinect sdk的代码。 (深度以毫米为单位):

     Hashtable preparePointCloud(short[] rawDepthData)
    {//simple holds the 3d point of 2d rgb pixels Y*640+X coordinates
        //for instance: 3D point location of x:100 y:50 (in 2d coordinates) is restored in key: 640*50 + 100 in hashtable

        Hashtable VectorList = new Hashtable();
        int x = 0;
        int y = 0;
        //rawdepthData holds y*640+x coordinates depth in mm that comes from depth frame. So by only looking the the key of hashtable color of the 3D point easly can be found.
        for (int i = 0; i < rawDepthData.Length; i++)
        {
            int z = rawDepthData[i];
            //int z = rawDepthData[y*640+x];
            if (z > 1)//don't add the unknown values "-1"
            {
                Vector3 temp = DepthToWorld(x_, y_, z);
                Vector2 color = WorldToColor(ref temp);
                int colorindex = (int)((color.Y) * 640 + (color.X));
                if (VectorList[colorindex] == null)
                {
                    VectorList.Add(colorindex, temp);
                }
            }

            x++;
            if (x == 640)
            {
                x = 0;
                y++;
                if (y == 480)
                    break;
            }
        }
        return VectorList;

    }

    Vector3 DepthToWorld(int x, int y, int depthValue)
    {
        Vector3 result;
        double depth = (double)(depthValue)/1000;   //mm to meter

        result.X = (float)((x - cx_d) * depth * fx_d);
        result.Y = (float)((y - cy_d) * depth * fy_d);
        result.Z = (float)depth;

        return result;
    }

    Vector2 WorldToColor(ref Vector3 pt)
    {
        OpenTK.Vector4 transformedPos_ = OpenTK.Vector4.Transform(new OpenTK.Vector4(pt,1.0f), depthCalibrationTransformationMatrix);
        Vector3 transformedPos = transformedPos_.Xyz;


        float invZ = 1.0f / transformedPos.Z;

        Vector2 result = new Vector2();

        double xValue = ((transformedPos.X * fx_rgb * invZ) + cx_rgb);
        result.X = (float)Math.Round(xValue, 0, System.MidpointRounding.AwayFromZero);


        double yValue = ((transformedPos.Y * fy_rgb * invZ) + cy_rgb);
        result.Y = (float)Math.Round(yValue, 0, System.MidpointRounding.AwayFromZero);

        colorrecord.Add(result);
        return result;
    }

同样找到点云准备进度如下:

                foreach (int rgbCoor in previousDepthListWithKeysTheseAreEqualTo_Y_Times640Plus_X.Keys)
                {
                    PointCloud.rigidPointCloudLocationList.Add((Vector3) previousDepthListWithKeysTheseAreEqualTo_Y_Times640Plus_X[rgbCoor]); 
                    //add the point coorinatis to the point cloud

                    //obtain the color
                    Vector3 point = (Vector3)previousDepthListWithKeysTheseAreEqualTo_Y_Times640Plus_X[rgbCoor];
                    Vector2 coor = WorldToColor(ref point);//in order to check Am I looking the correct coordinates
                    int indexCoor = 640 * (int)coor.Y + (int)coor.X;

                    Color color_ = Color.FromArgb(previousRawColorData[rgbCoor*4], previousRawColorData[rgbCoor*4 + 1], previousRawColorData[rgbCoor*4 + 2]);        
                    PointCloud.rigidPointCloudColorList.Add(color_.ToArgb());
                    //now add the color And the color and 3d locaiton info will be on the same List index (double checked)
                }

总结我的校准进度有问题。颜色和点云不匹配。有些开发人员使用Fisher的方法进行kinect校准没有问题。或者我错过了一些东西。我的实验中的一些screeenshots列出如下:

2D rgb picture

Point cloud view

这对你来说是个类似的问题吗?因为我没有领导。

最后,我想问一个关于点云视图的问题。点云显示像网格表面的点(参见上面的最后一张图)。这是正常的吗?

提前致谢。

更新:有没有人知道这段代码是什么?:

result.x = Utility :: Bound(Math :: Round((transformedPos.x * fx_rgb * invZ)+ cx_rgb),0,639);

result.y = Utility :: Bound(Math :: Round((transformedPos.y * fy_rgb * invZ)+ cy_rgb),0,479);

我找不到任何关于“Utility :: Bound()”的解释?

0 个答案:

没有答案