我有一个问题,关于如何解释使用Microsoft Kinect传感器和OpenNI从深度到真实世界坐标的转换给出的结果 . 使用Visual Studio 2015 C,OpenNI 2.0和OpenCV 2.4

该库工作正常,我能够获得深度图,然后在特定像素中使用“openni :: CoordinateConverter :: convertDepthToWorld”并获得其x,y,z世界坐标 .

令人困惑的是当我选择两个像素并获得它们之间的x距离(水平距离)时,该值根据这些像素的深度而不同 . 例如,我将Kinect传感器指向实心墙,并在其上销售两个参考点 . 然后我转到Kinect的深度视图,我定位这两个点(像素位置),我提取x,y,z坐标 . 但是,如果Kinect传感器距离墙壁700mm,则这两点之间的x距离与我将Kinect 1000mm从墙壁上放置的值不同 .

所以问题是,世界上两个固定点之间的距离是否与深度一起变化是正确的?当我向前或向后移动传感器(到墙壁)时,我期待它们之间的距离是相同的 .

谢谢 .


try {
    openni::OpenNI::initialize();

    openni::Device device;
    auto ret = device.open(openni::ANY_DEVICE);
    if (ret != openni::STATUS_OK) {
        throw std::runtime_error("");
    }

    openni::VideoStream depthStream;
    depthStream.create(device, openni::SensorType::SENSOR_DEPTH);
    depthStream.start();



    openni::VideoStream colorStream;
    colorStream.create(device, openni::SensorType::SENSOR_COLOR);
    colorStream.start();


    device.setDepthColorSyncEnabled(true);
    device.setImageRegistrationMode(openni::IMAGE_REGISTRATION_DEPTH_TO_COLOR);

    cv::Mat depthImage;
    cv::Mat colorImage;
    cv::Mat dst_image;

    float error;




    cv::Mat ColorFrame;



    while (1) {

        // Grab Frames
        openni::VideoFrameRef depthFrame;
        depthStream.readFrame(&depthFrame);

        openni::VideoFrameRef initialcolorFrame;
        colorStream.readFrame(&initialcolorFrame);

      // Create a RGB frame from the Color Stream frame

        const openni::RGB888Pixel* imageBuffer = (const openni::RGB888Pixel*)initialcolorFrame.getData();

        ColorFrame.create(initialcolorFrame.getHeight(), initialcolorFrame.getWidth(), CV_8UC3);
        memcpy(ColorFrame.data, imageBuffer, 3 * initialcolorFrame.getHeight()*initialcolorFrame.getWidth() * sizeof(uint8_t));

        cv::cvtColor(ColorFrame, ColorFrame, CV_BGR2RGB); //this will put colors right



        if (depthFrame.isValid()) {

                depthImage = cv::Mat(depthStream.getVideoMode().getResolutionY(),depthStream.getVideoMode().getResolutionX(),
                CV_16U, (char*)depthFrame.getData());

        }




    //Get World Coordinates of two points.
        float x = 0;
        float y = 0;
        float z = 0;

        float xx = 0;
        float yy = 0;
        float zz = 0;



        //Point 1 ( camera image center )
       openni::CoordinateConverter::convertDepthToWorld(depthStream, 320, 240, depthImage.at<openni::DepthPixel>(320, 240),&x,&y,&z);


        //Second point

        openni::CoordinateConverter::convertDepthToWorld(depthStream, 200, 220, depthImage.at<openni::DepthPixel>(200, 220), &xx, &yy, &zz);


    //Draw where these points are.

        cv::circle(ColorFrame, cv::Point(320, 240), 5, cv::Scalar(255, 0, 0), -1, CV_AA);
        cv::circle(ColorFrame, cv::Point(200, 220), 5, cv::Scalar(0, 255, 0), -1, CV_AA);



        // Get the depth of these two points
        auto videoMode = depthStream.getVideoMode();

        int centerX = 320;
        int centerY = 240;
        int centerXX = 200;
        int centerYY = 220;
        int centerIndexX = (centerY * videoMode.getResolutionX()) + centerX;
        int centerIndexXX = (centerYY * videoMode.getResolutionX()) + centerXX;



        short* depth = (short*)depthFrame.getData();


        //Write x,y,z world coordinates into the screen
        std::stringstream ss;
        ss << "CENTER :320, 240 :" << std::endl ;
        cv::putText(ColorFrame,
            ss.str(),
            cv::Point(0, 50),
            cv::FONT_HERSHEY_SIMPLEX,
            1,
            cv::Scalar(255, 0, 0),
            1);

        std::stringstream ss2;
        ss2 << "x[mm] :" << x << " y[mm] :" << y << " z[mm] :" << depth[centerIndexX];

        cv::putText(ColorFrame,
            ss2.str(),
            cv::Point(0, 100),
            cv::FONT_HERSHEY_SIMPLEX,
            0.8,
            cv::Scalar(0, 0, 255),
            1);




        std::stringstream ss3;
        ss3 << "Green Point: 200, 220 :" << std::endl;
        cv::putText(ColorFrame,
            ss3.str(),
            cv::Point(0, 150),
            cv::FONT_HERSHEY_SIMPLEX,
            1.0,
            cv::Scalar(0, 255, 0),
            1);

        std::stringstream ss4;
        ss4 << "x[mm] :" << xx << " y[mm] :" << yy << " z[mm] :" << depth[centerIndexXX];

        cv::putText(ColorFrame,
            ss4.str(),
            cv::Point(0, 200),
            cv::FONT_HERSHEY_SIMPLEX,
            0.8,
            cv::Scalar(0, 255, 0),
            1);


        cv::imshow("Depth Camera", dst_image);
        cv::imshow("RGB Camera", ColorFrame);



        int key = cv::waitKey(10);
        if (key == 'q') {
            break;
        }
    }
}
catch (std::exception&) {
    std::cout << openni::OpenNI::getExtendedError() << std::endl;
}

}