Using cv::rgbd::Odometry::compute

Using cv::rgbd::Odometry::compute

本文关键字:compute Odometry rgbd Using cv      更新时间:2023-10-16

我正在使用C++和OpenCV以及ROS的组合。我使用来自摄像头的实时图像(英特尔实感 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和深度保存在文件上,我可能是错的。