c++ - 使用 cv::rgbd::Odometry::compute

标签 c++ opencv ros

我正在使用 C++ 和 OpenCV 以及 ROS 的组合。我使用来 self 的相机(intel realsense R200)的实时图像。我从相机获取深度和 RGB 图像。在我的 C++ 代码中,我想使用这些图像来获取测距数据并从中制作轨迹。

我正在尝试使用“cv::rgbd::Odometry::compute”函数进行里程计,但返回值总是 false(代码中的“isSuccess”值始终为 0)。但我不知道我做错了哪一部分。

我使用 ROS 从相机读取我的图像,然后在回调函数中,首先我将所有图像转换为灰度,然后我使用 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;

}

更新:我校准了我的相机并用真实值替换了相机矩阵。

最佳答案

有点晚了,但对某些人来说仍然有用。

在我看来,您在计算中遗漏了外部校准:在我的实验中,R200 在 RGB 和深度相机之间有一个您没有考虑的转换分量。 此外,查看相机参数,深度和 RGB 具有不同的内在特性,并且颜色框架具有 MODIFIED_BROWN_CONRADY 镜头失真(但这是最小的),您是否消除了失真?

显然,如果您已经执行了所有这些步骤并将注册的 RGB 和深度保存在文件中,那么我可能是错的。

关于c++ - 使用 cv::rgbd::Odometry::compute,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48207408/

相关文章:

ros - 如何在 ROS 中为单个节点设置 VERBOSITY?

c++ - 允许重新申报?

c++ - 有什么简单的方法可以将 ASCII 转换为 UTF8? (使用 boost::locale)

c++ - opencv中dct实现错误

opencv - 如何处理 cv::VideoCapture 解码错误?

python - 将 numpy 数组中的所有像素替换为单独数组中的像素,除非值为 0

python - 在终端上运行的 ros 命令找不到 python 包

xml - 如何在 XML 变量中连接用户名?

c++ - addr2line 获取行号总是返回 0

c++ - 后期绑定(bind)有什么优点?举一个 C++ 函数指针上下文中的例子