mirror of
https://github.com/introlab/rtabmap.git
synced 2026-10-09 19:39:50 +08:00
merged master to scan_map branch
This commit is contained in:
@@ -389,12 +389,35 @@ class ViewController: GLKViewController, ARSessionDelegate, RTABMapObserver, UIP
|
|||||||
String(format: "Travelled distance: %.2f m\n", distanceTravelled) +
|
String(format: "Travelled distance: %.2f m\n", distanceTravelled) +
|
||||||
String(format: "Pose (x,y,z): %.2f %.2f %.2f", x, y, z)
|
String(format: "Pose (x,y,z): %.2f %.2f %.2f", x, y, z)
|
||||||
}
|
}
|
||||||
if(self.mState == .STATE_MAPPING)
|
if(self.mState == .STATE_MAPPING || self.mState == .STATE_VISUALIZING_CAMERA)
|
||||||
{
|
{
|
||||||
if(loopClosureId > 0) {
|
if(loopClosureId > 0) {
|
||||||
self.showToast(message: "Loop closure detected!", seconds: 1);
|
if(self.mState == .STATE_VISUALIZING_CAMERA) {
|
||||||
|
self.showToast(message: "Localized!", seconds: 1);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
self.showToast(message: "Loop closure detected!", seconds: 1);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if(landmarkDetected > 0) {
|
else if(rejected > 0)
|
||||||
|
{
|
||||||
|
if(inliers >= UserDefaults.standard.integer(forKey: "MinInliers"))
|
||||||
|
{
|
||||||
|
if(optimizationMaxError > 0.0)
|
||||||
|
{
|
||||||
|
self.showToast(message: String(format: "Loop closure rejected, too high graph optimization error (%.3fm: ratio=%.3f < factor=%.1fx).", optimizationMaxError, optimizationMaxErrorRatio, UserDefaults.standard.float(forKey: "MaxOptimizationError")), seconds: 1);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
self.showToast(message: String(format: "Loop closure rejected, graph optimization failed! You may try a different Graph Optimizer (see Mapping options)."), seconds: 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
self.showToast(message: String(format: "Loop closure rejected, not enough inliers (%d/%d < %d).", inliers, matches, UserDefaults.standard.integer(forKey: "MinInliers")), seconds: 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if(landmarkDetected > 0) {
|
||||||
self.showToast(message: "Landmark \(landmarkDetected) detected!", seconds: 1);
|
self.showToast(message: "Landmark \(landmarkDetected) detected!", seconds: 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -305,8 +305,8 @@ private:
|
|||||||
bool _mapLabelsAdded;
|
bool _mapLabelsAdded;
|
||||||
bool _depthAsMask;
|
bool _depthAsMask;
|
||||||
bool _stereoFromMotion;
|
bool _stereoFromMotion;
|
||||||
int _imagePreDecimation;
|
unsigned int _imagePreDecimation;
|
||||||
int _imagePostDecimation;
|
unsigned int _imagePostDecimation;
|
||||||
bool _compressionParallelized;
|
bool _compressionParallelized;
|
||||||
float _laserScanDownsampleStepSize;
|
float _laserScanDownsampleStepSize;
|
||||||
float _laserScanVoxelSize;
|
float _laserScanVoxelSize;
|
||||||
|
|||||||
@@ -108,7 +108,7 @@ public:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
ParametersMap parameters_;
|
ParametersMap parameters_;
|
||||||
int cloudDecimation_;
|
unsigned int cloudDecimation_;
|
||||||
float cloudMaxDepth_;
|
float cloudMaxDepth_;
|
||||||
float cloudMinDepth_;
|
float cloudMinDepth_;
|
||||||
std::vector<float> roiRatios_;
|
std::vector<float> roiRatios_;
|
||||||
|
|||||||
@@ -104,7 +104,7 @@ private:
|
|||||||
bool _fillInfoData;
|
bool _fillInfoData;
|
||||||
float _kalmanProcessNoise;
|
float _kalmanProcessNoise;
|
||||||
float _kalmanMeasurementNoise;
|
float _kalmanMeasurementNoise;
|
||||||
int _imageDecimation;
|
unsigned int _imageDecimation;
|
||||||
bool _alignWithGround;
|
bool _alignWithGround;
|
||||||
bool _publishRAMUsage;
|
bool _publishRAMUsage;
|
||||||
bool _imagesAlreadyRectified;
|
bool _imagesAlreadyRectified;
|
||||||
|
|||||||
@@ -220,8 +220,8 @@ class RTABMAP_EXP Parameters
|
|||||||
RTABMAP_PARAM(Mem, InitWMWithAllNodes, bool, false, "Initialize the Working Memory with all nodes in Long-Term Memory. When false, it is initialized with nodes of the previous session.");
|
RTABMAP_PARAM(Mem, InitWMWithAllNodes, bool, false, "Initialize the Working Memory with all nodes in Long-Term Memory. When false, it is initialized with nodes of the previous session.");
|
||||||
RTABMAP_PARAM(Mem, DepthAsMask, bool, true, "Use depth image as mask when extracting features for vocabulary.");
|
RTABMAP_PARAM(Mem, DepthAsMask, bool, true, "Use depth image as mask when extracting features for vocabulary.");
|
||||||
RTABMAP_PARAM(Mem, StereoFromMotion, bool, false, uFormat("Triangulate features without depth using stereo from motion (odometry). It would be ignored if %s is true and the feature detector used supports masking.", kMemDepthAsMask().c_str()));
|
RTABMAP_PARAM(Mem, StereoFromMotion, bool, false, uFormat("Triangulate features without depth using stereo from motion (odometry). It would be ignored if %s is true and the feature detector used supports masking.", kMemDepthAsMask().c_str()));
|
||||||
RTABMAP_PARAM(Mem, ImagePreDecimation, int, 1, "Image decimation (>=1) before features extraction.");
|
RTABMAP_PARAM(Mem, ImagePreDecimation, unsigned int, 1, uFormat("Decimation of the RGB image before visual feature detection. If depth size is larger than decimated RGB size, depth is decimated to be always at most equal to RGB size. If %s is true and if depth is smaller than decimated RGB, depth may be interpolated to match RGB size for feature detection.",kMemDepthAsMask().c_str()));
|
||||||
RTABMAP_PARAM(Mem, ImagePostDecimation, int, 1, "Image decimation (>=1) of saved data in created signatures (after features extraction). Decimation is done from the original image.");
|
RTABMAP_PARAM(Mem, ImagePostDecimation, unsigned int, 1, uFormat("Decimation of the RGB image before saving it to database. If depth size is larger than decimated RGB size, depth is decimated to be always at most equal to RGB size. Decimation is done from the original image. If set to same value than %s, data already decimated is saved (no need to re-decimate the image).", kMemImagePreDecimation().c_str()));
|
||||||
RTABMAP_PARAM(Mem, CompressionParallelized, bool, true, "Compression of sensor data is multi-threaded.");
|
RTABMAP_PARAM(Mem, CompressionParallelized, bool, true, "Compression of sensor data is multi-threaded.");
|
||||||
RTABMAP_PARAM(Mem, LaserScanDownsampleStepSize, int, 1, "If > 1, downsample the laser scans when creating a signature.");
|
RTABMAP_PARAM(Mem, LaserScanDownsampleStepSize, int, 1, "If > 1, downsample the laser scans when creating a signature.");
|
||||||
RTABMAP_PARAM(Mem, LaserScanVoxelSize, float, 0.0, uFormat("If > 0 m, voxel filtering is done on laser scans when creating a signature. If the laser scan had normals, they will be removed. To recompute the normals, make sure to use \"%s\" or \"%s\" parameters.", kMemLaserScanNormalK().c_str(), kMemLaserScanNormalRadius().c_str()));
|
RTABMAP_PARAM(Mem, LaserScanVoxelSize, float, 0.0, uFormat("If > 0 m, voxel filtering is done on laser scans when creating a signature. If the laser scan had normals, they will be removed. To recompute the normals, make sure to use \"%s\" or \"%s\" parameters.", kMemLaserScanNormalK().c_str(), kMemLaserScanNormalRadius().c_str()));
|
||||||
@@ -450,7 +450,7 @@ class RTABMAP_EXP Parameters
|
|||||||
RTABMAP_PARAM(Odom, KeyFrameThr, float, 0.3, "[Visual] Create a new keyframe when the number of inliers drops under this ratio of features in last frame. Setting the value to 0 means that a keyframe is created for each processed frame.");
|
RTABMAP_PARAM(Odom, KeyFrameThr, float, 0.3, "[Visual] Create a new keyframe when the number of inliers drops under this ratio of features in last frame. Setting the value to 0 means that a keyframe is created for each processed frame.");
|
||||||
RTABMAP_PARAM(Odom, VisKeyFrameThr, int, 150, "[Visual] Create a new keyframe when the number of inliers drops under this threshold. Setting the value to 0 means that a keyframe is created for each processed frame.");
|
RTABMAP_PARAM(Odom, VisKeyFrameThr, int, 150, "[Visual] Create a new keyframe when the number of inliers drops under this threshold. Setting the value to 0 means that a keyframe is created for each processed frame.");
|
||||||
RTABMAP_PARAM(Odom, ScanKeyFrameThr, float, 0.9, "[Geometry] Create a new keyframe when the number of ICP inliers drops under this ratio of points in last frame's scan. Setting the value to 0 means that a keyframe is created for each processed frame.");
|
RTABMAP_PARAM(Odom, ScanKeyFrameThr, float, 0.9, "[Geometry] Create a new keyframe when the number of ICP inliers drops under this ratio of points in last frame's scan. Setting the value to 0 means that a keyframe is created for each processed frame.");
|
||||||
RTABMAP_PARAM(Odom, ImageDecimation, int, 1, "Decimation of the images before registration. Negative decimation is done from RGB size instead of depth size (if depth is smaller than RGB, it may be interpolated depending of the decimation value).");
|
RTABMAP_PARAM(Odom, ImageDecimation, unsigned int, 1, uFormat("Decimation of the RGB image before registration. If depth size is larger than decimated RGB size, depth is decimated to be always at most equal to RGB size. If %s is true and if depth is smaller than decimated RGB, depth may be interpolated to match RGB size for feature detection.", kVisDepthAsMask().c_str()));
|
||||||
RTABMAP_PARAM(Odom, AlignWithGround, bool, false, "Align odometry with the ground on initialization.");
|
RTABMAP_PARAM(Odom, AlignWithGround, bool, false, "Align odometry with the ground on initialization.");
|
||||||
|
|
||||||
// Odometry Frame-to-Map
|
// Odometry Frame-to-Map
|
||||||
@@ -722,7 +722,7 @@ class RTABMAP_EXP Parameters
|
|||||||
|
|
||||||
// Occupancy Grid
|
// Occupancy Grid
|
||||||
RTABMAP_PARAM(Grid, FromDepth, bool, true, "Create occupancy grid from depth image(s), otherwise it is created from laser scan.");
|
RTABMAP_PARAM(Grid, FromDepth, bool, true, "Create occupancy grid from depth image(s), otherwise it is created from laser scan.");
|
||||||
RTABMAP_PARAM(Grid, DepthDecimation, int, 4, uFormat("[%s=true] Decimation of the depth image before creating cloud. Negative decimation is done from RGB size instead of depth size (if depth is smaller than RGB, it may be interpolated depending of the decimation value).", kGridDepthDecimation().c_str()));
|
RTABMAP_PARAM(Grid, DepthDecimation, unsigned int, 4, uFormat("[%s=true] Decimation of the depth image before creating cloud.", kGridDepthDecimation().c_str()));
|
||||||
RTABMAP_PARAM(Grid, RangeMin, float, 0.0, "Minimum range from sensor.");
|
RTABMAP_PARAM(Grid, RangeMin, float, 0.0, "Minimum range from sensor.");
|
||||||
RTABMAP_PARAM(Grid, RangeMax, float, 5.0, "Maximum range from sensor. 0=inf.");
|
RTABMAP_PARAM(Grid, RangeMax, float, 5.0, "Maximum range from sensor. 0=inf.");
|
||||||
RTABMAP_PARAM_STR(Grid, DepthRoiRatios, "0.0 0.0 0.0 0.0", uFormat("[%s=true] Region of interest ratios [left, right, top, bottom].", kGridFromDepth().c_str()));
|
RTABMAP_PARAM_STR(Grid, DepthRoiRatios, "0.0 0.0 0.0 0.0", uFormat("[%s=true] Region of interest ratios [left, right, top, bottom].", kGridFromDepth().c_str()));
|
||||||
|
|||||||
+50
-29
@@ -585,11 +585,11 @@ void Memory::parseParameters(const ParametersMap & parameters)
|
|||||||
UASSERT_MSG(_maxStMemSize >= 0, uFormat("value=%d", _maxStMemSize).c_str());
|
UASSERT_MSG(_maxStMemSize >= 0, uFormat("value=%d", _maxStMemSize).c_str());
|
||||||
UASSERT_MSG(_similarityThreshold >= 0.0f && _similarityThreshold <= 1.0f, uFormat("value=%f", _similarityThreshold).c_str());
|
UASSERT_MSG(_similarityThreshold >= 0.0f && _similarityThreshold <= 1.0f, uFormat("value=%f", _similarityThreshold).c_str());
|
||||||
UASSERT_MSG(_recentWmRatio >= 0.0f && _recentWmRatio <= 1.0f, uFormat("value=%f", _recentWmRatio).c_str());
|
UASSERT_MSG(_recentWmRatio >= 0.0f && _recentWmRatio <= 1.0f, uFormat("value=%f", _recentWmRatio).c_str());
|
||||||
if(_imagePreDecimation <= 0)
|
if(_imagePreDecimation == 0)
|
||||||
{
|
{
|
||||||
_imagePreDecimation = 1;
|
_imagePreDecimation = 1;
|
||||||
}
|
}
|
||||||
if(_imagePostDecimation <= 0)
|
if(_imagePostDecimation == 0)
|
||||||
{
|
{
|
||||||
_imagePostDecimation = 1;
|
_imagePostDecimation = 1;
|
||||||
}
|
}
|
||||||
@@ -4304,6 +4304,24 @@ Signature * Memory::createSignature(const SensorData & inputData, const Transfor
|
|||||||
if(_imagePreDecimation > 1)
|
if(_imagePreDecimation > 1)
|
||||||
{
|
{
|
||||||
preDecimation = _imagePreDecimation;
|
preDecimation = _imagePreDecimation;
|
||||||
|
int decimationDepth = _imagePreDecimation;
|
||||||
|
if( !data.cameraModels().empty() &&
|
||||||
|
data.cameraModels()[0].imageHeight()>0 &&
|
||||||
|
data.cameraModels()[0].imageWidth()>0)
|
||||||
|
{
|
||||||
|
// decimate from RGB image size
|
||||||
|
int targetSize = data.cameraModels()[0].imageHeight() / _imagePreDecimation;
|
||||||
|
if(targetSize >= data.depthRaw().rows)
|
||||||
|
{
|
||||||
|
decimationDepth = 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
decimationDepth = (int)ceil(float(data.depthRaw().rows) / float(targetSize));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
UDEBUG("decimation rgbOrLeft(rows=%d)=%d, depthOrRight(rows=%d)=%d", data.imageRaw().rows, _imagePreDecimation, data.depthOrRightRaw().rows, decimationDepth);
|
||||||
|
|
||||||
std::vector<CameraModel> cameraModels = decimatedData.cameraModels();
|
std::vector<CameraModel> cameraModels = decimatedData.cameraModels();
|
||||||
for(unsigned int i=0; i<cameraModels.size(); ++i)
|
for(unsigned int i=0; i<cameraModels.size(); ++i)
|
||||||
{
|
{
|
||||||
@@ -4311,21 +4329,10 @@ Signature * Memory::createSignature(const SensorData & inputData, const Transfor
|
|||||||
}
|
}
|
||||||
if(!cameraModels.empty())
|
if(!cameraModels.empty())
|
||||||
{
|
{
|
||||||
if(decimatedData.depthRaw().rows == decimatedData.imageRaw().rows &&
|
decimatedData.setRGBDImage(
|
||||||
decimatedData.depthRaw().cols == decimatedData.imageRaw().cols)
|
util2d::decimate(decimatedData.imageRaw(), _imagePreDecimation),
|
||||||
{
|
util2d::decimate(decimatedData.depthOrRightRaw(), decimationDepth),
|
||||||
decimatedData.setRGBDImage(
|
cameraModels);
|
||||||
util2d::decimate(decimatedData.imageRaw(), _imagePreDecimation),
|
|
||||||
util2d::decimate(decimatedData.depthOrRightRaw(), _imagePreDecimation),
|
|
||||||
cameraModels);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
decimatedData.setRGBDImage(
|
|
||||||
util2d::decimate(decimatedData.imageRaw(), _imagePreDecimation),
|
|
||||||
decimatedData.depthOrRightRaw(),
|
|
||||||
cameraModels);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -4361,13 +4368,13 @@ Signature * Memory::createSignature(const SensorData & inputData, const Transfor
|
|||||||
{
|
{
|
||||||
depthMask = util2d::interpolate(decimatedData.depthRaw(), imageMono.rows/decimatedData.depthRaw().rows, 0.1f);
|
depthMask = util2d::interpolate(decimatedData.depthRaw(), imageMono.rows/decimatedData.depthRaw().rows, 0.1f);
|
||||||
}
|
}
|
||||||
else if(_imagePreDecimation > 1)
|
else
|
||||||
{
|
{
|
||||||
UWARN("%s=%d is not compatible between RGB and depth images, the depth mask cannot be used! (decimated RGB=%dx%d, depth=%dx%d)",
|
UWARN("%s is true, but RGB size (%dx%d) modulo depth size (%dx%d) is not 0. Ignoring depth mask for feature detection (%s=%d).",
|
||||||
Parameters::kMemImagePreDecimation().c_str(),
|
Parameters::kMemDepthAsMask().c_str(),
|
||||||
_imagePreDecimation,
|
|
||||||
imageMono.cols, imageMono.rows,
|
imageMono.cols, imageMono.rows,
|
||||||
decimatedData.depthRaw().cols, decimatedData.depthRaw().rows);
|
decimatedData.depthRaw().cols, decimatedData.depthRaw().rows,
|
||||||
|
Parameters::kMemImagePreDecimation().c_str(), _imagePreDecimation);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -4381,14 +4388,14 @@ Signature * Memory::createSignature(const SensorData & inputData, const Transfor
|
|||||||
|
|
||||||
// A: Adjust keypoint position so that descriptors are correctly extracted
|
// A: Adjust keypoint position so that descriptors are correctly extracted
|
||||||
// B: In case we provided corresponding 3D features
|
// B: In case we provided corresponding 3D features
|
||||||
if(preDecimation > 1 || useProvided3dPoints)
|
if(_imagePreDecimation > 1 || useProvided3dPoints)
|
||||||
{
|
{
|
||||||
float decimationRatio = 1.0f / float(preDecimation);
|
float decimationRatio = 1.0f / float(_imagePreDecimation);
|
||||||
double log2value = log(double(preDecimation))/log(2.0);
|
double log2value = log(double(_imagePreDecimation))/log(2.0);
|
||||||
for(unsigned int i=0; i < keypoints.size(); ++i)
|
for(unsigned int i=0; i < keypoints.size(); ++i)
|
||||||
{
|
{
|
||||||
cv::KeyPoint & kpt = keypoints[i];
|
cv::KeyPoint & kpt = keypoints[i];
|
||||||
if(preDecimation > 1)
|
if(_imagePreDecimation > 1)
|
||||||
{
|
{
|
||||||
kpt.pt.x *= decimationRatio;
|
kpt.pt.x *= decimationRatio;
|
||||||
kpt.pt.y *= decimationRatio;
|
kpt.pt.y *= decimationRatio;
|
||||||
@@ -4876,11 +4883,25 @@ Signature * Memory::createSignature(const SensorData & inputData, const Transfor
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if(!data.rightRaw().empty() ||
|
int decimationDepth = _imagePreDecimation;
|
||||||
(data.depthRaw().rows == image.rows && data.depthRaw().cols == image.cols))
|
if( !data.cameraModels().empty() &&
|
||||||
|
data.cameraModels()[0].imageHeight()>0 &&
|
||||||
|
data.cameraModels()[0].imageWidth()>0)
|
||||||
{
|
{
|
||||||
depthOrRightImage = util2d::decimate(depthOrRightImage, _imagePostDecimation);
|
// decimate from RGB image size
|
||||||
|
int targetSize = data.cameraModels()[0].imageHeight() / _imagePreDecimation;
|
||||||
|
if(targetSize >= data.depthRaw().rows)
|
||||||
|
{
|
||||||
|
decimationDepth = 1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
decimationDepth = (int)ceil(float(data.depthRaw().rows) / float(targetSize));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
UDEBUG("decimation rgbOrLeft(rows=%d)=%d, depthOrRight(rows=%d)=%d", data.imageRaw().rows, _imagePostDecimation, data.depthOrRightRaw().rows, decimationDepth);
|
||||||
|
|
||||||
|
depthOrRightImage = util2d::decimate(depthOrRightImage, decimationDepth);
|
||||||
image = util2d::decimate(image, _imagePostDecimation);
|
image = util2d::decimate(image, _imagePostDecimation);
|
||||||
for(unsigned int i=0; i<cameraModels.size(); ++i)
|
for(unsigned int i=0; i<cameraModels.size(); ++i)
|
||||||
{
|
{
|
||||||
|
|||||||
+19
-21
@@ -559,19 +559,17 @@ Transform Odometry::process(SensorData & data, const Transform & guessIn, Odomet
|
|||||||
|
|
||||||
UTimer time;
|
UTimer time;
|
||||||
Transform t;
|
Transform t;
|
||||||
int decimationRgb = abs(_imageDecimation);
|
if(_imageDecimation > 1 && !data.imageRaw().empty())
|
||||||
if((_imageDecimation > 1 || _imageDecimation < -1) && !data.imageRaw().empty())
|
|
||||||
{
|
{
|
||||||
// Decimation of images with calibrations
|
// Decimation of images with calibrations
|
||||||
SensorData decimatedData = data;
|
SensorData decimatedData = data;
|
||||||
int decimationDepth = abs(_imageDecimation);
|
int decimationDepth = _imageDecimation;
|
||||||
if(_imageDecimation<0 &&
|
if( !data.cameraModels().empty() &&
|
||||||
!data.cameraModels().empty() &&
|
|
||||||
data.cameraModels()[0].imageHeight()>0 &&
|
data.cameraModels()[0].imageHeight()>0 &&
|
||||||
data.cameraModels()[0].imageWidth()>0)
|
data.cameraModels()[0].imageWidth()>0)
|
||||||
{
|
{
|
||||||
// decimate from RGB image size
|
// decimate from RGB image size
|
||||||
int targetSize = data.cameraModels()[0].imageHeight() / decimationRgb;
|
int targetSize = data.cameraModels()[0].imageHeight() / _imageDecimation;
|
||||||
if(targetSize >= data.depthRaw().rows)
|
if(targetSize >= data.depthRaw().rows)
|
||||||
{
|
{
|
||||||
decimationDepth = 1;
|
decimationDepth = 1;
|
||||||
@@ -581,14 +579,14 @@ Transform Odometry::process(SensorData & data, const Transform & guessIn, Odomet
|
|||||||
decimationDepth = (int)ceil(float(data.depthRaw().rows) / float(targetSize));
|
decimationDepth = (int)ceil(float(data.depthRaw().rows) / float(targetSize));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
UDEBUG("decimation rgbOrLeft(rows=%d)=%d, depthOrRight(rows=%d)=%d", data.imageRaw().rows, decimationRgb, data.depthOrRightRaw().rows, decimationDepth);
|
UDEBUG("decimation rgbOrLeft(rows=%d)=%d, depthOrRight(rows=%d)=%d", data.imageRaw().rows, _imageDecimation, data.depthOrRightRaw().rows, decimationDepth);
|
||||||
|
|
||||||
cv::Mat rgbLeft = util2d::decimate(decimatedData.imageRaw(), decimationRgb);
|
cv::Mat rgbLeft = util2d::decimate(decimatedData.imageRaw(), _imageDecimation);
|
||||||
cv::Mat depthRight = util2d::decimate(decimatedData.depthOrRightRaw(), decimationDepth);
|
cv::Mat depthRight = util2d::decimate(decimatedData.depthOrRightRaw(), decimationDepth);
|
||||||
std::vector<CameraModel> cameraModels = decimatedData.cameraModels();
|
std::vector<CameraModel> cameraModels = decimatedData.cameraModels();
|
||||||
for(unsigned int i=0; i<cameraModels.size(); ++i)
|
for(unsigned int i=0; i<cameraModels.size(); ++i)
|
||||||
{
|
{
|
||||||
cameraModels[i] = cameraModels[i].scaled(1.0/double(decimationRgb));
|
cameraModels[i] = cameraModels[i].scaled(1.0/double(_imageDecimation));
|
||||||
}
|
}
|
||||||
if(!cameraModels.empty())
|
if(!cameraModels.empty())
|
||||||
{
|
{
|
||||||
@@ -599,7 +597,7 @@ Transform Odometry::process(SensorData & data, const Transform & guessIn, Odomet
|
|||||||
StereoCameraModel stereoModel = decimatedData.stereoCameraModel();
|
StereoCameraModel stereoModel = decimatedData.stereoCameraModel();
|
||||||
if(stereoModel.isValidForProjection())
|
if(stereoModel.isValidForProjection())
|
||||||
{
|
{
|
||||||
stereoModel.scale(1.0/double(decimationRgb));
|
stereoModel.scale(1.0/double(_imageDecimation));
|
||||||
}
|
}
|
||||||
decimatedData.setStereoImage(rgbLeft, depthRight, stereoModel);
|
decimatedData.setStereoImage(rgbLeft, depthRight, stereoModel);
|
||||||
}
|
}
|
||||||
@@ -610,12 +608,12 @@ Transform Odometry::process(SensorData & data, const Transform & guessIn, Odomet
|
|||||||
|
|
||||||
// transform back the keypoints in the original image
|
// transform back the keypoints in the original image
|
||||||
std::vector<cv::KeyPoint> kpts = decimatedData.keypoints();
|
std::vector<cv::KeyPoint> kpts = decimatedData.keypoints();
|
||||||
double log2value = log(double(decimationRgb))/log(2.0);
|
double log2value = log(double(_imageDecimation))/log(2.0);
|
||||||
for(unsigned int i=0; i<kpts.size(); ++i)
|
for(unsigned int i=0; i<kpts.size(); ++i)
|
||||||
{
|
{
|
||||||
kpts[i].pt.x *= decimationRgb;
|
kpts[i].pt.x *= _imageDecimation;
|
||||||
kpts[i].pt.y *= decimationRgb;
|
kpts[i].pt.y *= _imageDecimation;
|
||||||
kpts[i].size *= decimationRgb;
|
kpts[i].size *= _imageDecimation;
|
||||||
kpts[i].octave += log2value;
|
kpts[i].octave += log2value;
|
||||||
}
|
}
|
||||||
data.setFeatures(kpts, decimatedData.keypoints3D(), decimatedData.descriptors());
|
data.setFeatures(kpts, decimatedData.keypoints3D(), decimatedData.descriptors());
|
||||||
@@ -626,19 +624,19 @@ Transform Odometry::process(SensorData & data, const Transform & guessIn, Odomet
|
|||||||
UASSERT(info->newCorners.size() == info->refCorners.size() || info->refCorners.empty());
|
UASSERT(info->newCorners.size() == info->refCorners.size() || info->refCorners.empty());
|
||||||
for(unsigned int i=0; i<info->newCorners.size(); ++i)
|
for(unsigned int i=0; i<info->newCorners.size(); ++i)
|
||||||
{
|
{
|
||||||
info->refCorners[i].x *= decimationRgb;
|
info->refCorners[i].x *= _imageDecimation;
|
||||||
info->refCorners[i].y *= decimationRgb;
|
info->refCorners[i].y *= _imageDecimation;
|
||||||
if(!info->refCorners.empty())
|
if(!info->refCorners.empty())
|
||||||
{
|
{
|
||||||
info->newCorners[i].x *= decimationRgb;
|
info->newCorners[i].x *= _imageDecimation;
|
||||||
info->newCorners[i].y *= decimationRgb;
|
info->newCorners[i].y *= _imageDecimation;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
for(std::multimap<int, cv::KeyPoint>::iterator iter=info->words.begin(); iter!=info->words.end(); ++iter)
|
for(std::multimap<int, cv::KeyPoint>::iterator iter=info->words.begin(); iter!=info->words.end(); ++iter)
|
||||||
{
|
{
|
||||||
iter->second.pt.x *= decimationRgb;
|
iter->second.pt.x *= _imageDecimation;
|
||||||
iter->second.pt.y *= decimationRgb;
|
iter->second.pt.y *= _imageDecimation;
|
||||||
iter->second.size *= decimationRgb;
|
iter->second.size *= _imageDecimation;
|
||||||
iter->second.octave += log2value;
|
iter->second.octave += log2value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -394,6 +394,13 @@ Transform RegistrationVis::computeTransformationImpl(
|
|||||||
{
|
{
|
||||||
depthMask = util2d::interpolate(fromSignature.sensorData().depthRaw(), fromSignature.sensorData().imageRaw().rows/fromSignature.sensorData().depthRaw().rows, 0.1f);
|
depthMask = util2d::interpolate(fromSignature.sensorData().depthRaw(), fromSignature.sensorData().imageRaw().rows/fromSignature.sensorData().depthRaw().rows, 0.1f);
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
UWARN("%s is true, but RGB size (%dx%d) modulo depth size (%dx%d) is not 0. Ignoring depth mask for feature detection.",
|
||||||
|
Parameters::kVisDepthAsMask().c_str(),
|
||||||
|
fromSignature.sensorData().imageRaw().rows, fromSignature.sensorData().imageRaw().cols,
|
||||||
|
fromSignature.sensorData().depthRaw().rows, fromSignature.sensorData().depthRaw().cols);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
kptsFrom = _detectorFrom->generateKeypoints(
|
kptsFrom = _detectorFrom->generateKeypoints(
|
||||||
@@ -613,6 +620,13 @@ Transform RegistrationVis::computeTransformationImpl(
|
|||||||
{
|
{
|
||||||
depthMask = util2d::interpolate(toSignature.sensorData().depthRaw(), imageTo.rows/toSignature.sensorData().depthRaw().rows, 0.1f);
|
depthMask = util2d::interpolate(toSignature.sensorData().depthRaw(), imageTo.rows/toSignature.sensorData().depthRaw().rows, 0.1f);
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
UWARN("%s is true, but RGB size (%dx%d) modulo depth size (%dx%d) is not 0. Ignoring depth mask for feature detection.",
|
||||||
|
Parameters::kVisDepthAsMask().c_str(),
|
||||||
|
toSignature.sensorData().imageRaw().rows, toSignature.sensorData().imageRaw().cols,
|
||||||
|
toSignature.sensorData().depthRaw().rows, toSignature.sensorData().depthRaw().cols);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
kptsTo = _detectorTo->generateKeypoints(
|
kptsTo = _detectorTo->generateKeypoints(
|
||||||
|
|||||||
@@ -1893,12 +1893,23 @@ void MainWindow::processStats(const rtabmap::Statistics & stat)
|
|||||||
|
|
||||||
bool fastMovement = (bool)uValue(stat.data(), Statistics::kMemoryFast_movement(), 0.0f);
|
bool fastMovement = (bool)uValue(stat.data(), Statistics::kMemoryFast_movement(), 0.0f);
|
||||||
|
|
||||||
|
int rehearsalMerged = (int)uValue(stat.data(), Statistics::kMemoryRehearsal_merged(), 0.0f);
|
||||||
|
|
||||||
// update cache
|
// update cache
|
||||||
Signature signature;
|
Signature signature;
|
||||||
if(stat.getLastSignatureData().id() == stat.refImageId())
|
if(stat.getLastSignatureData().id() == stat.refImageId())
|
||||||
{
|
{
|
||||||
signature = stat.getLastSignatureData();
|
signature = stat.getLastSignatureData();
|
||||||
|
}
|
||||||
|
else if(rehearsalMerged>0 &&
|
||||||
|
rehearsalMerged == stat.getLastSignatureData().id() &&
|
||||||
|
_cachedSignatures.contains(rehearsalMerged))
|
||||||
|
{
|
||||||
|
signature = _cachedSignatures.value(rehearsalMerged);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(signature.id()!=0)
|
||||||
|
{
|
||||||
// make sure data are uncompressed
|
// make sure data are uncompressed
|
||||||
// We don't need to uncompress images if we don't show them
|
// We don't need to uncompress images if we don't show them
|
||||||
bool uncompressImages = !signature.sensorData().imageCompressed().empty() && (
|
bool uncompressImages = !signature.sensorData().imageCompressed().empty() && (
|
||||||
@@ -1919,7 +1930,8 @@ void MainWindow::processStats(const rtabmap::Statistics & stat)
|
|||||||
uncompressScan?&tmpScan:0,
|
uncompressScan?&tmpScan:0,
|
||||||
0, &tmpG, &tmpO, &tmpE);
|
0, &tmpG, &tmpO, &tmpE);
|
||||||
|
|
||||||
if( uStr2Bool(_preferencesDialog->getParameter(Parameters::kMemIncrementalMemory())) &&
|
if( stat.getLastSignatureData().id() == stat.refImageId() &&
|
||||||
|
uStr2Bool(_preferencesDialog->getParameter(Parameters::kMemIncrementalMemory())) &&
|
||||||
signature.getWeight()>=0) // ignore intermediate nodes for the cache
|
signature.getWeight()>=0) // ignore intermediate nodes for the cache
|
||||||
{
|
{
|
||||||
if(smallMovement || fastMovement)
|
if(smallMovement || fastMovement)
|
||||||
@@ -1963,8 +1975,6 @@ void MainWindow::processStats(const rtabmap::Statistics & stat)
|
|||||||
|
|
||||||
_ui->label_matchId->clear();
|
_ui->label_matchId->clear();
|
||||||
|
|
||||||
|
|
||||||
int rehearsalMerged = (int)uValue(stat.data(), Statistics::kMemoryRehearsal_merged(), 0.0f);
|
|
||||||
bool rehearsedSimilarity = (float)uValue(stat.data(), Statistics::kMemoryRehearsal_id(), 0.0f) != 0.0f;
|
bool rehearsedSimilarity = (float)uValue(stat.data(), Statistics::kMemoryRehearsal_id(), 0.0f) != 0.0f;
|
||||||
int proximityTimeDetections = (int)uValue(stat.data(), Statistics::kProximityTime_detections(), 0.0f);
|
int proximityTimeDetections = (int)uValue(stat.data(), Statistics::kProximityTime_detections(), 0.0f);
|
||||||
bool scanMatchingSuccess = (bool)uValue(stat.data(), Statistics::kNeighborLinkRefiningAccepted(), 0.0f);
|
bool scanMatchingSuccess = (bool)uValue(stat.data(), Statistics::kNeighborLinkRefiningAccepted(), 0.0f);
|
||||||
|
|||||||
@@ -95,7 +95,11 @@
|
|||||||
<enum>QFrame::Raised</enum>
|
<enum>QFrame::Raised</enum>
|
||||||
</property>
|
</property>
|
||||||
<property name="currentIndex">
|
<property name="currentIndex">
|
||||||
|
<<<<<<< HEAD
|
||||||
<number>13</number>
|
<number>13</number>
|
||||||
|
=======
|
||||||
|
<number>19</number>
|
||||||
|
>>>>>>> eabf3e3d57572b30878512e47b051986c3592cea
|
||||||
</property>
|
</property>
|
||||||
<widget class="QWidget" name="page_22">
|
<widget class="QWidget" name="page_22">
|
||||||
<layout class="QVBoxLayout" name="verticalLayout_29" stretch="0,1">
|
<layout class="QVBoxLayout" name="verticalLayout_29" stretch="0,1">
|
||||||
@@ -8906,7 +8910,7 @@ If set to false, classic RTAB-Map loop closure detection is done using only imag
|
|||||||
<item row="14" column="1">
|
<item row="14" column="1">
|
||||||
<widget class="QLabel" name="label_retrieved_13">
|
<widget class="QLabel" name="label_retrieved_13">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Image pre decimation. This option can be used to reduce image size before features extraction.</string>
|
<string>Image pre decimation. Decimation of the RGB image before visual feature detection. If depth size is larger than decimated RGB size, depth is decimated to be always at most equal to RGB size. If Vocabulary->Depth As Mask is true and if depth is smaller than decimated RGB, depth may be interpolated to match RGB size for feature detection.</string>
|
||||||
</property>
|
</property>
|
||||||
<property name="wordWrap">
|
<property name="wordWrap">
|
||||||
<bool>true</bool>
|
<bool>true</bool>
|
||||||
@@ -9024,7 +9028,7 @@ If set to false, classic RTAB-Map loop closure detection is done using only imag
|
|||||||
<item row="15" column="1">
|
<item row="15" column="1">
|
||||||
<widget class="QLabel" name="label_retrieved_6">
|
<widget class="QLabel" name="label_retrieved_6">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Image post decimation. This option can be used to save images in lower resolution (size/decimation). It is done on the original image.</string>
|
<string>Image post decimation. Decimation of the RGB image before saving it to database. If depth size is larger than decimated RGB size, depth is decimated to be always at most equal to RGB size. Decimation is done from the original image. If set to same value than Pre Decimation, data already decimated is saved (no need to re-decimate the image).</string>
|
||||||
</property>
|
</property>
|
||||||
<property name="wordWrap">
|
<property name="wordWrap">
|
||||||
<bool>true</bool>
|
<bool>true</bool>
|
||||||
@@ -12278,7 +12282,7 @@ If set to false, classic RTAB-Map loop closure detection is done using only imag
|
|||||||
<item row="0" column="0">
|
<item row="0" column="0">
|
||||||
<widget class="QSpinBox" name="spinBox_grid_decimation">
|
<widget class="QSpinBox" name="spinBox_grid_decimation">
|
||||||
<property name="minimum">
|
<property name="minimum">
|
||||||
<number>-32</number>
|
<number>1</number>
|
||||||
</property>
|
</property>
|
||||||
<property name="maximum">
|
<property name="maximum">
|
||||||
<number>32</number>
|
<number>32</number>
|
||||||
@@ -12291,7 +12295,7 @@ If set to false, classic RTAB-Map loop closure detection is done using only imag
|
|||||||
<item row="0" column="1">
|
<item row="0" column="1">
|
||||||
<widget class="QLabel" name="label_322">
|
<widget class="QLabel" name="label_322">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Image Decimation (1-2-4-8-...). Negative decimation is done from RGB size instead of depth size (if depth is smaller than RGB, it may be interpolated depending of the decimation value).</string>
|
<string>Decimation of the depth image before creating cloud.</string>
|
||||||
</property>
|
</property>
|
||||||
<property name="wordWrap">
|
<property name="wordWrap">
|
||||||
<bool>true</bool>
|
<bool>true</bool>
|
||||||
@@ -13855,7 +13859,7 @@ If set to false, classic RTAB-Map loop closure detection is done using only imag
|
|||||||
<item row="9" column="0">
|
<item row="9" column="0">
|
||||||
<widget class="QSpinBox" name="odom_imageDecimation">
|
<widget class="QSpinBox" name="odom_imageDecimation">
|
||||||
<property name="minimum">
|
<property name="minimum">
|
||||||
<number>-32</number>
|
<number>1</number>
|
||||||
</property>
|
</property>
|
||||||
<property name="maximum">
|
<property name="maximum">
|
||||||
<number>32</number>
|
<number>32</number>
|
||||||
@@ -13878,7 +13882,7 @@ If set to false, classic RTAB-Map loop closure detection is done using only imag
|
|||||||
<item row="9" column="1">
|
<item row="9" column="1">
|
||||||
<widget class="QLabel" name="label_248">
|
<widget class="QLabel" name="label_248">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Decimation of images before features extraction. Negative decimation is done from RGB size instead of depth size (if depth is smaller than RGB, it may be interpolated depending of the decimation value).</string>
|
<string>Decimation of the RGB image before registration. If depth size is larger than decimated RGB size, depth is decimated to be always at most equal to RGB size. If Visual Registration -> Visual Feature -> Depth as Mask is true and if depth is smaller than decimated RGB, depth may be interpolated to match RGB size for feature detection.</string>
|
||||||
</property>
|
</property>
|
||||||
<property name="wordWrap">
|
<property name="wordWrap">
|
||||||
<bool>true</bool>
|
<bool>true</bool>
|
||||||
|
|||||||
Reference in New Issue
Block a user