mirror of
https://github.com/introlab/rtabmap.git
synced 2026-10-04 00:57:46 +08:00
CameraImages: support reading multicamera image and calibration files
This commit is contained in:
@@ -77,6 +77,20 @@ public:
|
||||
_hasConfigForEachFrame = value;
|
||||
}
|
||||
|
||||
// Enable multi-camera mode. Each image in the folder is expected to be the
|
||||
// horizontal concatenation of N sub-camera images of a rig, sharing the same
|
||||
// base name (timestamp or node id), e.g. "1780687370.031791.jpg" or "1.jpg".
|
||||
// One calibration file per sub-camera must exist in the calibrationFolder
|
||||
// passed to init(), named "<imageBaseName>_<index>.yaml" with index starting
|
||||
// at 0 (e.g. "1_0.yaml", "1_1.yaml", ...). The number of cameras is
|
||||
// auto-detected from the first frame. Each sub-image width is taken from the
|
||||
// corresponding model's calibrated image size; if a model has no size, a
|
||||
// uniform split (stackedWidth / N) is assumed instead.
|
||||
void setMultiCameraCalibration(bool enabled)
|
||||
{
|
||||
_multiCameraCalib = enabled;
|
||||
}
|
||||
|
||||
void setScanPath(
|
||||
const std::string & dir,
|
||||
int maxScanPts = 0,
|
||||
@@ -158,6 +172,7 @@ private:
|
||||
|
||||
bool _filenamesAreTimestamps;
|
||||
bool _hasConfigForEachFrame;
|
||||
bool _multiCameraCalib;
|
||||
std::string _timestampsPath;
|
||||
bool _syncImageRateWithStamps;
|
||||
|
||||
@@ -174,6 +189,7 @@ private:
|
||||
std::list<Transform> groundTruth_;
|
||||
CameraModel _model;
|
||||
std::list<CameraModel> _models;
|
||||
std::list<std::vector<CameraModel> > _multiModels; // one vector of sub-camera models per frame (multi-camera mode)
|
||||
|
||||
UTimer _captureTimer;
|
||||
double _captureDelay;
|
||||
|
||||
@@ -60,6 +60,7 @@ CameraImages::CameraImages() :
|
||||
_depthFromScanFillHolesFromBorder(false),
|
||||
_filenamesAreTimestamps(false),
|
||||
_hasConfigForEachFrame(false),
|
||||
_multiCameraCalib(false),
|
||||
_syncImageRateWithStamps(true),
|
||||
_odometryFormat(0),
|
||||
_groundTruthFormat(0),
|
||||
@@ -91,6 +92,7 @@ CameraImages::CameraImages(const std::string & path,
|
||||
_depthFromScanFillHolesFromBorder(false),
|
||||
_filenamesAreTimestamps(false),
|
||||
_hasConfigForEachFrame(false),
|
||||
_multiCameraCalib(false),
|
||||
_syncImageRateWithStamps(true),
|
||||
_odometryFormat(0),
|
||||
_groundTruthFormat(0),
|
||||
@@ -118,6 +120,7 @@ bool CameraImages::init(const std::string & calibrationFolder, const std::string
|
||||
_framesPublished=0;
|
||||
_model = cameraModel();
|
||||
_models.clear();
|
||||
_multiModels.clear();
|
||||
covariances_.clear();
|
||||
|
||||
UDEBUG("");
|
||||
@@ -201,41 +204,108 @@ bool CameraImages::init(const std::string & calibrationFolder, const std::string
|
||||
|
||||
if(_dir)
|
||||
{
|
||||
// look for calibration files
|
||||
UINFO("calibration folder=%s name=%s", calibrationFolder.c_str(), cameraName.c_str());
|
||||
if(!calibrationFolder.empty() && !cameraName.empty())
|
||||
if(_multiCameraCalib)
|
||||
{
|
||||
if(!_model.load(calibrationFolder, cameraName))
|
||||
// Multi-camera mode: each image is a horizontal stack of N sub-camera
|
||||
// images. Load one CameraModel per sub-camera from calibration files
|
||||
// named "<imageBaseName>_<index>.yaml" (index starting at 0).
|
||||
if(calibrationFolder.empty())
|
||||
{
|
||||
UWARN("Missing calibration files for camera \"%s\" in \"%s\" folder, you should calibrate the camera!",
|
||||
cameraName.c_str(), calibrationFolder.c_str());
|
||||
UERROR("Multi-camera calibration is enabled but no calibration folder was provided.");
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
UINFO("Camera parameters: fx=%f fy=%f cx=%f cy=%f",
|
||||
_model.fx(),
|
||||
_model.fy(),
|
||||
_model.cx(),
|
||||
_model.cy());
|
||||
const std::list<std::string> & imageFiles = _dir->getFileNames();
|
||||
|
||||
cv::FileStorage fs(calibrationFolder+"/"+cameraName+".yaml", 0);
|
||||
cv::FileNode poseNode = fs["local_transform"];
|
||||
if(!poseNode.isNone())
|
||||
// auto-detect the number of cameras from the first frame
|
||||
int numCameras = 0;
|
||||
std::string firstBase = imageFiles.front().substr(0, imageFiles.front().find_last_of('.'));
|
||||
while(UFile::exists(calibrationFolder + "/" + firstBase + "_" + uNumber2Str(numCameras) + ".yaml"))
|
||||
{
|
||||
++numCameras;
|
||||
}
|
||||
|
||||
if(numCameras == 0)
|
||||
{
|
||||
UERROR("Multi-camera calibration is enabled but no calibration file matching "
|
||||
"\"%s/%s_<index>.yaml\" was found for the first image \"%s\".",
|
||||
calibrationFolder.c_str(), firstBase.c_str(), imageFiles.front().c_str());
|
||||
return false;
|
||||
}
|
||||
|
||||
UINFO("Multi-camera mode: %d sub-cameras detected from \"%s\".", numCameras, calibrationFolder.c_str());
|
||||
for(std::list<std::string>::const_iterator iter=imageFiles.begin(); iter!=imageFiles.end(); ++iter)
|
||||
{
|
||||
std::string base = iter->substr(0, iter->find_last_of('.'));
|
||||
std::vector<CameraModel> models(numCameras);
|
||||
for(int i=0; i<numCameras; ++i)
|
||||
{
|
||||
UWARN("Using local transform from calibration file (%s) instead of the parameter one (%s).",
|
||||
_model.localTransform().prettyPrint().c_str(),
|
||||
this->getLocalTransform().prettyPrint().c_str());
|
||||
this->setLocalTransform(_model.localTransform());
|
||||
std::string name = base + "_" + uNumber2Str(i);
|
||||
if(!models[i].load(calibrationFolder, name) || !models[i].isValidForProjection())
|
||||
{
|
||||
UERROR("Failed to load a valid calibration \"%s/%s.yaml\" for multi-camera frame \"%s\".",
|
||||
calibrationFolder.c_str(), name.c_str(), iter->c_str());
|
||||
_multiModels.clear();
|
||||
return false;
|
||||
}
|
||||
if(models[i].localTransform().isNull())
|
||||
{
|
||||
// In multi-camera mode the rig extrinsics are required: each
|
||||
// sub-camera calibration must provide a "local_transform".
|
||||
UERROR("Calibration \"%s/%s.yaml\" has no \"local_transform\"; it is "
|
||||
"required in multi-camera mode (rig extrinsics).",
|
||||
calibrationFolder.c_str(), name.c_str());
|
||||
_multiModels.clear();
|
||||
return false;
|
||||
}
|
||||
if(_rectifyImages && !models[i].isValidForRectification())
|
||||
{
|
||||
UERROR("Parameter \"rectifyImages\" is set, but calibration \"%s/%s.yaml\" is not valid for rectification.",
|
||||
calibrationFolder.c_str(), name.c_str());
|
||||
_multiModels.clear();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
_multiModels.push_back(models);
|
||||
}
|
||||
}
|
||||
_model.setName(cameraName);
|
||||
|
||||
_model.setLocalTransform(this->getLocalTransform());
|
||||
if(_rectifyImages && !_model.isValidForRectification())
|
||||
else
|
||||
{
|
||||
UERROR("Parameter \"rectifyImages\" is set, but no camera model is loaded or valid.");
|
||||
return false;
|
||||
// look for calibration files
|
||||
UINFO("calibration folder=%s name=%s", calibrationFolder.c_str(), cameraName.c_str());
|
||||
if(!calibrationFolder.empty() && !cameraName.empty())
|
||||
{
|
||||
if(!_model.load(calibrationFolder, cameraName))
|
||||
{
|
||||
UWARN("Missing calibration files for camera \"%s\" in \"%s\" folder, you should calibrate the camera!",
|
||||
cameraName.c_str(), calibrationFolder.c_str());
|
||||
}
|
||||
else
|
||||
{
|
||||
UINFO("Camera parameters: fx=%f fy=%f cx=%f cy=%f",
|
||||
_model.fx(),
|
||||
_model.fy(),
|
||||
_model.cx(),
|
||||
_model.cy());
|
||||
|
||||
cv::FileStorage fs(calibrationFolder+"/"+cameraName+".yaml", 0);
|
||||
cv::FileNode poseNode = fs["local_transform"];
|
||||
if(!poseNode.isNone())
|
||||
{
|
||||
UWARN("Using local transform from calibration file (%s) instead of the parameter one (%s).",
|
||||
_model.localTransform().prettyPrint().c_str(),
|
||||
this->getLocalTransform().prettyPrint().c_str());
|
||||
this->setLocalTransform(_model.localTransform());
|
||||
}
|
||||
}
|
||||
}
|
||||
_model.setName(cameraName);
|
||||
|
||||
_model.setLocalTransform(this->getLocalTransform());
|
||||
if(_rectifyImages && !_model.isValidForRectification())
|
||||
{
|
||||
UERROR("Parameter \"rectifyImages\" is set, but no camera model is loaded or valid.");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -245,7 +315,7 @@ bool CameraImages::init(const std::string & calibrationFolder, const std::string
|
||||
groundTruth_.clear();
|
||||
if(success)
|
||||
{
|
||||
if(_dir && _hasConfigForEachFrame)
|
||||
if(_dir && _hasConfigForEachFrame && !_multiCameraCalib)
|
||||
{
|
||||
#if CV_MAJOR_VERSION < 3 || (CV_MAJOR_VERSION == 3 && CV_MAJOR_VERSION < 2)
|
||||
UDirectory dirJson(_path, "yaml xml");
|
||||
@@ -653,7 +723,9 @@ bool CameraImages::readPoses(
|
||||
|
||||
bool CameraImages::isCalibrated() const
|
||||
{
|
||||
return (_dir && (_model.isValidForProjection() || (_models.size() && _models.front().isValidForProjection()))) ||
|
||||
return (_dir && (_model.isValidForProjection() ||
|
||||
(_models.size() && _models.front().isValidForProjection()) ||
|
||||
(_multiModels.size() && !_multiModels.front().empty() && _multiModels.front().front().isValidForProjection()))) ||
|
||||
_scanDir;
|
||||
}
|
||||
|
||||
@@ -728,7 +800,13 @@ SensorData CameraImages::captureImage(SensorCaptureInfo * info)
|
||||
cv::Mat covariance;
|
||||
Transform groundTruthPose;
|
||||
cv::Mat depthFromScan;
|
||||
CameraModel model = _model;
|
||||
std::vector<CameraModel> models; // one entry per camera (single entry in single-camera mode)
|
||||
if(!_multiCameraCalib)
|
||||
{
|
||||
// Single-camera mode keeps exactly one model in the vector; in multi-camera
|
||||
// mode the per-frame vector is taken from _multiModels below.
|
||||
models.push_back(_model);
|
||||
}
|
||||
UDEBUG("");
|
||||
if(_dir || _scanDir)
|
||||
{
|
||||
@@ -784,7 +862,7 @@ SensorData CameraImages::captureImage(SensorCaptureInfo * info)
|
||||
{
|
||||
UERROR("groundTruth cannot be used when startAt < 0");
|
||||
}
|
||||
if(_models.size() && !model.isValidForProjection())
|
||||
if((_models.size() && !models.back().isValidForProjection()) || _multiModels.size())
|
||||
{
|
||||
UERROR("models cannot be used when startAt < 0");
|
||||
}
|
||||
@@ -826,13 +904,20 @@ SensorData CameraImages::captureImage(SensorCaptureInfo * info)
|
||||
groundTruthPose = groundTruth_.front();
|
||||
groundTruth_.pop_front();
|
||||
}
|
||||
if(_models.size() && !model.isValidForProjection())
|
||||
if(_models.size() && !models.back().isValidForProjection())
|
||||
{
|
||||
UASSERT_MSG(stampsSize==0 || stampsSize == _models.size(),
|
||||
UASSERT_MSG(stampsSize==0 || stampsSize == _models.size(),
|
||||
uFormat("Stamps=%ld models=%ld", _stamps.size(), _models.size()).c_str());
|
||||
model = _models.front();
|
||||
models.back() = _models.front();
|
||||
_models.pop_front();
|
||||
}
|
||||
if(_multiModels.size())
|
||||
{
|
||||
UASSERT_MSG(stampsSize==0 || stampsSize == _multiModels.size(),
|
||||
uFormat("Stamps=%ld multiModels=%ld", stampsSize, _multiModels.size()).c_str());
|
||||
models = _multiModels.front();
|
||||
_multiModels.pop_front();
|
||||
}
|
||||
|
||||
while(_count++ < _startAt)
|
||||
{
|
||||
@@ -875,13 +960,20 @@ SensorData CameraImages::captureImage(SensorCaptureInfo * info)
|
||||
groundTruthPose = groundTruth_.front();
|
||||
groundTruth_.pop_front();
|
||||
}
|
||||
if(_models.size() && !model.isValidForProjection())
|
||||
if(_models.size() && !models.back().isValidForProjection())
|
||||
{
|
||||
UASSERT_MSG(stampsSize==0 || stampsSize == _models.size(),
|
||||
UASSERT_MSG(stampsSize==0 || stampsSize == _models.size(),
|
||||
uFormat("Stamps=%ld models=%ld", _stamps.size(), _models.size()).c_str());
|
||||
model = _models.front();
|
||||
models.back() = _models.front();
|
||||
_models.pop_front();
|
||||
}
|
||||
if(_multiModels.size())
|
||||
{
|
||||
UASSERT_MSG(stampsSize==0 || stampsSize == _multiModels.size(),
|
||||
uFormat("Stamps=%ld multiModels=%ld", stampsSize, _multiModels.size()).c_str());
|
||||
models = _multiModels.front();
|
||||
_multiModels.pop_front();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -951,9 +1043,56 @@ SensorData CameraImages::captureImage(SensorCaptureInfo * info)
|
||||
}
|
||||
}
|
||||
|
||||
if(!img.empty() && model.isValidForRectification() && _rectifyImages)
|
||||
if(!img.empty() && !models.empty())
|
||||
{
|
||||
img = model.rectifyImage(img);
|
||||
// The image is a horizontal stack of N sub-images (N==1 in
|
||||
// single-camera mode). Each sub-camera's width comes from its
|
||||
// calibrated image size; if a model has no size (==0), assume a
|
||||
// uniform split (stackedWidth / N) and set it. If requested, each
|
||||
// sub-image is rectified independently with its model and written
|
||||
// into a new stacked image of the same layout.
|
||||
cv::Mat rectified;
|
||||
int offset = 0;
|
||||
for(size_t i=0; i<models.size(); ++i)
|
||||
{
|
||||
if(models[i].imageWidth()==0 || models[i].imageHeight()==0)
|
||||
{
|
||||
models[i].setImageSize(cv::Size(img.cols/(int)models.size(), img.rows));
|
||||
}
|
||||
int subWidth = models[i].imageWidth();
|
||||
if(offset+subWidth > img.cols)
|
||||
{
|
||||
UERROR("Multi-camera: sum of sub-image widths (%d) exceeds the stacked "
|
||||
"image width (%d) at camera %d.", offset+subWidth, img.cols, (int)i);
|
||||
rectified = cv::Mat();
|
||||
break;
|
||||
}
|
||||
if(_rectifyImages)
|
||||
{
|
||||
if(!models[i].isValidForRectification())
|
||||
{
|
||||
UERROR("Parameter \"rectifyImages\" is set, but camera model %d is not valid for rectification.", (int)i);
|
||||
rectified = cv::Mat();
|
||||
break;
|
||||
}
|
||||
if(rectified.empty())
|
||||
{
|
||||
rectified = cv::Mat::zeros(img.rows, img.cols, img.type());
|
||||
}
|
||||
cv::Rect roi(offset, 0, subWidth, img.rows);
|
||||
models[i].rectifyImage(img(roi)).copyTo(rectified(roi));
|
||||
}
|
||||
offset += subWidth;
|
||||
}
|
||||
if(offset != img.cols)
|
||||
{
|
||||
UWARN("Multi-camera: sum of sub-image widths (%d) does not match the "
|
||||
"stacked image width (%d).", offset, img.cols);
|
||||
}
|
||||
if(!rectified.empty())
|
||||
{
|
||||
img = rectified;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -966,7 +1105,7 @@ SensorData CameraImages::captureImage(SensorCaptureInfo * info)
|
||||
if(_depthFromScan && !img.empty())
|
||||
{
|
||||
UDEBUG("Computing depth from scan...");
|
||||
if(!model.isValidForProjection())
|
||||
if(models.empty() || !models.front().isValidForProjection())
|
||||
{
|
||||
UWARN("Depth from laser scan: Camera model should be valid.");
|
||||
}
|
||||
@@ -977,10 +1116,23 @@ SensorData CameraImages::captureImage(SensorCaptureInfo * info)
|
||||
else
|
||||
{
|
||||
pcl::PointCloud<pcl::PointXYZ>::Ptr cloud = util3d::laserScanToPointCloud(scan, scan.localTransform());
|
||||
depthFromScan = util3d::projectCloudToCamera(img.size(), model.K(), cloud, model.localTransform());
|
||||
if(_depthFromScanFillHoles!=0)
|
||||
// There is no multi-camera version of projectCloudToCamera(): project
|
||||
// the scan into each (sub-)camera and stack the registered depth images
|
||||
// horizontally, matching the RGB layout (single iteration in single-camera
|
||||
// mode). Sub-image widths come from each model's (already set) image size.
|
||||
// Holes are filled per sub-image so they don't bleed across cameras.
|
||||
depthFromScan = cv::Mat::zeros(img.rows, img.cols, CV_32FC1);
|
||||
int offset = 0;
|
||||
for(size_t i=0; i<models.size() && offset+models[i].imageWidth()<=img.cols; ++i)
|
||||
{
|
||||
util3d::fillProjectedCloudHoles(depthFromScan, _depthFromScanFillHoles>0, _depthFromScanFillHolesFromBorder);
|
||||
int subWidth = models[i].imageWidth();
|
||||
cv::Mat subDepth = util3d::projectCloudToCamera(cv::Size(subWidth, img.rows), models[i].K(), cloud, models[i].localTransform());
|
||||
if(_depthFromScanFillHoles!=0)
|
||||
{
|
||||
util3d::fillProjectedCloudHoles(subDepth, _depthFromScanFillHoles>0, _depthFromScanFillHolesFromBorder);
|
||||
}
|
||||
subDepth.copyTo(depthFromScan(cv::Rect(offset, 0, subWidth, img.rows)));
|
||||
offset += subWidth;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -992,15 +1144,10 @@ SensorData CameraImages::captureImage(SensorCaptureInfo * info)
|
||||
UWARN("Directory is not set, camera must be initialized.");
|
||||
}
|
||||
|
||||
if(model.imageHeight() == 0 || model.imageWidth() == 0)
|
||||
{
|
||||
model.setImageSize(img.size());
|
||||
}
|
||||
|
||||
SensorData data;
|
||||
if(!img.empty() || !scan.empty())
|
||||
{
|
||||
data = SensorData(scan, _isDepth?cv::Mat():img, _isDepth?img:depthFromScan, model, this->getNextSeqID(), stamp);
|
||||
data = SensorData(scan, _isDepth?cv::Mat():img, _isDepth?img:depthFromScan, models, this->getNextSeqID(), stamp);
|
||||
data.setGroundTruth(groundTruthPose);
|
||||
}
|
||||
|
||||
|
||||
@@ -1665,12 +1665,12 @@ void DatabaseViewer::extractImages()
|
||||
}
|
||||
StereoCameraModel model(
|
||||
cameraName,
|
||||
data.imageRaw().size(),
|
||||
data.stereoCameraModels()[i].left().imageSize(),
|
||||
data.stereoCameraModels()[i].left().K_raw(),
|
||||
data.stereoCameraModels()[i].left().D_raw(),
|
||||
data.stereoCameraModels()[i].left().R(),
|
||||
data.stereoCameraModels()[i].left().P(),
|
||||
data.rightRaw().size(),
|
||||
data.stereoCameraModels()[i].right().imageSize(),
|
||||
data.stereoCameraModels()[i].right().K_raw(),
|
||||
data.stereoCameraModels()[i].right().D_raw(),
|
||||
data.stereoCameraModels()[i].right().R(),
|
||||
@@ -1730,7 +1730,7 @@ void DatabaseViewer::extractImages()
|
||||
cameraName+="_"+uNumber2Str((int)i);
|
||||
}
|
||||
CameraModel model(cameraName,
|
||||
data.imageRaw().size(),
|
||||
data.cameraModels()[i].imageSize(),
|
||||
data.cameraModels()[i].K_raw(),
|
||||
data.cameraModels()[i].D_raw(),
|
||||
data.cameraModels()[i].R(),
|
||||
|
||||
@@ -843,6 +843,7 @@ PreferencesDialog::PreferencesDialog(QWidget * parent) :
|
||||
connect(_ui->lineEdit_cameraRGBDImages_path_rgb, SIGNAL(textChanged(const QString &)), this, SLOT(makeObsoleteSourcePanel()));
|
||||
connect(_ui->lineEdit_cameraRGBDImages_path_depth, SIGNAL(textChanged(const QString &)), this, SLOT(makeObsoleteSourcePanel()));
|
||||
connect(_ui->checkBox_cameraImages_configForEachFrame, SIGNAL(stateChanged(int)), this, SLOT(makeObsoleteSourcePanel()));
|
||||
connect(_ui->checkBox_cameraImages_multiCameraCalibration, SIGNAL(stateChanged(int)), this, SLOT(makeObsoleteSourcePanel()));
|
||||
connect(_ui->checkBox_cameraImages_timestamps, SIGNAL(stateChanged(int)), this, SLOT(makeObsoleteSourcePanel()));
|
||||
connect(_ui->checkBox_cameraImages_syncTimeStamps, SIGNAL(stateChanged(int)), this, SLOT(makeObsoleteSourcePanel()));
|
||||
connect(_ui->doubleSpinBox_cameraRGBDImages_scale, SIGNAL(valueChanged(double)), this, SLOT(makeObsoleteSourcePanel()));
|
||||
@@ -2389,6 +2390,7 @@ void PreferencesDialog::resetSettings(QGroupBox * groupBox)
|
||||
_ui->lineEdit_depthai_blob_path->clear();
|
||||
|
||||
_ui->checkBox_cameraImages_configForEachFrame->setChecked(false);
|
||||
_ui->checkBox_cameraImages_multiCameraCalibration->setChecked(false);
|
||||
_ui->checkBox_cameraImages_timestamps->setChecked(false);
|
||||
_ui->checkBox_cameraImages_syncTimeStamps->setChecked(true);
|
||||
_ui->lineEdit_cameraImages_timestamps->setText("");
|
||||
@@ -2924,6 +2926,7 @@ void PreferencesDialog::readCameraSettings(const QString & filePath)
|
||||
_ui->comboBox_cameraImages_bayerMode->setCurrentIndex(settings.value("bayerMode",_ui->comboBox_cameraImages_bayerMode->currentIndex()).toInt());
|
||||
|
||||
_ui->checkBox_cameraImages_configForEachFrame->setChecked(settings.value("config_each_frame",_ui->checkBox_cameraImages_configForEachFrame->isChecked()).toBool());
|
||||
_ui->checkBox_cameraImages_multiCameraCalibration->setChecked(settings.value("multi_camera_calibration",_ui->checkBox_cameraImages_multiCameraCalibration->isChecked()).toBool());
|
||||
_ui->checkBox_cameraImages_timestamps->setChecked(settings.value("filenames_as_stamps",_ui->checkBox_cameraImages_timestamps->isChecked()).toBool());
|
||||
_ui->checkBox_cameraImages_syncTimeStamps->setChecked(settings.value("sync_stamps",_ui->checkBox_cameraImages_syncTimeStamps->isChecked()).toBool());
|
||||
_ui->lineEdit_cameraImages_timestamps->setText(settings.value("stamps", _ui->lineEdit_cameraImages_timestamps->text()).toString());
|
||||
@@ -3546,6 +3549,7 @@ void PreferencesDialog::writeCameraSettings(const QString & filePath) const
|
||||
settings.setValue("maxFrames", _ui->source_images_spinBox_maxFrames->value());
|
||||
settings.setValue("bayerMode", _ui->comboBox_cameraImages_bayerMode->currentIndex());
|
||||
settings.setValue("config_each_frame", _ui->checkBox_cameraImages_configForEachFrame->isChecked());
|
||||
settings.setValue("multi_camera_calibration", _ui->checkBox_cameraImages_multiCameraCalibration->isChecked());
|
||||
settings.setValue("filenames_as_stamps", _ui->checkBox_cameraImages_timestamps->isChecked());
|
||||
settings.setValue("sync_stamps", _ui->checkBox_cameraImages_syncTimeStamps->isChecked());
|
||||
settings.setValue("stamps", _ui->lineEdit_cameraImages_timestamps->text());
|
||||
@@ -7069,6 +7073,7 @@ Camera * PreferencesDialog::createCamera(
|
||||
_ui->lineEdit_cameraImages_timestamps->text().toStdString(),
|
||||
_ui->checkBox_cameraImages_syncTimeStamps->isChecked());
|
||||
((CameraRGBDImages*)camera)->setConfigForEachFrame(_ui->checkBox_cameraImages_configForEachFrame->isChecked());
|
||||
((CameraRGBDImages*)camera)->setMultiCameraCalibration(_ui->checkBox_cameraImages_multiCameraCalibration->isChecked());
|
||||
}
|
||||
else if(driver == kSrcDC1394)
|
||||
{
|
||||
@@ -7319,7 +7324,8 @@ Camera * PreferencesDialog::createCamera(
|
||||
_ui->checkBox_cameraImages_timestamps->isChecked(),
|
||||
_ui->lineEdit_cameraImages_timestamps->text().toStdString(),
|
||||
_ui->checkBox_cameraImages_syncTimeStamps->isChecked());
|
||||
((CameraRGBDImages*)camera)->setConfigForEachFrame(_ui->checkBox_cameraImages_configForEachFrame->isChecked());
|
||||
((CameraImages*)camera)->setConfigForEachFrame(_ui->checkBox_cameraImages_configForEachFrame->isChecked());
|
||||
((CameraImages*)camera)->setMultiCameraCalibration(_ui->checkBox_cameraImages_multiCameraCalibration->isChecked());
|
||||
}
|
||||
else if(driver == kSrcDatabase)
|
||||
{
|
||||
|
||||
+410
-390
@@ -7,7 +7,7 @@
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>980</width>
|
||||
<height>925</height>
|
||||
<height>1246</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="sizePolicy">
|
||||
@@ -63,9 +63,9 @@
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>-648</y>
|
||||
<y>-557</y>
|
||||
<width>684</width>
|
||||
<height>5218</height>
|
||||
<height>5360</height>
|
||||
</rect>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout_16">
|
||||
@@ -95,7 +95,7 @@
|
||||
<enum>QFrame::Raised</enum>
|
||||
</property>
|
||||
<property name="currentIndex">
|
||||
<number>19</number>
|
||||
<number>5</number>
|
||||
</property>
|
||||
<widget class="QWidget" name="page_22">
|
||||
<layout class="QVBoxLayout" name="verticalLayout_29" stretch="0,0">
|
||||
@@ -3469,7 +3469,7 @@ when using the file type, logs are saved in LogRtabmap.txt (located in the worki
|
||||
<item>
|
||||
<widget class="QStackedWidget" name="stackedWidget_src">
|
||||
<property name="currentIndex">
|
||||
<number>3</number>
|
||||
<number>0</number>
|
||||
</property>
|
||||
<widget class="QWidget" name="page_41">
|
||||
<layout class="QVBoxLayout" name="verticalLayout_64">
|
||||
@@ -3590,7 +3590,7 @@ when using the file type, logs are saved in LogRtabmap.txt (located in the worki
|
||||
<item>
|
||||
<widget class="QStackedWidget" name="stackedWidget_rgbd">
|
||||
<property name="currentIndex">
|
||||
<number>9</number>
|
||||
<number>7</number>
|
||||
</property>
|
||||
<widget class="QWidget" name="page_32">
|
||||
<layout class="QVBoxLayout" name="verticalLayout_63">
|
||||
@@ -7556,279 +7556,6 @@ when using the file type, logs are saved in LogRtabmap.txt (located in the worki
|
||||
</property>
|
||||
<item>
|
||||
<layout class="QGridLayout" name="gridLayout_68" columnstretch="0,0,1">
|
||||
<item row="3" column="1">
|
||||
<widget class="QCheckBox" name="checkBox_cameraImages_syncTimeStamps">
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="11" column="1">
|
||||
<widget class="QDoubleSpinBox" name="doubleSpinBox_maxPoseTimeDiff">
|
||||
<property name="suffix">
|
||||
<string> s</string>
|
||||
</property>
|
||||
<property name="decimals">
|
||||
<number>4</number>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<double>9.990000000000000</double>
|
||||
</property>
|
||||
<property name="singleStep">
|
||||
<double>0.010000000000000</double>
|
||||
</property>
|
||||
<property name="value">
|
||||
<double>0.020000000000000</double>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QCheckBox" name="checkBox_cameraImages_configForEachFrame">
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="15" column="0">
|
||||
<widget class="QToolButton" name="toolButton_cameraImages_path_imu">
|
||||
<property name="text">
|
||||
<string>...</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="15" column="2">
|
||||
<widget class="QLabel" name="label_463">
|
||||
<property name="text">
|
||||
<string>Path to file containing optional IMU data (*.csv [EuRoC format]). Mouse over the box to show formats.</string>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="textInteractionFlags">
|
||||
<set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="7" column="1">
|
||||
<widget class="QComboBox" name="comboBox_cameraImages_odomFormat">
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p>Raw Format (3 values): x y z<br/>Raw Format (6 values): x y z roll pitch yaw<br/>Raw Format (7 values): x y z qx qy qz qw<br/>Raw Format (9 values, 3x3 rotation): r11 r12 r13 r21 r22 r23 r31 r32 r33<br/>Raw Format (12 values, 3x4 transform): r11 r12 r13 tx r21 r22 r23 ty r31 r32 r33 tz</p><p>RGBD-SLAM (stamp tx ty tz qx qy qz qw)<br/>RGBD-SLAM + ID (stamp id tx ty tz qx qy qz qw)<br/>KITTI (stamp + 12 values transform)<br/>TORO<br/>g2o<br/>NewCollege (stamp x y)<br/>Malaga Urban (GPS)<br/>St Lucia Stereo (INS)<br/>EuRoC MAV (stamp,tx,ty,tz,qw,qx,qy,qz...)</p></body></html></string>
|
||||
</property>
|
||||
<property name="sizeAdjustPolicy">
|
||||
<enum>QComboBox::AdjustToContents</enum>
|
||||
</property>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Raw</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>RGBD-SLAM (motion capture)</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>KITTI</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>TORO</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>g2o</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>NewCollege</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Malaga Urban</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>St Lucia Stereo</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Karlsruhe</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>EuRoC MAV</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>RGBD-SLAM</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>RGBD-SLAM + ID</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>rgbd_bonn</string>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="17" column="2">
|
||||
<widget class="QLabel" name="label_465">
|
||||
<property name="text">
|
||||
<string>IMU Rate. To synchronize capture rate with IMU timestamps, set to 0. This can be set a little over the actual IMU rate to keep up with camera capture rate if images are dropped by odometry.</string>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="textInteractionFlags">
|
||||
<set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="2">
|
||||
<widget class="QLabel" name="label_256">
|
||||
<property name="text">
|
||||
<string>Synchronize capture rate with timestamps.</string>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="textInteractionFlags">
|
||||
<set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="13" column="2">
|
||||
<widget class="QLabel" name="label_294">
|
||||
<property name="text">
|
||||
<string>Local transform from /base_link to /laser_link. Mouse over the box to show formats.</string>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="textInteractionFlags">
|
||||
<set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="6" column="2">
|
||||
<widget class="QLabel" name="label_348">
|
||||
<property name="text">
|
||||
<string>Odometry file. Select the correct format below.</string>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="textInteractionFlags">
|
||||
<set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="15" column="1">
|
||||
<widget class="QLineEdit" name="lineEdit_cameraImages_path_imu">
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p>cvs format (comma split): &quot;stamp_sec,gyro_x,gyro_y,gyro_z,acc_x,acc_y,acc_z&quot;</p><p>EuRoC format: &quot;stamp_nanosec,gyro_x,gyro_y,gyro_z,acc_x,acc_y,acc_z&quot;</p></body></html></string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="16" column="2">
|
||||
<widget class="QLabel" name="label_464">
|
||||
<property name="text">
|
||||
<string>Local transform from /base_link to /imu_link. Mouse over the box to show formats.</string>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="textInteractionFlags">
|
||||
<set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="12" column="1">
|
||||
<widget class="QLineEdit" name="lineEdit_cameraImages_path_scans">
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="13" column="1">
|
||||
<widget class="QLineEdit" name="lineEdit_cameraImages_laser_transform">
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p>Format (3 values): x y z<br/>Format (6 values): x y z roll pitch yaw<br/>Format (7 values): x y z qx qy qz qw<br/>Format (9 values, 3x3 rotation): r11 r12 r13 r21 r22 r23 r31 r32 r33<br/>Format (12 values, 3x4 transform): r11 r12 r13 tx r21 r22 r23 ty r31 r32 r33 tz</p><p>KITTI: /base_link to /scan = -0.27 0 0.08 0 0 0<br/>KITTI: /base_footprint to /scan = -0.27 0 1.75 0 0 0</p></body></html></string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>0 0 0 0 0 0</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="12" column="2">
|
||||
<widget class="QLabel" name="label_293">
|
||||
<property name="text">
|
||||
<string>Path to directory containing optional laser scans (*.pcd, *.ply, *.bin [KITTI format]). The directory should have the same size has the images directory. </string>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="textInteractionFlags">
|
||||
<set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QCheckBox" name="checkBox_cameraImages_timestamps">
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="14" column="2">
|
||||
<widget class="QLabel" name="label_292">
|
||||
<property name="text">
|
||||
<string>Maximum laser scan points.</string>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="textInteractionFlags">
|
||||
<set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="14" column="1">
|
||||
<widget class="QSpinBox" name="spinBox_cameraImages_max_scan_pts">
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p>KITTI: 130 000 points</p></body></html></string>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>99999999</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="17" column="1">
|
||||
<widget class="QSpinBox" name="spinBox_cameraImages_max_imu_rate">
|
||||
<property name="toolTip">
|
||||
<string>EuRoC: 200 Hz -> 250 Hz</string>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>99999999</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="1">
|
||||
<widget class="QComboBox" name="comboBox_cameraImages_bayerMode">
|
||||
<property name="sizeAdjustPolicy">
|
||||
@@ -7861,47 +7588,41 @@ when using the file type, logs are saved in LogRtabmap.txt (located in the worki
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="11" column="2">
|
||||
<widget class="QLabel" name="label_443">
|
||||
<item row="14" column="1">
|
||||
<widget class="QLineEdit" name="lineEdit_cameraImages_laser_transform">
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p>Format (3 values): x y z<br/>Format (6 values): x y z roll pitch yaw<br/>Format (7 values): x y z qx qy qz qw<br/>Format (9 values, 3x3 rotation): r11 r12 r13 r21 r22 r23 r31 r32 r33<br/>Format (12 values, 3x4 transform): r11 r12 r13 tx r21 r22 r23 ty r31 r32 r33 tz</p><p>KITTI: /base_link to /scan = -0.27 0 0.08 0 0 0<br/>KITTI: /base_footprint to /scan = -0.27 0 1.75 0 0 0</p></body></html></string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Max time difference between data and corresponding pose for format with stamps. If delay is over this threshold, the pose won't be set on data loaded. This is used when odometry and/or ground truth files are set.</string>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="textInteractionFlags">
|
||||
<set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set>
|
||||
<string>0 0 0 0 0 0</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="12" column="0">
|
||||
<widget class="QToolButton" name="toolButton_cameraImages_path_scans">
|
||||
<item row="15" column="1">
|
||||
<widget class="QSpinBox" name="spinBox_cameraImages_max_scan_pts">
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p>KITTI: 130 000 points</p></body></html></string>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>99999999</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="9" column="0">
|
||||
<widget class="QToolButton" name="toolButton_cameraImages_gt">
|
||||
<property name="text">
|
||||
<string>...</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="1">
|
||||
<widget class="QLineEdit" name="lineEdit_cameraImages_timestamps">
|
||||
<item row="9" column="1">
|
||||
<widget class="QLineEdit" name="lineEdit_cameraImages_gt">
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="2">
|
||||
<widget class="QLabel" name="label_255">
|
||||
<property name="text">
|
||||
<string>Use file names as timestamps. Format is epoch time. Example: "1305031102.175304.png".</string>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="textInteractionFlags">
|
||||
<set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="16" column="1">
|
||||
<item row="18" column="1">
|
||||
<widget class="QLineEdit" name="lineEdit_cameraImages_imu_transform">
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p>Format (3 values): x y z<br/>Format (6 values): x y z roll pitch yaw<br/>Format (7 values): x y z qx qy qz qw<br/>Format (9 values, 3x3 rotation): r11 r12 r13 r21 r22 r23 r31 r32 r33<br/>Format (12 values, 3x4 transform): r11 r12 r13 tx r21 r22 r23 ty r31 r32 r33 tz</p><p>EuRoC: /base_link to /imu = 0 0 1 0 -1 0 1 0 0</p></body></html></string>
|
||||
@@ -7911,10 +7632,10 @@ when using the file type, logs are saved in LogRtabmap.txt (located in the worki
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="8" column="2">
|
||||
<widget class="QLabel" name="label_288">
|
||||
<item row="18" column="2">
|
||||
<widget class="QLabel" name="label_464">
|
||||
<property name="text">
|
||||
<string>Ground truth file. Select the correct format below.</string>
|
||||
<string>Local transform from /base_link to /imu_link. Mouse over the box to show formats.</string>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
@@ -7924,28 +7645,53 @@ when using the file type, logs are saved in LogRtabmap.txt (located in the worki
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="8" column="0">
|
||||
<widget class="QToolButton" name="toolButton_cameraImages_gt">
|
||||
<item row="19" column="2">
|
||||
<widget class="QLabel" name="label_465">
|
||||
<property name="text">
|
||||
<string>...</string>
|
||||
<string>IMU Rate. To synchronize capture rate with IMU timestamps, set to 0. This can be set a little over the actual IMU rate to keep up with camera capture rate if images are dropped by odometry.</string>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="textInteractionFlags">
|
||||
<set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="8" column="1">
|
||||
<widget class="QLineEdit" name="lineEdit_cameraImages_gt">
|
||||
<item row="1" column="2">
|
||||
<widget class="QLabel" name="label_605">
|
||||
<property name="text">
|
||||
<string>Load config file for each frame. For calibration, global calibration path above should be empty. Config files should be in the same directory than RGB frames and they should have the same name than the corresponding frame file. Currently supporting 3DScannerApp for iOS export config format (JSON, intrinsics, pose and stamp) and RTAB-Map calibration file format.</string>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="textInteractionFlags">
|
||||
<set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="7" column="1">
|
||||
<widget class="QLineEdit" name="lineEdit_cameraImages_odom">
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="0">
|
||||
<widget class="QToolButton" name="toolButton_cameraImages_timestamps">
|
||||
<item row="4" column="2">
|
||||
<widget class="QLabel" name="label_256">
|
||||
<property name="text">
|
||||
<string>...</string>
|
||||
<string>Synchronize capture rate with timestamps.</string>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="textInteractionFlags">
|
||||
<set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="9" column="1">
|
||||
<item row="10" column="1">
|
||||
<widget class="QComboBox" name="comboBox_cameraImages_gtFormat">
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p>Raw Format (3 values): x y z<br/>Raw Format (6 values): x y z roll pitch yaw<br/>Raw Format (7 values): x y z qx qy qz qw<br/>Raw Format (9 values, 3x3 rotation): r11 r12 r13 r21 r22 r23 r31 r32 r33<br/>Raw Format (12 values, 3x4 transform): r11 r12 r13 tx r21 r22 r23 ty r31 r32 r33 tz</p><p>RGBD-SLAM (stamp tx ty tz qx qy qz qw)<br/>RGBD-SLAM + ID (stamp id tx ty tz qx qy qz qw)<br/>KITTI (stamp + 12 values transform)<br/>TORO<br/>g2o<br/>NewCollege (stamp x y)<br/>Malaga Urban (GPS)<br/>St Lucia Stereo (INS)<br/>EuRoC MAV (stamp,tx,ty,tz,qw,qx,qy,qz...)</p></body></html></string>
|
||||
@@ -8020,72 +7766,6 @@ when using the file type, logs are saved in LogRtabmap.txt (located in the worki
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="2">
|
||||
<widget class="QLabel" name="label_605">
|
||||
<property name="text">
|
||||
<string>Load config file for each frame. For calibration, global calibration path above should be empty. Config files should be in the same directory than RGB frames and they should have the same name than the corresponding frame file. Currently supporting 3DScannerApp for iOS export config format (JSON, intrinsics, pose and stamp) and RTAB-Map calibration file format.</string>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="textInteractionFlags">
|
||||
<set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="6" column="0">
|
||||
<widget class="QToolButton" name="toolButton_cameraImages_odom">
|
||||
<property name="text">
|
||||
<string>...</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="7" column="2">
|
||||
<widget class="QLabel" name="label_349">
|
||||
<property name="text">
|
||||
<string>Odometry format. See tool tip for more details on formats. Note that formats without stamps should have the same number of values than the source images.</string>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="textInteractionFlags">
|
||||
<set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="6" column="1">
|
||||
<widget class="QLineEdit" name="lineEdit_cameraImages_odom">
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="9" column="2">
|
||||
<widget class="QLabel" name="label_289">
|
||||
<property name="text">
|
||||
<string>Ground truth format. See tool tip for more details on formats. Note that formats without stamps should have the same number of values than the source images.</string>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="textInteractionFlags">
|
||||
<set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="2">
|
||||
<widget class="QLabel" name="label_251">
|
||||
<property name="text">
|
||||
<string>Timestamps file (*.txt). The file should contain one column. The number of rows should be the same than the number of images in the folder. Not used if "Use file names as timestamps" above is checked. </string>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="textInteractionFlags">
|
||||
<set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="2">
|
||||
<widget class="QLabel" name="label_265">
|
||||
<property name="text">
|
||||
@@ -8099,7 +7779,344 @@ when using the file type, logs are saved in LogRtabmap.txt (located in the worki
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="2">
|
||||
<widget class="QLabel" name="label_255">
|
||||
<property name="text">
|
||||
<string>Use file names as timestamps. Format is epoch time. Example: "1305031102.175304.png".</string>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="textInteractionFlags">
|
||||
<set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="13" column="0">
|
||||
<widget class="QToolButton" name="toolButton_cameraImages_path_scans">
|
||||
<property name="text">
|
||||
<string>...</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="2">
|
||||
<widget class="QLabel" name="label_798">
|
||||
<property name="text">
|
||||
<string>Multi-camera mode: each image is a horizontal stack of N sub-camera images. One calibration file per sub-camera (named <imageBaseName>_<index>.yaml, index starting at 0) must be in the calibration folder. The number of cameras is auto-detected and a local_transform (rig extrinsics) is required in each file.</string>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="textInteractionFlags">
|
||||
<set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="17" column="0">
|
||||
<widget class="QToolButton" name="toolButton_cameraImages_path_imu">
|
||||
<property name="text">
|
||||
<string>...</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="7" column="2">
|
||||
<widget class="QLabel" name="label_348">
|
||||
<property name="text">
|
||||
<string>Odometry file. Select the correct format below.</string>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="textInteractionFlags">
|
||||
<set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="7" column="0">
|
||||
<widget class="QToolButton" name="toolButton_cameraImages_odom">
|
||||
<property name="text">
|
||||
<string>...</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="19" column="1">
|
||||
<widget class="QSpinBox" name="spinBox_cameraImages_max_imu_rate">
|
||||
<property name="toolTip">
|
||||
<string>EuRoC: 200 Hz -> 250 Hz</string>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<number>99999999</number>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="8" column="2">
|
||||
<widget class="QLabel" name="label_349">
|
||||
<property name="text">
|
||||
<string>Odometry format. See tool tip for more details on formats. Note that formats without stamps should have the same number of values than the source images.</string>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="textInteractionFlags">
|
||||
<set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="17" column="1">
|
||||
<widget class="QLineEdit" name="lineEdit_cameraImages_path_imu">
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p>cvs format (comma split): &quot;stamp_sec,gyro_x,gyro_y,gyro_z,acc_x,acc_y,acc_z&quot;</p><p>EuRoC format: &quot;stamp_nanosec,gyro_x,gyro_y,gyro_z,acc_x,acc_y,acc_z&quot;</p></body></html></string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="10" column="2">
|
||||
<widget class="QLabel" name="label_289">
|
||||
<property name="text">
|
||||
<string>Ground truth format. See tool tip for more details on formats. Note that formats without stamps should have the same number of values than the source images.</string>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="textInteractionFlags">
|
||||
<set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="2">
|
||||
<widget class="QLabel" name="label_251">
|
||||
<property name="text">
|
||||
<string>Timestamps file (*.txt). The file should contain one column. The number of rows should be the same than the number of images in the folder. Not used if "Use file names as timestamps" above is checked. </string>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="textInteractionFlags">
|
||||
<set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="1">
|
||||
<widget class="QCheckBox" name="checkBox_cameraImages_timestamps">
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="12" column="1">
|
||||
<widget class="QDoubleSpinBox" name="doubleSpinBox_maxPoseTimeDiff">
|
||||
<property name="suffix">
|
||||
<string> s</string>
|
||||
</property>
|
||||
<property name="decimals">
|
||||
<number>4</number>
|
||||
</property>
|
||||
<property name="maximum">
|
||||
<double>9.990000000000000</double>
|
||||
</property>
|
||||
<property name="singleStep">
|
||||
<double>0.010000000000000</double>
|
||||
</property>
|
||||
<property name="value">
|
||||
<double>0.020000000000000</double>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="1">
|
||||
<widget class="QLineEdit" name="lineEdit_cameraImages_timestamps">
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="13" column="1">
|
||||
<widget class="QLineEdit" name="lineEdit_cameraImages_path_scans">
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QCheckBox" name="checkBox_cameraImages_multiCameraCalibration">
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="13" column="2">
|
||||
<widget class="QLabel" name="label_293">
|
||||
<property name="text">
|
||||
<string>Path to directory containing optional laser scans (*.pcd, *.ply, *.bin [KITTI format]). The directory should have the same size has the images directory. </string>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="textInteractionFlags">
|
||||
<set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QCheckBox" name="checkBox_cameraImages_configForEachFrame">
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="0">
|
||||
<widget class="QToolButton" name="toolButton_cameraImages_timestamps">
|
||||
<property name="text">
|
||||
<string>...</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="9" column="2">
|
||||
<widget class="QLabel" name="label_288">
|
||||
<property name="text">
|
||||
<string>Ground truth file. Select the correct format below.</string>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="textInteractionFlags">
|
||||
<set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="17" column="2">
|
||||
<widget class="QLabel" name="label_463">
|
||||
<property name="text">
|
||||
<string>Path to file containing optional IMU data (*.csv [EuRoC format]). Mouse over the box to show formats.</string>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="textInteractionFlags">
|
||||
<set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="11" column="1">
|
||||
<widget class="QLineEdit" name="lineEdit_cameraImages_gt_transform">
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p>Format (3 values): x y z<br/>Format (6 values): x y z roll pitch yaw<br/>Format (7 values): x y z qx qy qz qw<br/>Format (9 values, 3x3 rotation): r11 r12 r13 r21 r22 r23 r31 r32 r33<br/>Format (12 values, 3x4 transform): r11 r12 r13 tx r21 r22 r23 ty r31 r32 r33 tz</p></body></html></string>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>0 0 0 0 0 0</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="14" column="2">
|
||||
<widget class="QLabel" name="label_294">
|
||||
<property name="text">
|
||||
<string>Local transform from /base_link to /laser_link. Mouse over the box to show formats.</string>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="textInteractionFlags">
|
||||
<set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="8" column="1">
|
||||
<widget class="QComboBox" name="comboBox_cameraImages_odomFormat">
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p>Raw Format (3 values): x y z<br/>Raw Format (6 values): x y z roll pitch yaw<br/>Raw Format (7 values): x y z qx qy qz qw<br/>Raw Format (9 values, 3x3 rotation): r11 r12 r13 r21 r22 r23 r31 r32 r33<br/>Raw Format (12 values, 3x4 transform): r11 r12 r13 tx r21 r22 r23 ty r31 r32 r33 tz</p><p>RGBD-SLAM (stamp tx ty tz qx qy qz qw)<br/>RGBD-SLAM + ID (stamp id tx ty tz qx qy qz qw)<br/>KITTI (stamp + 12 values transform)<br/>TORO<br/>g2o<br/>NewCollege (stamp x y)<br/>Malaga Urban (GPS)<br/>St Lucia Stereo (INS)<br/>EuRoC MAV (stamp,tx,ty,tz,qw,qx,qy,qz...)</p></body></html></string>
|
||||
</property>
|
||||
<property name="sizeAdjustPolicy">
|
||||
<enum>QComboBox::AdjustToContents</enum>
|
||||
</property>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Raw</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>RGBD-SLAM (motion capture)</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>KITTI</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>TORO</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>g2o</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>NewCollege</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Malaga Urban</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>St Lucia Stereo</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>Karlsruhe</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>EuRoC MAV</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>RGBD-SLAM</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>RGBD-SLAM + ID</string>
|
||||
</property>
|
||||
</item>
|
||||
<item>
|
||||
<property name="text">
|
||||
<string>rgbd_bonn</string>
|
||||
</property>
|
||||
</item>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="4" column="1">
|
||||
<widget class="QCheckBox" name="checkBox_cameraImages_syncTimeStamps">
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="15" column="2">
|
||||
<widget class="QLabel" name="label_292">
|
||||
<property name="text">
|
||||
<string>Maximum laser scan points.</string>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="textInteractionFlags">
|
||||
<set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="11" column="2">
|
||||
<widget class="QLabel" name="label_794">
|
||||
<property name="text">
|
||||
<string>Local transform from /base_link to /gt_link. Mouse over the box to show formats. By default, we assume the ground truth matches the base frame, if the ground truth refers to another frame, set this to convert the poses in base frame.</string>
|
||||
@@ -8112,13 +8129,16 @@ when using the file type, logs are saved in LogRtabmap.txt (located in the worki
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="10" column="1">
|
||||
<widget class="QLineEdit" name="lineEdit_cameraImages_gt_transform">
|
||||
<property name="toolTip">
|
||||
<string><html><head/><body><p>Format (3 values): x y z<br/>Format (6 values): x y z roll pitch yaw<br/>Format (7 values): x y z qx qy qz qw<br/>Format (9 values, 3x3 rotation): r11 r12 r13 r21 r22 r23 r31 r32 r33<br/>Format (12 values, 3x4 transform): r11 r12 r13 tx r21 r22 r23 ty r31 r32 r33 tz</p></body></html></string>
|
||||
</property>
|
||||
<item row="12" column="2">
|
||||
<widget class="QLabel" name="label_443">
|
||||
<property name="text">
|
||||
<string>0 0 0 0 0 0</string>
|
||||
<string>Max time difference between data and corresponding pose for format with stamps. If delay is over this threshold, the pose won't be set on data loaded. This is used when odometry and/or ground truth files are set.</string>
|
||||
</property>
|
||||
<property name="wordWrap">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="textInteractionFlags">
|
||||
<set>Qt::LinksAccessibleByMouse|Qt::TextSelectableByMouse</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
|
||||
Reference in New Issue
Block a user