Updated default Vis/EstimationType=1 (PnP). Added all fovis and viso2 parameters.

This commit is contained in:
matlabbe
2017-05-30 18:29:49 -04:00
parent f6e21bd6c8
commit 21e716b08a
12 changed files with 1633 additions and 85 deletions

View File

@@ -58,6 +58,8 @@ private:
fovis::StereoCalibration * stereoCalib_; fovis::StereoCalibration * stereoCalib_;
fovis::DepthImage * depthImage_; fovis::DepthImage * depthImage_;
fovis::StereoDepth * stereoDepth_; fovis::StereoDepth * stereoDepth_;
ParametersMap fovisParameters_;
bool lost_;
}; };
} }

View File

@@ -54,6 +54,7 @@ private:
bool lost_; bool lost_;
bool keep_reference_frame_; bool keep_reference_frame_;
Transform reference_motion_; Transform reference_motion_;
ParametersMap viso2Parameters_;
}; };
} }

View File

@@ -383,7 +383,7 @@ class RTABMAP_EXP Parameters
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, 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, AlignWithGround, bool, false, "Align odometry with the ground on initialization."); RTABMAP_PARAM(Odom, AlignWithGround, bool, false, "Align odometry with the ground on initialization.");
// Odometry Bag-of-words // Odometry Frame-to-Map
RTABMAP_PARAM(OdomF2M, MaxSize, int, 2000, "[Visual] Local map size: If > 0 (example 5000), the odometry will maintain a local map of X maximum words."); RTABMAP_PARAM(OdomF2M, MaxSize, int, 2000, "[Visual] Local map size: If > 0 (example 5000), the odometry will maintain a local map of X maximum words.");
RTABMAP_PARAM(OdomF2M, MaxNewFeatures, int, 0, "[Visual] Maximum features (sorted by keypoint response) added to local map from a new key-frame. 0 means no limit."); RTABMAP_PARAM(OdomF2M, MaxNewFeatures, int, 0, "[Visual] Maximum features (sorted by keypoint response) added to local map from a new key-frame. 0 means no limit.");
RTABMAP_PARAM(OdomF2M, ScanMaxSize, int, 2000, "[Geometry] Maximum local scan map size."); RTABMAP_PARAM(OdomF2M, ScanMaxSize, int, 2000, "[Geometry] Maximum local scan map size.");
@@ -397,6 +397,53 @@ class RTABMAP_EXP Parameters
RTABMAP_PARAM(OdomMono, MinTranslation, float, 0.02, "Minimum translation to add new points to local map. On initialization, translation x 5 is used as the minimum."); RTABMAP_PARAM(OdomMono, MinTranslation, float, 0.02, "Minimum translation to add new points to local map. On initialization, translation x 5 is used as the minimum.");
RTABMAP_PARAM(OdomMono, MaxVariance, float, 0.01, "Maximum variance to add new points to local map."); RTABMAP_PARAM(OdomMono, MaxVariance, float, 0.01, "Maximum variance to add new points to local map.");
// Odometry Fovis
RTABMAP_PARAM(OdomFovis, FeatureWindowSize, int, 9, "The size of the n x n image patch surrounding each feature, used for keypoint matching.");
RTABMAP_PARAM(OdomFovis, MaxPyramidLevel, int, 3, "The maximum Gaussian pyramid level to process the image at. Pyramid level 1 corresponds to the original image.");
RTABMAP_PARAM(OdomFovis, MinPyramidLevel, int, 0, "The minimum pyramid level.");
RTABMAP_PARAM(OdomFovis, TargetPixelsPerFeature, int, 250, "Specifies the desired feature density as a ratio of input image pixels per feature detected. This number is used to control the adaptive feature thresholding.");
RTABMAP_PARAM(OdomFovis, FastThreshold, int, 20, "FAST threshold.");
RTABMAP_PARAM(OdomFovis, UseAdaptiveThreshold, bool, true, "Use FAST adaptive threshold.");
RTABMAP_PARAM(OdomFovis, FastThresholdAdaptiveGain, double, 0.005, "FAST threshold adaptive gain.");
RTABMAP_PARAM(OdomFovis, UseHomographyInitialization, bool, true, "Use homography initialization.");
RTABMAP_PARAM(OdomFovis, UseBucketing, bool, true, "");
RTABMAP_PARAM(OdomFovis, BucketWidth, int, 80, "");
RTABMAP_PARAM(OdomFovis, BucketHeight, int, 80, "");
RTABMAP_PARAM(OdomFovis, MaxKeypointsPerBucket, int, 25, "");
RTABMAP_PARAM(OdomFovis, UseImageNormalization, bool, false, "");
RTABMAP_PARAM(OdomFovis, InlierMaxReprojectionError, double, 1.5, "The maximum image-space reprojection error (in pixels) a feature match is allowed to have and still be considered an inlier in the set of features used for motion estimation.");
RTABMAP_PARAM(OdomFovis, CliqueInlierThreshold, double, 0.1, "See Howard's greedy max-clique algorithm for determining the maximum set of mutually consisten feature matches. This specifies the compatibility threshold, in meters.");
RTABMAP_PARAM(OdomFovis, MinFeaturesForEstimate, int, 10, "Minimum number of features in the inlier set for the motion estimate to be considered valid.");
RTABMAP_PARAM(OdomFovis, MaxMeanReprojectionError, double, 10.0, "Maximum mean reprojection error over the inlier feature matches for the motion estimate to be considered valid.");
RTABMAP_PARAM(OdomFovis, UseSubpixelRefinement, bool, true, "Specifies whether or not to refine feature matches to subpixel resolution.");
RTABMAP_PARAM(OdomFovis, FeatureSearchWindow, int, 25, "Specifies the size of the search window to apply when searching for feature matches across time frames. The search is conducted around the feature location predicted by the initial rotation estimate.");
RTABMAP_PARAM(OdomFovis, UpdateTargetFeaturesWithRefined, bool, false, "When subpixel refinement is enabled, the refined feature locations can be saved over the original feature locations. This has a slightly negative impact on frame-to-frame visual odometry, but is likely better when using this library as part of a visual SLAM algorithm.");
RTABMAP_PARAM(OdomFovis, StereoRequireMutualMatch, bool, true, "");
RTABMAP_PARAM(OdomFovis, StereoMaxDistEpipolarLine, double, 1.5, "");
RTABMAP_PARAM(OdomFovis, StereoMaxRefinementDisplacement, double, 1.0, "");
RTABMAP_PARAM(OdomFovis, StereoMaxDisparity, int, 128, "");
// Odometry viso2
RTABMAP_PARAM(OdomViso2, RansacIters, int, 200, "Number of RANSAC iterations.");
RTABMAP_PARAM(OdomViso2, InlierThreshold, double, 2.0, "Fundamental matrix inlier threshold.");
RTABMAP_PARAM(OdomViso2, Reweighting, bool, true, "Lower border weights (more robust to calibration errors).");
RTABMAP_PARAM(OdomViso2, MatchNmsN, int, 3, "Non-max-suppression: min. distance between maxima (in pixels).");
RTABMAP_PARAM(OdomViso2, MatchNmsTau, int, 50, "Non-max-suppression: interest point peakiness threshold.");
RTABMAP_PARAM(OdomViso2, MatchBinsize, int, 50, "Matching bin width/height (affects efficiency only).");
RTABMAP_PARAM(OdomViso2, MatchRadius, int, 200, "Matching radius (du/dv in pixels).");
RTABMAP_PARAM(OdomViso2, MatchDispTolerance, int, 2, "Disparity tolerance for stereo matches (in pixels).");
RTABMAP_PARAM(OdomViso2, MatchOutlierDispTolerance, int, 5, "Outlier removal: disparity tolerance (in pixels).");
RTABMAP_PARAM(OdomViso2, MatchOutlierFlowTolerance, int, 5, "Outlier removal: flow tolerance (in pixels).");
RTABMAP_PARAM(OdomViso2, MatchMultiStage, bool, true, "Multistage matching (denser and faster).");
RTABMAP_PARAM(OdomViso2, MatchHalfResolution, bool, true, "Match at half resolution, refine at full resolution.");
RTABMAP_PARAM(OdomViso2, MatchRefinement, int, 1, "Refinement (0=none,1=pixel,2=subpixel).");
RTABMAP_PARAM(OdomViso2, BucketMaxFeatures, int, 2, "Maximal number of features per bucket.");
RTABMAP_PARAM(OdomViso2, BucketWidth, double, 50, "Width of bucket.");
RTABMAP_PARAM(OdomViso2, BucketHeight, double, 50, "Height of bucket.");
// Common registration parameters // Common registration parameters
RTABMAP_PARAM(Reg, VarianceFromInliersCount, bool, false, "Set variance as the inverse of the number of inliers. Otherwise, the variance is computed as the average 3D position error of the inliers."); RTABMAP_PARAM(Reg, VarianceFromInliersCount, bool, false, "Set variance as the inverse of the number of inliers. Otherwise, the variance is computed as the average 3D position error of the inliers.");
RTABMAP_PARAM(Reg, VarianceNormalized, bool, false, "Normalize covariance values. Position variances are multiplied by norm of the transform and orientation variances are multiplied by angle of the transform."); RTABMAP_PARAM(Reg, VarianceNormalized, bool, false, "Normalize covariance values. Position variances are multiplied by norm of the transform and orientation variances are multiplied by angle of the transform.");
@@ -404,7 +451,7 @@ class RTABMAP_EXP Parameters
RTABMAP_PARAM(Reg, Force3DoF, bool, false, "Force 3 degrees-of-freedom transform (3Dof: x,y and yaw). Parameters z, roll and pitch will be set to 0."); RTABMAP_PARAM(Reg, Force3DoF, bool, false, "Force 3 degrees-of-freedom transform (3Dof: x,y and yaw). Parameters z, roll and pitch will be set to 0.");
// Visual registration parameters // Visual registration parameters
RTABMAP_PARAM(Vis, EstimationType, int, 0, "Motion estimation approach: 0:3D->3D, 1:3D->2D (PnP), 2:2D->2D (Epipolar Geometry)"); RTABMAP_PARAM(Vis, EstimationType, int, 1, "Motion estimation approach: 0:3D->3D, 1:3D->2D (PnP), 2:2D->2D (Epipolar Geometry)");
RTABMAP_PARAM(Vis, ForwardEstOnly, bool, true, "Forward estimation only (A->B). If false, a transformation is also computed in backward direction (B->A), then the two resulting transforms are merged (middle interpolation between the transforms)."); RTABMAP_PARAM(Vis, ForwardEstOnly, bool, true, "Forward estimation only (A->B). If false, a transformation is also computed in backward direction (B->A), then the two resulting transforms are merged (middle interpolation between the transforms).");
RTABMAP_PARAM(Vis, InlierDistance, float, 0.1, uFormat("[%s = 0] Maximum distance for feature correspondences. Used by 3D->3D estimation approach.", kVisEstimationType().c_str())); RTABMAP_PARAM(Vis, InlierDistance, float, 0.1, uFormat("[%s = 0] Maximum distance for feature correspondences. Used by 3D->3D estimation approach.", kVisEstimationType().c_str()));
RTABMAP_PARAM(Vis, RefineIterations, int, 5, uFormat("[%s = 0] Number of iterations used to refine the transformation found by RANSAC. 0 means that the transformation is not refined.", kVisEstimationType().c_str())); RTABMAP_PARAM(Vis, RefineIterations, int, 5, uFormat("[%s = 0] Number of iterations used to refine the transformation found by RANSAC. 0 means that the transformation is not refined.", kVisEstimationType().c_str()));
@@ -424,7 +471,6 @@ class RTABMAP_EXP Parameters
#else #else
RTABMAP_PARAM(Vis, FeatureType, int, 6, "0=SURF 1=SIFT 2=ORB 3=FAST/FREAK 4=FAST/BRIEF 5=GFTT/FREAK 6=GFTT/BRIEF 7=BRISK 8=GFTT/ORB 9=FREAK."); RTABMAP_PARAM(Vis, FeatureType, int, 6, "0=SURF 1=SIFT 2=ORB 3=FAST/FREAK 4=FAST/BRIEF 5=GFTT/FREAK 6=GFTT/BRIEF 7=BRISK 8=GFTT/ORB 9=FREAK.");
#endif #endif
RTABMAP_PARAM(Vis, MaxFeatures, int, 1000, "0 no limits."); RTABMAP_PARAM(Vis, MaxFeatures, int, 1000, "0 no limits.");
RTABMAP_PARAM(Vis, MaxDepth, float, 0, "Max depth of the features (0 means no limit)."); RTABMAP_PARAM(Vis, MaxDepth, float, 0, "Max depth of the features (0 means no limit).");
RTABMAP_PARAM(Vis, MinDepth, float, 0, "Min depth of the features (0 means no limit)."); RTABMAP_PARAM(Vis, MinDepth, float, 0, "Min depth of the features (0 means no limit).");

View File

@@ -45,8 +45,14 @@ OdometryFovis::OdometryFovis(const ParametersMap & parameters) :
rect_(0), rect_(0),
stereoCalib_(0), stereoCalib_(0),
depthImage_(0), depthImage_(0),
stereoDepth_(0) stereoDepth_(0),
lost_(false)
{ {
fovisParameters_ = Parameters::filterParameters(parameters, "OdomFovis");
if(parameters.find(Parameters::kOdomVisKeyFrameThr()) != parameters.end())
{
fovisParameters_.insert(*parameters.find(Parameters::kOdomVisKeyFrameThr()));
}
} }
OdometryFovis::~OdometryFovis() OdometryFovis::~OdometryFovis()
@@ -104,6 +110,7 @@ void OdometryFovis::reset(const Transform & initialPose)
delete stereoDepth_; delete stereoDepth_;
stereoDepth_ = 0; stereoDepth_ = 0;
} }
lost_ = false;
#endif #endif
} }
@@ -150,7 +157,45 @@ Transform OdometryFovis::computeTransform(
UFATAL("Not supported color type!"); UFATAL("Not supported color type!");
} }
fovis::VisualOdometryOptions options = fovis::VisualOdometry::getDefaultOptions(); fovis::VisualOdometryOptions options;
if(fovis_ == 0 || (data.cameraModels().size() != 1 && stereoDepth_ == 0))
{
options = fovis::VisualOdometry::getDefaultOptions();
ParametersMap defaults = Parameters::getDefaultParameters("OdomFovis");
options["feature-window-size"] = uValue(fovisParameters_, Parameters::kOdomFovisFeatureWindowSize(), defaults.at(Parameters::kOdomFovisFeatureWindowSize()));
options["max-pyramid-level"] = uValue(fovisParameters_, Parameters::kOdomFovisMaxPyramidLevel(), defaults.at(Parameters::kOdomFovisMaxPyramidLevel()));
options["min-pyramid-level"] = uValue(fovisParameters_, Parameters::kOdomFovisMinPyramidLevel(), defaults.at(Parameters::kOdomFovisMinPyramidLevel()));
options["target-pixels-per-feature"] = uValue(fovisParameters_, Parameters::kOdomFovisTargetPixelsPerFeature(), defaults.at(Parameters::kOdomFovisTargetPixelsPerFeature()));
options["fast-threshold"] = uValue(fovisParameters_, Parameters::kOdomFovisFastThreshold(), defaults.at(Parameters::kOdomFovisFastThreshold()));
options["use-adaptive-threshold"] = uValue(fovisParameters_, Parameters::kOdomFovisUseAdaptiveThreshold(), defaults.at(Parameters::kOdomFovisUseAdaptiveThreshold()));
options["fast-threshold-adaptive-gain"] = uValue(fovisParameters_, Parameters::kOdomFovisFastThresholdAdaptiveGain(), defaults.at(Parameters::kOdomFovisFastThresholdAdaptiveGain()));
options["use-homography-initialization"] = uValue(fovisParameters_, Parameters::kOdomFovisUseHomographyInitialization(), defaults.at(Parameters::kOdomFovisUseHomographyInitialization()));
options["ref-frame-change-threshold"] = uValue(fovisParameters_, Parameters::kOdomVisKeyFrameThr(), uNumber2Str(Parameters::defaultOdomVisKeyFrameThr()));
// OdometryFrame
options["use-bucketing"] = uValue(fovisParameters_, Parameters::kOdomFovisUseBucketing(), defaults.at(Parameters::kOdomFovisUseBucketing()));
options["bucket-width"] = uValue(fovisParameters_, Parameters::kOdomFovisBucketWidth(), defaults.at(Parameters::kOdomFovisBucketWidth()));
options["bucket-height"] = uValue(fovisParameters_, Parameters::kOdomFovisBucketHeight(), defaults.at(Parameters::kOdomFovisBucketHeight()));
options["max-keypoints-per-bucket"] = uValue(fovisParameters_, Parameters::kOdomFovisMaxKeypointsPerBucket(), defaults.at(Parameters::kOdomFovisMaxKeypointsPerBucket()));
options["use-image-normalization"] = uValue(fovisParameters_, Parameters::kOdomFovisUseImageNormalization(), defaults.at(Parameters::kOdomFovisUseImageNormalization()));
// MotionEstimator
options["inlier-max-reprojection-error"] = uValue(fovisParameters_, Parameters::kOdomFovisInlierMaxReprojectionError(), defaults.at(Parameters::kOdomFovisInlierMaxReprojectionError()));
options["clique-inlier-threshold"] = uValue(fovisParameters_, Parameters::kOdomFovisCliqueInlierThreshold(), defaults.at(Parameters::kOdomFovisCliqueInlierThreshold()));
options["min-features-for-estimate"] = uValue(fovisParameters_, Parameters::kOdomFovisMinFeaturesForEstimate(), defaults.at(Parameters::kOdomFovisMinFeaturesForEstimate()));
options["max-mean-reprojection-error"] = uValue(fovisParameters_, Parameters::kOdomFovisMaxMeanReprojectionError(), defaults.at(Parameters::kOdomFovisMaxMeanReprojectionError()));
options["use-subpixel-refinement"] = uValue(fovisParameters_, Parameters::kOdomFovisUseSubpixelRefinement(), defaults.at(Parameters::kOdomFovisUseSubpixelRefinement()));
options["feature-search-window"] = uValue(fovisParameters_, Parameters::kOdomFovisFeatureSearchWindow(), defaults.at(Parameters::kOdomFovisFeatureSearchWindow()));
options["update-target-features-with-refined"] = uValue(fovisParameters_, Parameters::kOdomFovisUpdateTargetFeaturesWithRefined(), defaults.at(Parameters::kOdomFovisUpdateTargetFeaturesWithRefined()));
// StereoDepth
options["stereo-require-mutual-match"] = uValue(fovisParameters_, Parameters::kOdomFovisStereoRequireMutualMatch(), defaults.at(Parameters::kOdomFovisStereoRequireMutualMatch()));
options["stereo-max-dist-epipolar-line"] = uValue(fovisParameters_, Parameters::kOdomFovisStereoMaxDistEpipolarLine(), defaults.at(Parameters::kOdomFovisStereoMaxDistEpipolarLine()));
options["stereo-max-refinement-displacement"] = uValue(fovisParameters_, Parameters::kOdomFovisStereoMaxRefinementDisplacement(), defaults.at(Parameters::kOdomFovisStereoMaxRefinementDisplacement()));
options["stereo-max-disparity"] = uValue(fovisParameters_, Parameters::kOdomFovisStereoMaxDisparity(), defaults.at(Parameters::kOdomFovisStereoMaxDisparity()));
}
fovis::DepthSource * depthSource = 0; fovis::DepthSource * depthSource = 0;
cv::Mat depth; cv::Mat depth;
cv::Mat right; cv::Mat right;
@@ -283,22 +328,35 @@ Transform OdometryFovis::computeTransform(
fovis_ = new fovis::VisualOdometry(rect_, options); fovis_ = new fovis::VisualOdometry(rect_, options);
} }
fovis_->processFrame(gray.data, depthSource); fovis_->processFrame(gray.data, depthSource);
// get the motion estimate for this frame to the previous frame. // get the motion estimate for this frame to the previous frame.
t = Transform::fromEigen3d(fovis_->getMotionEstimate()); t = Transform::fromEigen3d(fovis_->getMotionEstimate());
fovis::MotionEstimateStatusCode statusCode = fovis::SUCCESS; cv::Mat covariance;
if(fovis_->getMotionEstimator()) fovis::MotionEstimateStatusCode statusCode = fovis_->getMotionEstimator()->getMotionEstimateStatus();
{
statusCode = fovis_->getMotionEstimator()->getMotionEstimateStatus();
}
if(statusCode > fovis::SUCCESS) if(statusCode > fovis::SUCCESS)
{ {
UWARN("Fovis error status: %s", fovis::MotionEstimateStatusCodeStrings[statusCode]); UWARN("Fovis error status: %s", fovis::MotionEstimateStatusCodeStrings[statusCode]);
t.setNull(); t.setNull();
lost_ = true;
covariance = cv::Mat::eye(6,6, CV_64FC1)*9999.0;
}
else if(lost_)
{
lost_ = false;
// we are not lost anymore but we don't know where we are now according to last valid pose
covariance = cv::Mat::eye(6,6, CV_64FC1)*9999.0;
}
else
{
const Eigen::MatrixXd& cov = fovis_->getMotionEstimator()->getMotionEstimateCov();
if(cov.cols() == 6 && cov.rows() == 6 && cov(0,0) > 0.0)
{
covariance = cv::Mat::eye(6,6, CV_64FC1);
memcpy(covariance.data, cov.data(), 36*sizeof(double));
covariance *= 100.0; // to be in the same scale than loop closure detection
}
} }
if(!t.isNull() && !t.isIdentity() && !localTransform.isIdentity() && !localTransform.isNull()) if(!t.isNull() && !t.isIdentity() && !localTransform.isIdentity() && !localTransform.isNull())
@@ -314,12 +372,28 @@ Transform OdometryFovis::computeTransform(
info->features = fovis_->getTargetFrame()->getNumDetectedKeypoints(); info->features = fovis_->getTargetFrame()->getNumDetectedKeypoints();
info->matches = fovis_->getMotionEstimator()->getNumMatches(); info->matches = fovis_->getMotionEstimator()->getNumMatches();
info->inliers = fovis_->getMotionEstimator()->getNumInliers(); info->inliers = fovis_->getMotionEstimator()->getNumInliers();
const Eigen::MatrixXd& cov = fovis_->getMotionEstimator()->getMotionEstimateCov(); info->covariance = covariance;
if(cov.cols() == 6 && cov.rows() == 6 && cov(0,0) > 0.0)
if(this->isInfoDataFilled())
{ {
info->covariance = cv::Mat::eye(6,6, CV_64FC1); const fovis::FeatureMatch * matches = fovis_->getMotionEstimator()->getMatches();
memcpy(info->covariance.data, cov.data(), 36*sizeof(double)); int numMatches = fovis_->getMotionEstimator()->getNumMatches();
info->covariance *= 100.0; // to be in the same scale than loop closure detection if(matches && numMatches>0)
{
info->refCorners.resize(numMatches);
info->newCorners.resize(numMatches);
info->cornerInliers.resize(numMatches);
int oi=0;
for (int i = 0; i < numMatches; ++i)
{
info->refCorners[i].x = matches[i].ref_keypoint->base_uv[0];
info->refCorners[i].y = matches[i].ref_keypoint->base_uv[1];
info->newCorners[i].x = matches[i].target_keypoint->base_uv[0];
info->newCorners[i].y = matches[i].target_keypoint->base_uv[1];
info->cornerInliers[oi++] = i;
}
info->cornerInliers.resize(oi);
}
} }
} }

View File

@@ -62,6 +62,7 @@ OdometryViso2::OdometryViso2(const ParametersMap & parameters) :
reference_motion_(Transform::getIdentity()) reference_motion_(Transform::getIdentity())
{ {
Parameters::parse(parameters, Parameters::kOdomVisKeyFrameThr(), ref_frame_inlier_threshold_); Parameters::parse(parameters, Parameters::kOdomVisKeyFrameThr(), ref_frame_inlier_threshold_);
viso2Parameters_ = Parameters::filterParameters(parameters, "OdomViso2");
} }
OdometryViso2::~OdometryViso2() OdometryViso2::~OdometryViso2()
@@ -162,6 +163,30 @@ Transform OdometryViso2::computeTransform(
params.calib.cu = data.stereoCameraModel().left().cx(); params.calib.cu = data.stereoCameraModel().left().cx();
params.calib.cv = data.stereoCameraModel().left().cy(); params.calib.cv = data.stereoCameraModel().left().cy();
params.calib.f = data.stereoCameraModel().left().fx(); params.calib.f = data.stereoCameraModel().left().fx();
Parameters::parse(viso2Parameters_, Parameters::kOdomViso2RansacIters(), params.ransac_iters);
Parameters::parse(viso2Parameters_, Parameters::kOdomViso2InlierThreshold(), params.inlier_threshold);
Parameters::parse(viso2Parameters_, Parameters::kOdomViso2Reweighting(), params.reweighting);
Parameters::parse(viso2Parameters_, Parameters::kOdomViso2MatchNmsN(), params.match.nms_n);
Parameters::parse(viso2Parameters_, Parameters::kOdomViso2MatchNmsTau(), params.match.nms_tau);
Parameters::parse(viso2Parameters_, Parameters::kOdomViso2MatchBinsize(), params.match.match_binsize);
Parameters::parse(viso2Parameters_, Parameters::kOdomViso2MatchRadius(), params.match.match_radius);
Parameters::parse(viso2Parameters_, Parameters::kOdomViso2MatchDispTolerance(), params.match.match_disp_tolerance);
Parameters::parse(viso2Parameters_, Parameters::kOdomViso2MatchOutlierDispTolerance(), params.match.outlier_disp_tolerance);
Parameters::parse(viso2Parameters_, Parameters::kOdomViso2MatchOutlierFlowTolerance(), params.match.outlier_flow_tolerance);
bool multistage = Parameters::defaultOdomViso2MatchMultiStage();
bool halfResolution = Parameters::defaultOdomViso2MatchHalfResolution();
Parameters::parse(viso2Parameters_, Parameters::kOdomViso2MatchMultiStage(), multistage);
Parameters::parse(viso2Parameters_, Parameters::kOdomViso2MatchHalfResolution() , halfResolution);
params.match.multi_stage = multistage?1:0;
params.match.half_resolution = halfResolution?1:0;
Parameters::parse(viso2Parameters_, Parameters::kOdomViso2MatchRefinement(), params.match.refinement);
Parameters::parse(viso2Parameters_, Parameters::kOdomViso2BucketMaxFeatures(), params.bucket.max_features);
Parameters::parse(viso2Parameters_, Parameters::kOdomViso2BucketWidth(), params.bucket.bucket_width);
Parameters::parse(viso2Parameters_, Parameters::kOdomViso2BucketHeight(), params.bucket.bucket_height);
viso2_ = new VisualOdometryStereo(params); viso2_ = new VisualOdometryStereo(params);
viso2_->process(leftGray.data, rightGray.data, dims); viso2_->process(leftGray.data, rightGray.data, dims);
@@ -245,19 +270,22 @@ Transform OdometryViso2::computeTransform(
info->covariance = covariance; info->covariance = covariance;
} }
if(this->isInfoDataFilled())
{
std::vector<Matcher::p_match> matches = viso2_->getMatches(); std::vector<Matcher::p_match> matches = viso2_->getMatches();
info->refCorners.resize(matches.size()); info->refCorners.resize(matches.size());
info->newCorners.resize(matches.size()); info->newCorners.resize(matches.size());
info->cornerInliers.resize(matches.size()); info->cornerInliers.resize(matches.size());
for (size_t i = 0; i < matches.size(); ++i) for (size_t i = 0; i < matches.size(); ++i)
{ {
info->refCorners[i].x = matches[i].u1c; info->refCorners[i].x = matches[i].u1p;
info->refCorners[i].y = matches[i].v1c; info->refCorners[i].y = matches[i].v1p;
info->newCorners[i].x = matches[i].u1p; info->newCorners[i].x = matches[i].u1c;
info->newCorners[i].y = matches[i].v1p; info->newCorners[i].y = matches[i].v1c;
info->cornerInliers[i] = i; info->cornerInliers[i] = i;
} }
} }
}
UINFO("Odom update time = %fs lost=%s", timer.elapsed(), lost_?"true":"false"); UINFO("Odom update time = %fs lost=%s", timer.elapsed(), lost_?"true":"false");

View File

@@ -298,8 +298,8 @@ private slots:
void addParameter(double value); void addParameter(double value);
void addParameter(const QString & value); void addParameter(const QString & value);
void updatePredictionPlot(); void updatePredictionPlot();
void updateKpROI();
void updateOdometryVisibility(); void updateOdometryVisibility();
void updateKpROI();
void updateStereoDisparityVisibility(); void updateStereoDisparityVisibility();
void useOdomFeatures(); void useOdomFeatures();
void useGridProjRayTracing(); void useGridProjRayTracing();

View File

@@ -78,6 +78,17 @@ AboutDialog::AboutDialog(QWidget * parent) :
_ui->label_gtsam->setText(Optimizer::isAvailable(Optimizer::kTypeGTSAM)?"Yes":"No"); _ui->label_gtsam->setText(Optimizer::isAvailable(Optimizer::kTypeGTSAM)?"Yes":"No");
_ui->label_cvsba->setText(Optimizer::isAvailable(Optimizer::kTypeCVSBA)?"Yes":"No"); _ui->label_cvsba->setText(Optimizer::isAvailable(Optimizer::kTypeCVSBA)?"Yes":"No");
#ifdef RTABMAP_FOVIS
_ui->label_fovis->setText("Yes");
#else
_ui->label_fovis->setText("No");
#endif
#ifdef RTABMAP_VISO2
_ui->label_viso2->setText("Yes");
#else
_ui->label_viso2->setText("No");
#endif
} }
AboutDialog::~AboutDialog() AboutDialog::~AboutDialog()

View File

@@ -1210,10 +1210,12 @@ void MainWindow::processOdometry(const rtabmap::OdometryEvent & odom, bool dataI
Qt::yellow); Qt::yellow);
} }
} }
else if(odom.info().type == (int)Odometry::kTypeF2F || odom.info().type == (int)Odometry::kTypeViso2) else if(odom.info().type == (int)Odometry::kTypeF2F ||
odom.info().type == (int)Odometry::kTypeViso2 ||
odom.info().type == (int)Odometry::kTypeFovis)
{ {
std::vector<cv::KeyPoint> kpts; std::vector<cv::KeyPoint> kpts;
cv::KeyPoint::convert(odom.info().refCorners, kpts, 7); cv::KeyPoint::convert(odom.info().newCorners, kpts, 7);
_ui->imageView_odometry->setFeatures( _ui->imageView_odometry->setFeatures(
kpts, kpts,
odom.data().depthRaw(), odom.data().depthRaw(),
@@ -1223,10 +1225,10 @@ void MainWindow::processOdometry(const rtabmap::OdometryEvent & odom, bool dataI
//detect if it is OdometryMono intitialization //detect if it is OdometryMono intitialization
bool monoInitialization = false; bool monoInitialization = false;
//if(_preferencesDialog->getOdomStrategy() == ?? && odom.info().type == (int)Odometry::kTypeF2F) if(_preferencesDialog->getOdomStrategy() == 4 && odom.info().type == (int)Odometry::kTypeF2F)
//{ {
// monoInitialization = true; monoInitialization = true;
//} }
_ui->imageView_odometry->clearLines(); _ui->imageView_odometry->clearLines();
if(lost && !monoInitialization) if(lost && !monoInitialization)
@@ -1270,7 +1272,9 @@ void MainWindow::processOdometry(const rtabmap::OdometryEvent & odom, bool dataI
} }
} }
} }
if((odom.info().type == (int)Odometry::kTypeF2F || odom.info().type == (int)Odometry::kTypeViso2) && odom.info().refCorners.size()) if((odom.info().type == (int)Odometry::kTypeF2F ||
odom.info().type == (int)Odometry::kTypeViso2 ||
odom.info().type == (int)Odometry::kTypeFovis) && odom.info().refCorners.size())
{ {
if(_ui->imageView_odometry->isFeaturesShown() || _ui->imageView_odometry->isLinesShown()) if(_ui->imageView_odometry->isFeaturesShown() || _ui->imageView_odometry->isLinesShown())
{ {
@@ -1286,10 +1290,10 @@ void MainWindow::processOdometry(const rtabmap::OdometryEvent & odom, bool dataI
if(_ui->imageView_odometry->isLinesShown()) if(_ui->imageView_odometry->isLinesShown())
{ {
_ui->imageView_odometry->addLine( _ui->imageView_odometry->addLine(
odom.info().refCorners[i].x,
odom.info().refCorners[i].y,
odom.info().newCorners[i].x, odom.info().newCorners[i].x,
odom.info().newCorners[i].y, odom.info().newCorners[i].y,
odom.info().refCorners[i].x,
odom.info().refCorners[i].y,
inliers.find(i) != inliers.end()?Qt::blue:Qt::yellow); inliers.find(i) != inliers.end()?Qt::blue:Qt::yellow);
} }
} }

View File

@@ -31,6 +31,7 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#include "rtabmap/core/util3d_filtering.h" #include "rtabmap/core/util3d_filtering.h"
#include "rtabmap/core/util3d.h" #include "rtabmap/core/util3d.h"
#include "rtabmap/core/OdometryEvent.h" #include "rtabmap/core/OdometryEvent.h"
#include "rtabmap/core/Odometry.h"
#include "rtabmap/utilite/ULogger.h" #include "rtabmap/utilite/ULogger.h"
#include "rtabmap/utilite/UConversion.h" #include "rtabmap/utilite/UConversion.h"
#include "rtabmap/utilite/UCv2Qt.h" #include "rtabmap/utilite/UCv2Qt.h"
@@ -379,14 +380,16 @@ void OdometryViewer::processData(const rtabmap::OdometryEvent & odom)
if(!odom.data().imageRaw().empty()) if(!odom.data().imageRaw().empty())
{ {
if(odom.info().type == 0) if(odom.info().type == (int)Odometry::kTypeF2M)
{ {
imageView_->setFeatures(odom.info().words, odom.data().depthRaw(), Qt::yellow); imageView_->setFeatures(odom.info().words, odom.data().depthRaw(), Qt::yellow);
} }
else if(odom.info().type == 1) else if(odom.info().type == (int)Odometry::kTypeF2F ||
odom.info().type == (int)Odometry::kTypeViso2 ||
odom.info().type == (int)Odometry::kTypeFovis)
{ {
std::vector<cv::KeyPoint> kpts; std::vector<cv::KeyPoint> kpts;
cv::KeyPoint::convert(odom.info().refCorners, kpts); cv::KeyPoint::convert(odom.info().newCorners, kpts, 7);
imageView_->setFeatures(kpts, odom.data().depthRaw(), Qt::red); imageView_->setFeatures(kpts, odom.data().depthRaw(), Qt::red);
} }
@@ -418,7 +421,7 @@ void OdometryViewer::processData(const rtabmap::OdometryEvent & odom)
imageView_->setImageDepth(uCvMat2QImage(odom.data().depthOrRightRaw())); imageView_->setImageDepth(uCvMat2QImage(odom.data().depthOrRightRaw()));
} }
if(odom.info().type == 0) if(odom.info().type == Odometry::kTypeF2M)
{ {
if(imageView_->isFeaturesShown()) if(imageView_->isFeaturesShown())
{ {
@@ -433,7 +436,9 @@ void OdometryViewer::processData(const rtabmap::OdometryEvent & odom)
} }
} }
} }
if(odom.info().type == 1 && odom.info().cornerInliers.size()) if((odom.info().type == (int)Odometry::kTypeF2F ||
odom.info().type == (int)Odometry::kTypeViso2 ||
odom.info().type == (int)Odometry::kTypeFovis) && odom.info().cornerInliers.size())
{ {
if(imageView_->isFeaturesShown() || imageView_->isLinesShown()) if(imageView_->isFeaturesShown() || imageView_->isLinesShown())
{ {
@@ -448,10 +453,10 @@ void OdometryViewer::processData(const rtabmap::OdometryEvent & odom)
if(imageView_->isLinesShown()) if(imageView_->isLinesShown())
{ {
imageView_->addLine( imageView_->addLine(
odom.info().refCorners[odom.info().cornerInliers[i]].x,
odom.info().refCorners[odom.info().cornerInliers[i]].y,
odom.info().newCorners[odom.info().cornerInliers[i]].x, odom.info().newCorners[odom.info().cornerInliers[i]].x,
odom.info().newCorners[odom.info().cornerInliers[i]].y, odom.info().newCorners[odom.info().cornerInliers[i]].y,
odom.info().refCorners[odom.info().cornerInliers[i]].x,
odom.info().refCorners[odom.info().cornerInliers[i]].y,
Qt::blue); Qt::blue);
} }
} }

View File

@@ -920,6 +920,55 @@ PreferencesDialog::PreferencesDialog(QWidget * parent) :
_ui->doubleSpinBox_kalmanProcessNoise->setObjectName(Parameters::kOdomKalmanProcessNoise().c_str()); _ui->doubleSpinBox_kalmanProcessNoise->setObjectName(Parameters::kOdomKalmanProcessNoise().c_str());
_ui->doubleSpinBox_kalmanMeasurementNoise->setObjectName(Parameters::kOdomKalmanMeasurementNoise().c_str()); _ui->doubleSpinBox_kalmanMeasurementNoise->setObjectName(Parameters::kOdomKalmanMeasurementNoise().c_str());
//Odometry Fovis
_ui->spinBox_OdomFovisFeatureWindowSize->setObjectName(Parameters::kOdomFovisFeatureWindowSize().c_str());
_ui->spinBox_OdomFovisMaxPyramidLevel->setObjectName(Parameters::kOdomFovisMaxPyramidLevel().c_str());
_ui->spinBox_OdomFovisMinPyramidLevel->setObjectName(Parameters::kOdomFovisMinPyramidLevel().c_str());
_ui->spinBox_OdomFovisTargetPixelsPerFeature->setObjectName(Parameters::kOdomFovisTargetPixelsPerFeature().c_str());
_ui->spinBox_OdomFovisFastThreshold->setObjectName(Parameters::kOdomFovisFastThreshold().c_str());
_ui->checkBox_OdomFovisUseAdaptiveThreshold->setObjectName(Parameters::kOdomFovisUseAdaptiveThreshold().c_str());
_ui->doubleSpinBox_OdomFovisFastThresholdAdaptiveGain->setObjectName(Parameters::kOdomFovisFastThresholdAdaptiveGain().c_str());
_ui->checkBox_OdomFovisUseHomographyInitialization->setObjectName(Parameters::kOdomFovisUseHomographyInitialization().c_str());
_ui->checkBox_OdomFovisUseBucketing->setObjectName(Parameters::kOdomFovisUseBucketing().c_str());
_ui->spinBox_OdomFovisBucketWidth->setObjectName(Parameters::kOdomFovisBucketWidth().c_str());
_ui->spinBox_OdomFovisBucketHeight->setObjectName(Parameters::kOdomFovisBucketHeight().c_str());
_ui->spinBox_OdomFovisMaxKeypointsPerBucket->setObjectName(Parameters::kOdomFovisMaxKeypointsPerBucket().c_str());
_ui->checkBox_OdomFovisUseImageNormalization->setObjectName(Parameters::kOdomFovisUseImageNormalization().c_str());
_ui->doubleSpinBox_OdomFovisInlierMaxReprojectionError->setObjectName(Parameters::kOdomFovisInlierMaxReprojectionError().c_str());
_ui->doubleSpinBox_OdomFovisCliqueInlierThreshold->setObjectName(Parameters::kOdomFovisCliqueInlierThreshold().c_str());
_ui->spinBox_OdomFovisMinFeaturesForEstimate->setObjectName(Parameters::kOdomFovisMinFeaturesForEstimate().c_str());
_ui->doubleSpinBox_OdomFovisMaxMeanReprojectionError->setObjectName(Parameters::kOdomFovisMaxMeanReprojectionError().c_str());
_ui->checkBox_OdomFovisUseSubpixelRefinement->setObjectName(Parameters::kOdomFovisUseSubpixelRefinement().c_str());
_ui->spinBox_OdomFovisFeatureSearchWindow->setObjectName(Parameters::kOdomFovisFeatureSearchWindow().c_str());
_ui->checkBox_OdomFovisUpdateTargetFeaturesWithRefined->setObjectName(Parameters::kOdomFovisUpdateTargetFeaturesWithRefined().c_str());
_ui->checkBox_OdomFovisStereoRequireMutualMatch->setObjectName(Parameters::kOdomFovisStereoRequireMutualMatch().c_str());
_ui->doubleSpinBox_OdomFovisStereoMaxDistEpipolarLine->setObjectName(Parameters::kOdomFovisStereoMaxDistEpipolarLine().c_str());
_ui->doubleSpinBox_OdomFovisStereoMaxRefinementDisplacement->setObjectName(Parameters::kOdomFovisStereoMaxRefinementDisplacement().c_str());
_ui->spinBox_OdomFovisStereoMaxDisparity->setObjectName(Parameters::kOdomFovisStereoMaxDisparity().c_str());
// Odometry viso2
_ui->spinBox_OdomViso2RansacIters->setObjectName(Parameters::kOdomViso2RansacIters().c_str());
_ui->doubleSpinBox_OdomViso2InlierThreshold->setObjectName(Parameters::kOdomViso2InlierThreshold().c_str());
_ui->checkBox_OdomViso2Reweighting->setObjectName(Parameters::kOdomViso2Reweighting().c_str());
_ui->spinBox_OdomViso2MatchNmsN->setObjectName(Parameters::kOdomViso2MatchNmsN().c_str());
_ui->spinBox_OdomViso2MatchNmsTau->setObjectName(Parameters::kOdomViso2MatchNmsTau().c_str());
_ui->spinBox_OdomViso2MatchBinsize->setObjectName(Parameters::kOdomViso2MatchBinsize().c_str());
_ui->spinBox_OdomViso2MatchRadius->setObjectName(Parameters::kOdomViso2MatchRadius().c_str());
_ui->spinBox_OdomViso2MatchDispTolerance->setObjectName(Parameters::kOdomViso2MatchDispTolerance().c_str());
_ui->spinBox_OdomViso2MatchOutlierDispTolerance->setObjectName(Parameters::kOdomViso2MatchOutlierDispTolerance().c_str());
_ui->spinBox_OdomViso2MatchOutlierFlowTolerance->setObjectName(Parameters::kOdomViso2MatchOutlierFlowTolerance().c_str());
_ui->checkBox_OdomViso2MatchMultiStage->setObjectName(Parameters::kOdomViso2MatchMultiStage().c_str());
_ui->checkBox_OdomViso2MatchHalfResolution->setObjectName(Parameters::kOdomViso2MatchHalfResolution().c_str());
_ui->spinBox_OdomViso2MatchRefinement->setObjectName(Parameters::kOdomViso2MatchRefinement().c_str());
_ui->spinBox_OdomViso2BucketMaxFeatures->setObjectName(Parameters::kOdomViso2BucketMaxFeatures().c_str());
_ui->doubleSpinBox_OdomViso2BucketWidth->setObjectName(Parameters::kOdomViso2BucketWidth().c_str());
_ui->doubleSpinBox_OdomViso2BucketHeight->setObjectName(Parameters::kOdomViso2BucketHeight().c_str());
//Stereo //Stereo
_ui->stereo_winWidth->setObjectName(Parameters::kStereoWinWidth().c_str()); _ui->stereo_winWidth->setObjectName(Parameters::kStereoWinWidth().c_str());
_ui->stereo_winHeight->setObjectName(Parameters::kStereoWinHeight().c_str()); _ui->stereo_winHeight->setObjectName(Parameters::kStereoWinHeight().c_str());
@@ -3833,9 +3882,11 @@ void PreferencesDialog::setupKpRoiPanel()
void PreferencesDialog::updateOdometryVisibility() void PreferencesDialog::updateOdometryVisibility()
{ {
_ui->stackedWidget_odometryType->setVisible( _ui->groupBox_odomF2M->setVisible(_ui->odom_strategy->currentIndex()==0);
_ui->odom_strategy->currentIndex() == 2 || // fovis _ui->groupBox_odomF2F->setVisible(_ui->odom_strategy->currentIndex()==1);
_ui->odom_strategy->currentIndex() == 3); // viso2 _ui->groupBox_odomFovis->setVisible(_ui->odom_strategy->currentIndex()==2);
_ui->groupBox_odomViso2->setVisible(_ui->odom_strategy->currentIndex()==3);
_ui->groupBox_odomMono->setVisible(_ui->odom_strategy->currentIndex()==4);
} }
void PreferencesDialog::updateKpROI() void PreferencesDialog::updateKpROI()

View File

@@ -82,6 +82,13 @@ p, li { white-space: pre-wrap; }
</item> </item>
<item> <item>
<layout class="QGridLayout" name="gridLayout" columnstretch="0,1"> <layout class="QGridLayout" name="gridLayout" columnstretch="0,1">
<item row="23" column="0">
<widget class="QLabel" name="label_25">
<property name="text">
<string>With FOVIS :</string>
</property>
</widget>
</item>
<item row="3" column="0"> <item row="3" column="0">
<widget class="QLabel" name="label_4"> <widget class="QLabel" name="label_4">
<property name="text"> <property name="text">
@@ -265,6 +272,16 @@ p, li { white-space: pre-wrap; }
</property> </property>
</widget> </widget>
</item> </item>
<item row="1" column="1">
<widget class="QLabel" name="label_8">
<property name="text">
<string>Mathieu Labbé, matlabbe@gmail.com</string>
</property>
<property name="alignment">
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item row="14" column="0"> <item row="14" column="0">
<widget class="QLabel" name="label_22"> <widget class="QLabel" name="label_22">
<property name="text"> <property name="text">
@@ -282,16 +299,6 @@ p, li { white-space: pre-wrap; }
</property> </property>
</widget> </widget>
</item> </item>
<item row="1" column="1">
<widget class="QLabel" name="label_8">
<property name="text">
<string>Mathieu Labbé, matlabbe@gmail.com</string>
</property>
<property name="alignment">
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item row="7" column="0"> <item row="7" column="0">
<widget class="QLabel" name="label_6"> <widget class="QLabel" name="label_6">
<property name="text"> <property name="text">
@@ -316,6 +323,13 @@ p, li { white-space: pre-wrap; }
</property> </property>
</widget> </widget>
</item> </item>
<item row="1" column="0">
<widget class="QLabel" name="label_2">
<property name="text">
<string>Author :</string>
</property>
</widget>
</item>
<item row="21" column="0"> <item row="21" column="0">
<widget class="QLabel" name="label_20"> <widget class="QLabel" name="label_20">
<property name="text"> <property name="text">
@@ -333,10 +347,10 @@ p, li { white-space: pre-wrap; }
</property> </property>
</widget> </widget>
</item> </item>
<item row="1" column="0"> <item row="16" column="0">
<widget class="QLabel" name="label_2"> <widget class="QLabel" name="label_17">
<property name="text"> <property name="text">
<string>Author :</string> <string>With stereo FlyCapture2 :</string>
</property> </property>
</widget> </widget>
</item> </item>
@@ -347,10 +361,10 @@ p, li { white-space: pre-wrap; }
</property> </property>
</widget> </widget>
</item> </item>
<item row="16" column="0"> <item row="19" column="0">
<widget class="QLabel" name="label_17"> <widget class="QLabel" name="label_19">
<property name="text"> <property name="text">
<string>With stereo FlyCapture2 :</string> <string>With GTSAM :</string>
</property> </property>
</widget> </widget>
</item> </item>
@@ -371,6 +385,13 @@ p, li { white-space: pre-wrap; }
</property> </property>
</widget> </widget>
</item> </item>
<item row="22" column="0">
<widget class="QLabel" name="label_24">
<property name="text">
<string>With CPU-TSDF :</string>
</property>
</widget>
</item>
<item row="4" column="1"> <item row="4" column="1">
<widget class="QLabel" name="label_HomePage_3"> <widget class="QLabel" name="label_HomePage_3">
<property name="text"> <property name="text">
@@ -388,20 +409,6 @@ p, li { white-space: pre-wrap; }
</property> </property>
</widget> </widget>
</item> </item>
<item row="19" column="0">
<widget class="QLabel" name="label_19">
<property name="text">
<string>With GTSAM :</string>
</property>
</widget>
</item>
<item row="22" column="0">
<widget class="QLabel" name="label_24">
<property name="text">
<string>With CPU-TSDF :</string>
</property>
</widget>
</item>
<item row="22" column="1"> <item row="22" column="1">
<widget class="QLabel" name="label_cputsdf"> <widget class="QLabel" name="label_cputsdf">
<property name="text"> <property name="text">
@@ -412,6 +419,33 @@ p, li { white-space: pre-wrap; }
</property> </property>
</widget> </widget>
</item> </item>
<item row="24" column="0">
<widget class="QLabel" name="label_26">
<property name="text">
<string>With Viso2 :</string>
</property>
</widget>
</item>
<item row="23" column="1">
<widget class="QLabel" name="label_fovis">
<property name="text">
<string/>
</property>
<property name="alignment">
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
</property>
</widget>
</item>
<item row="24" column="1">
<widget class="QLabel" name="label_viso2">
<property name="text">
<string/>
</property>
<property name="alignment">
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignVCenter</set>
</property>
</widget>
</item>
</layout> </layout>
</item> </item>
<item> <item>

File diff suppressed because it is too large Load Diff