Added stereo multi-camera support (#884)

* Integrated OpenGV

* Fixed build without opengv

* Cmake: moved OpenGV dependency status under solvers group

* Added multi-stereocamera models support

* Fixed OpenGV 0 sample error when one of the camera doesn't have features. Fixed g2o BA id offset with multi-camera.

* Fixed multicam 3d points generated from stereo correspondences

* db: Fixed multi stereo models not loaded correctly

* gui: fixed stereo rectification option, RegVis: fixed projection error with old databases (image size not set in calibration)

* OdomF2M: Fixed map.at error when bundle adjustment is not used

* depthai: added imu firmware update option for convenience

* Fixed various refactor errors

* Moved "large number stereo correspondences rejected" warning outside computeCorrespondences function for multicam

* Added error log if ba correspondences are computed with empty signatures

* fixed compilation errors with latest opencv

Co-authored-by: mathieu86 <mathieu@robust.ai>
This commit is contained in:
matlabbe
2022-07-20 15:20:14 -04:00
committed by GitHub
co-authored by mathieu86
parent 71a28bb570
commit 5943a8b065
64 changed files with 2205 additions and 1010 deletions
+5 -4
View File
@@ -359,7 +359,8 @@ int main(int argc, char * argv[])
data.imageRaw().cols, data.imageRaw().rows, data.depthOrRightRaw().cols, data.depthOrRightRaw().rows);
}
pcl::visualization::CloudViewer * viewer = 0;
if(!data.stereoCameraModel().isValidForProjection() && (data.cameraModels().size() == 0 || !data.cameraModels()[0].isValidForProjection()))
if((data.stereoCameraModels().empty() || data.stereoCameraModels()[0].isValidForProjection()) &&
(data.cameraModels().empty() || !data.cameraModels()[0].isValidForProjection()))
{
UWARN("Camera not calibrated! The registered cloud cannot be shown.");
}
@@ -465,7 +466,7 @@ int main(int argc, char * argv[])
cv::imshow("Left", rgb); // show frame
cv::imshow("Right", right);
if(rgb.cols == right.cols && rgb.rows == right.rows && data.stereoCameraModel().isValidForProjection())
if(rgb.cols == right.cols && rgb.rows == right.rows && data.stereoCameraModels().size()==1 && data.stereoCameraModels()[0].isValidForProjection())
{
if(right.channels() == 3)
{
@@ -473,8 +474,8 @@ int main(int argc, char * argv[])
}
pcl::PointCloud<pcl::PointXYZRGB>::Ptr cloud = rtabmap::util3d::cloudFromStereoImages(
rgb, right,
data.stereoCameraModel());
cloud = rtabmap::util3d::transformPointCloud(cloud, rtabmap::Transform::opengl_T_rtabmap()*data.stereoCameraModel().localTransform());
data.stereoCameraModels()[0]);
cloud = rtabmap::util3d::transformPointCloud(cloud, rtabmap::Transform::opengl_T_rtabmap()*data.stereoCameraModels()[0].localTransform());
if(viewer)
viewer->showCloud(cloud, "cloud");
}
+14 -7
View File
@@ -1046,6 +1046,7 @@ int main(int argc, char * argv[])
// uncompress data
std::vector<CameraModel> models = node.sensorData().cameraModels();
std::vector<StereoCameraModel> stereoModels = node.sensorData().stereoCameraModels();
cv::Mat rgb;
cv::Mat depth;
@@ -1156,16 +1157,19 @@ int main(int argc, char * argv[])
}
model.save(dir);
}
if(node.sensorData().stereoCameraModel().isValidForProjection())
for(size_t i=0; i<stereoModels.size(); ++i)
{
StereoCameraModel model = node.sensorData().stereoCameraModel();
StereoCameraModel model = stereoModels[i];
std::string modelName = (exportImagesId?uNumber2Str(iter->first):uFormat("%f",node.getStamp()));
if(stereoModels.size() > 1) {
modelName += "_" + uNumber2Str((int)i);
}
model.setName(modelName, "left", "right");
std::string dir = outputDirectory+"/"+baseName+"_calib";
if(!UDirectory::exists(dir)) {
UDirectory::makeDir(dir);
}
node.sensorData().stereoCameraModel().save(dir);
model.save(dir);
}
}
@@ -1203,9 +1207,9 @@ int main(int argc, char * argv[])
Transform cameraViewpoint = iter->second * node.sensorData().cameraModels()[0].localTransform(); // take the first camera
rawViewpoints.insert(std::make_pair(iter->first, cameraViewpoint));
}
else if(!node.sensorData().stereoCameraModel().localTransform().isNull())
else if(!node.sensorData().stereoCameraModels().empty() && !node.sensorData().stereoCameraModels()[0].localTransform().isNull())
{
Transform cameraViewpoint = iter->second * node.sensorData().stereoCameraModel().localTransform();
Transform cameraViewpoint = iter->second * node.sensorData().stereoCameraModels()[0].localTransform();
rawViewpoints.insert(std::make_pair(iter->first, cameraViewpoint));
}
else
@@ -1238,9 +1242,12 @@ int main(int argc, char * argv[])
rawViewpointIndices.resize(assembledCloudI->size(), iter->first);
}
if(models.empty() && node.sensorData().stereoCameraModel().isValidForProjection())
if(models.empty())
{
models.push_back(node.sensorData().stereoCameraModel().left());
for(size_t i=0; i<node.sensorData().stereoCameraModels().size(); ++i)
{
models.push_back(node.sensorData().stereoCameraModels()[i].left());
}
}
robotPoses.insert(std::make_pair(iter->first, iter->second));