我已经在这个问题上研究了很长时间了,并且还处于创造力的尽头,所以希望有人可以帮助我指出正确的方向。我一直在使用Kinect,并尝试将数据捕获到MATLAB。幸运的是,有很多方法可以做到这一点(我目前正在使用http://www.mathworks.com/matlabcentral/fileexchange/30242-kinect-matlab)。当我尝试将捕获的数据投影到3D时,我的传统方法给出的重建结果很差。

长话短说,我最终为Matlab编写了Kinect SDK包装器,该包装器执行了重建和对齐。重建工作就像一场梦,但是...

正如您在此处看到的那样,我在对齐方面遇到了很多麻烦:

请不要仔细看模型:(。

如您所见,对齐方式不正确。我不确定为什么会这样。我已经读过很多论坛,在这些论坛上,其他人使用相同的方法比我获得了更大的成功。

我当前的管道使用Kinect Matlab(使用Openni)捕获数据,使用Kinect SDK进行重建,然后使用Kinect SDK进行对齐(通过NuiImageGetColorPixelCoordinateFrameFromDepthPixelFrameAtResolution)。我怀疑这可能是由于Openni造成的,但是在创建使用Kinect SDK捕获的mex函数调用方面,我收效甚微。

如果有人能指出我应该更深入研究的方向,将不胜感激。

编辑:

图我应该发布一些代码。这是我用于对齐的代码:

    /* The matlab mex function */
    void mexFunction( int nlhs, mxArray *plhs[], int nrhs,
            const mxArray *prhs[] ){

        if( nrhs < 2 )
        {
            printf( "No depth input or color image specified!\n" );
            mexErrMsgTxt( "Input Error" );
        }

        int width = 640, height = 480;

        // get input depth data

        unsigned short *pDepthRow = ( unsigned short* ) mxGetData( prhs[0] );
        unsigned char *pColorRow = ( unsigned char* ) mxGetData( prhs[1] );

        // compute the warping

        INuiSensor *sensor = CreateFirstConnected();
        long colorCoords[ 640*480*2 ];
        sensor->NuiImageGetColorPixelCoordinateFrameFromDepthPixelFrameAtResolution(
                NUI_IMAGE_RESOLUTION_640x480, NUI_IMAGE_RESOLUTION_640x480,
                640*480, pDepthRow, 640*480*2, colorCoords );
        sensor->NuiShutdown();
        sensor->Release();

        // create matlab output; it's a column ordered matrix ;_;

        int Jdimsc[3];
        Jdimsc[0]=height;
        Jdimsc[1]=width;
        Jdimsc[2]=3;

        plhs[0] = mxCreateNumericArray( 3, Jdimsc, mxUINT8_CLASS, mxREAL );
        unsigned char *Iout = ( unsigned char* )mxGetData( plhs[0] );

        for( int x = 0; x < width; x++ )
            for( int y = 0; y < height; y++ ){

                int idx = ( y*width + x )*2;
                long c_x = colorCoords[ idx + 0 ];
                long c_y = colorCoords[ idx + 1 ];

                bool correct = ( c_x >= 0 && c_x < width
                        && c_y >= 0 && c_y < height );
                c_x = correct ? c_x : x;
                c_y = correct ? c_y : y;

                Iout[ 0*height*width + x*height + y ] =
                        pColorRow[ 0*height*width + c_x*height + c_y ];
                Iout[ 1*height*width + x*height + y ] =
                        pColorRow[ 1*height*width + c_x*height + c_y ];
                Iout[ 2*height*width + x*height + y ] =
                        pColorRow[ 2*height*width + c_x*height + c_y ];

            }

    }

最佳答案

对于立体视觉系统,这是一个众所周知的问题。不久前,我遇到了同样的问题。我发布的原始问题可以在here中找到。我试图做的事情与此类似。但是,经过大量研究,我得出的结论是捕获的数据集不容易对齐。

另一方面,在记录数据集时,您可以轻松地使用函数调用来对齐RGB和深度数据。此方法在OpenNI和Kinect SDK中均可用(功能相同,而函数调用的名称各不相同)

看起来您正在使用Kinect SDK捕获数据集,可以使用MapDepthFrameToColorFrame将数据与Kinect SDK对齐。

由于您还提到了使用OpenNI,因此请查看AlternativeViewPointCapability

我没有使用Kinect SDK的经验,但是对于OpenNI v1.5,在注册记录器节点之前,通过执行以下函数调用解决了整个问题:

depth.GetAlternativeViewPointCap().SetViewPoint(image);

其中image是图像生成器节点,而depth是深度生成器节点。这是旧版SDK所取代,而旧版SDK已被OpenNI 2.0 SDK取代。因此,如果您使用的是最新的SDK,则函数调用可能会有所不同,但是总体过程可能会相似。

我还添加了一些示例图像:

如果不使用上述对齐功能,则未对齐RGB上的深度边缘

使用该函数调用时,深度边缘会完全对齐(有一些红外阴影区域显示了某些边缘,但它们只是无效的深度区域)

10-07 19:12
查看更多