Использование cv:: rgbd:: Odometry:: compute

Я использую С++ и OpenCV с комбинацией ROS. Я использую живые изображения с моей камеры (intel realsense R200). Я получаю глубину и изображения RGB с моей камеры. В моем коде на С++ я хочу использовать эти изображения, чтобы получить данные одометрия и сделать из него траекторию.

Я пытаюсь использовать функцию cv:: rgbd:: Odometry:: compute для одометрия, но всегда возвращаю значение false (значение isSuccess в коде всегда равно 0). Но я не знаю, в какой части я делаю неправильно.

Я читал свои изображения с камеры с помощью ROS, а затем в функции Callback, сначала конвертировал все изображения в оттенки серого, а затем использовал функцию Surf для обнаружения функций. Затем я хочу использовать "вычислить", чтобы получить преобразование между текущим и предыдущим кадрами.

Насколько я понял, "Rt" и "inintRt" - это вывод функции, поэтому достаточно скопировать их с правильным размером.

Может ли кто-нибудь увидеть проблему? Я что-то пропустил?

boost::shared_ptr<rgbd::Odometry> odom;

Mat Rt = Mat(4,4, CV_64FC1);
Mat initRt = Mat(4,4, CV_64FC1);

Mat prevFtrM; //mask Matrix of previous image
Mat currFtrM; //mask Matrix of current image
Mat tempFtrM;

Mat imgprev;// previous depth image
Mat imgcurr;// current depth image

Mat imgprevC;// previous colored image
Mat imgcurrC;// current colored image


void Surf(Mat img) // detect features of the img and fill currFtrM
{
    int minHessian = 400;
    Ptr<SURF> detector = SURF::create( minHessian );
    vector<KeyPoint> keypoints_1;

    currFtrM = Mat::zeros(img.size(), CV_8U);  // type of mask is CV_8U
    Mat roi(currFtrM, cv::Rect(0,0,img.size().width,img.size().height));
    roi = Scalar(255, 255, 255);

    detector->detect( img, keypoints_1, currFtrM );

    Mat img_keypoints_1;
    drawKeypoints( img, keypoints_1, img_keypoints_1, Scalar::all(-1), DrawMatchesFlags::DEFAULT );
    //-- Show detected (drawn) keypoints
    imshow("Keypoints 1", img_keypoints_1 );
}


void Callback(const sensor_msgs::ImageConstPtr& clr, const sensor_msgs::ImageConstPtr& dpt)
{

    if(!imgcurr.data || !imgcurrC.data) // first frame
    {
        // depth image
        imgcurr = cv_bridge::toCvShare(dpt, sensor_msgs::image_encodings::TYPE_32FC1)->image;

        // colored image
        imgcurrC = cv_bridge::toCvShare(clr, "bgr8")->image;
        cvtColor(imgcurrC, imgcurrC, COLOR_BGR2GRAY);

        //find features in the image
        Surf(imgcurrC);
        prevFtrM = currFtrM;

        //scale color image to size of depth image
        resize(imgcurrC,imgcurrC, imgcurr.size());

        return;
    }

    odom = boost::make_shared<rgbd::RgbdOdometry>(imgcurrC, Odometry::DEFAULT_MIN_DEPTH(), Odometry::DEFAULT_MAX_DEPTH(),               Odometry::DEFAULT_MAX_DEPTH_DIFF(), std::vector< int >(), std::vector< float >(),               Odometry::DEFAULT_MAX_POINTS_PART(), Odometry::RIGID_BODY_MOTION);



    // depth image
    imgprev = imgcurr;
    imgcurr = cv_bridge::toCvShare(dpt, sensor_msgs::image_encodings::TYPE_32FC1)->image;

    // colored image
    imgprevC = imgcurrC;
    imgcurrC = cv_bridge::toCvShare(clr, "bgr8")->image;
    cvtColor(imgcurrC, imgcurrC, COLOR_BGR2GRAY);

    //scale color image to size of depth image
    resize(imgcurrC,imgcurrC, imgcurr.size());
    cv::imshow("Color resized", imgcurrC);

    tempFtrM = currFtrM;
    //detect new features in imgcurrC and save in a vector<Point2f>
    Surf( imgcurrC);

    prevFtrM = tempFtrM;

    //set camera matrix to identity matrix
    float vals[] = {619.137635, 0., 304.793791, 0., 625.407449, 223.984030, 0., 0., 1.};

    const Mat cameraMatrix = Mat(3, 3, CV_32FC1, vals);
    odom->setCameraMatrix(cameraMatrix);


    bool isSuccess = odom->compute( imgprevC, imgprev, prevFtrM,  imgcurrC, imgcurr, currFtrM, Rt, initRt );

    if(isSuccess)
        cout << "isSuccess   " << isSuccess << endl;

}

Обновление: Я откалибровал свою камеру и заменил матрицу камеры на реальные значения.

Ответ 1

Немного опоздал, но все же может быть полезным для кого-то.

Мне кажется, что вам не хватает внешней калибровки из расчета: в моих экспериментах R200 имеет компонент перевода между RGB и камерой глубины, который вы не принимаете во внимание. Кроме того, если смотреть на параметры камеры, у Depth и RGB разные свойства, а у Color frame искажения объектива MODIFIED_BROWN_CONRADY (но это минимально), вы не искажаете это?

Очевидно, что я могу ошибаться, если вы уже проделали все эти шаги и сохранили в файлах зарегистрированные RGB и Depth.