mirror of
https://github.com/introlab/rtabmap.git
synced 2026-09-02 17:40:23 +08:00
ExportDialog: added ground normals up option, added camera projection mask and decimation options. Export CLI: added --ground_normals_up and --cam_projection_mask options, changed --bin option by --ascii option (now binary by default). DBViewer: warn when scan from depth option is enabled but there is no depth.
This commit is contained in:
@@ -313,6 +313,7 @@ std::vector<std::pair< std::pair<int, int>, pcl::PointXY> > RTABMAP_EXP projectC
|
|||||||
float maxDistance = 0.0f,
|
float maxDistance = 0.0f,
|
||||||
float maxAngle = 0.0f,
|
float maxAngle = 0.0f,
|
||||||
const std::vector<float> & roiRatios = std::vector<float>(),
|
const std::vector<float> & roiRatios = std::vector<float>(),
|
||||||
|
const cv::Mat & projMask = cv::Mat(),
|
||||||
bool distanceToCamPolicy = false,
|
bool distanceToCamPolicy = false,
|
||||||
const ProgressState * state = 0);
|
const ProgressState * state = 0);
|
||||||
/**
|
/**
|
||||||
@@ -326,6 +327,7 @@ std::vector<std::pair< std::pair<int, int>, pcl::PointXY> > RTABMAP_EXP projectC
|
|||||||
float maxDistance = 0.0f,
|
float maxDistance = 0.0f,
|
||||||
float maxAngle = 0.0f,
|
float maxAngle = 0.0f,
|
||||||
const std::vector<float> & roiRatios = std::vector<float>(),
|
const std::vector<float> & roiRatios = std::vector<float>(),
|
||||||
|
const cv::Mat & projMask = cv::Mat(),
|
||||||
bool distanceToCamPolicy = false,
|
bool distanceToCamPolicy = false,
|
||||||
const ProgressState * state = 0);
|
const ProgressState * state = 0);
|
||||||
|
|
||||||
|
|||||||
@@ -481,23 +481,27 @@ void RTABMAP_EXP adjustNormalsToViewPoints(
|
|||||||
const std::map<int, Transform> & poses,
|
const std::map<int, Transform> & poses,
|
||||||
const pcl::PointCloud<pcl::PointXYZ>::Ptr & rawCloud,
|
const pcl::PointCloud<pcl::PointXYZ>::Ptr & rawCloud,
|
||||||
const std::vector<int> & rawCameraIndices,
|
const std::vector<int> & rawCameraIndices,
|
||||||
pcl::PointCloud<pcl::PointNormal>::Ptr & cloud);
|
pcl::PointCloud<pcl::PointNormal>::Ptr & cloud,
|
||||||
|
float groundNormalsUp = 0.0f);
|
||||||
void RTABMAP_EXP adjustNormalsToViewPoints(
|
void RTABMAP_EXP adjustNormalsToViewPoints(
|
||||||
const std::map<int, Transform> & poses,
|
const std::map<int, Transform> & poses,
|
||||||
const pcl::PointCloud<pcl::PointXYZ>::Ptr & rawCloud,
|
const pcl::PointCloud<pcl::PointXYZ>::Ptr & rawCloud,
|
||||||
const std::vector<int> & rawCameraIndices,
|
const std::vector<int> & rawCameraIndices,
|
||||||
pcl::PointCloud<pcl::PointXYZRGBNormal>::Ptr & cloud);
|
pcl::PointCloud<pcl::PointXYZRGBNormal>::Ptr & cloud,
|
||||||
|
float groundNormalsUp = 0.0f);
|
||||||
void RTABMAP_EXP adjustNormalsToViewPoints(
|
void RTABMAP_EXP adjustNormalsToViewPoints(
|
||||||
const std::map<int, Transform> & poses,
|
const std::map<int, Transform> & poses,
|
||||||
const pcl::PointCloud<pcl::PointXYZ>::Ptr & rawCloud,
|
const pcl::PointCloud<pcl::PointXYZ>::Ptr & rawCloud,
|
||||||
const std::vector<int> & rawCameraIndices,
|
const std::vector<int> & rawCameraIndices,
|
||||||
pcl::PointCloud<pcl::PointXYZINormal>::Ptr & cloud);
|
pcl::PointCloud<pcl::PointXYZINormal>::Ptr & cloud,
|
||||||
|
float groundNormalsUp = 0.0f);
|
||||||
|
|
||||||
void RTABMAP_EXP adjustNormalsToViewPoints(
|
void RTABMAP_EXP adjustNormalsToViewPoints(
|
||||||
const std::map<int, Transform> & viewpoints,
|
const std::map<int, Transform> & viewpoints,
|
||||||
const LaserScan & rawScan,
|
const LaserScan & rawScan,
|
||||||
const std::vector<int> & viewpointIds,
|
const std::vector<int> & viewpointIds,
|
||||||
LaserScan & scan);
|
LaserScan & scan,
|
||||||
|
float groundNormalsUp = 0.0f);
|
||||||
|
|
||||||
pcl::PolygonMesh::Ptr RTABMAP_EXP meshDecimation(const pcl::PolygonMesh::Ptr & mesh, float factor);
|
pcl::PolygonMesh::Ptr RTABMAP_EXP meshDecimation(const pcl::PolygonMesh::Ptr & mesh, float factor);
|
||||||
|
|
||||||
|
|||||||
@@ -2848,6 +2848,7 @@ std::vector<std::pair< std::pair<int, int>, pcl::PointXY> > projectCloudToCamera
|
|||||||
float maxDistance,
|
float maxDistance,
|
||||||
float maxAngle,
|
float maxAngle,
|
||||||
const std::vector<float> & roiRatios,
|
const std::vector<float> & roiRatios,
|
||||||
|
const cv::Mat & projMask,
|
||||||
bool distanceToCamPolicy,
|
bool distanceToCamPolicy,
|
||||||
const ProgressState * state)
|
const ProgressState * state)
|
||||||
{
|
{
|
||||||
@@ -2857,6 +2858,8 @@ std::vector<std::pair< std::pair<int, int>, pcl::PointXY> > projectCloudToCamera
|
|||||||
UINFO("maxDistance=%f", maxDistance);
|
UINFO("maxDistance=%f", maxDistance);
|
||||||
UINFO("maxAngle=%f", maxAngle);
|
UINFO("maxAngle=%f", maxAngle);
|
||||||
UINFO("distanceToCamPolicy=%s", distanceToCamPolicy?"true":"false");
|
UINFO("distanceToCamPolicy=%s", distanceToCamPolicy?"true":"false");
|
||||||
|
UINFO("roiRatios=%s", roiRatios.size() == 4?uFormat("%f %f %f %f", roiRatios[0], roiRatios[1], roiRatios[2], roiRatios[3]):"");
|
||||||
|
UINFO("projMask=%dx%d", projMask.cols, projMask.rows);
|
||||||
std::vector<std::pair< std::pair<int, int>, pcl::PointXY> > pointToPixel;
|
std::vector<std::pair< std::pair<int, int>, pcl::PointXY> > pointToPixel;
|
||||||
|
|
||||||
if (cloud.empty() || cameraPoses.empty() || cameraModels.empty())
|
if (cloud.empty() || cameraPoses.empty() || cameraModels.empty())
|
||||||
@@ -2873,18 +2876,46 @@ std::vector<std::pair< std::pair<int, int>, pcl::PointXY> > projectCloudToCamera
|
|||||||
|
|
||||||
std::vector<ProjectionInfo> invertedIndex(cloud.size()); // For each point: list of cameras
|
std::vector<ProjectionInfo> invertedIndex(cloud.size()); // For each point: list of cameras
|
||||||
int cameraProcessed = 0;
|
int cameraProcessed = 0;
|
||||||
|
bool wrongMaskFormatWarned = false;
|
||||||
for(std::map<int, Transform>::const_iterator pter = cameraPoses.lower_bound(0); pter!=cameraPoses.end(); ++pter)
|
for(std::map<int, Transform>::const_iterator pter = cameraPoses.lower_bound(0); pter!=cameraPoses.end(); ++pter)
|
||||||
{
|
{
|
||||||
std::map<int, std::vector<CameraModel> >::const_iterator iter=cameraModels.find(pter->first);
|
std::map<int, std::vector<CameraModel> >::const_iterator iter=cameraModels.find(pter->first);
|
||||||
if(iter!=cameraModels.end() && !iter->second.empty())
|
if(iter!=cameraModels.end() && !iter->second.empty())
|
||||||
{
|
{
|
||||||
for(size_t i=0; i<iter->second.size(); ++i)
|
cv::Mat validProjMask;
|
||||||
|
if(!projMask.empty())
|
||||||
{
|
{
|
||||||
Transform cameraTransform = (pter->second * iter->second[i].localTransform());
|
if(projMask.type() != CV_8UC1)
|
||||||
|
{
|
||||||
|
if(!wrongMaskFormatWarned)
|
||||||
|
UERROR("Wrong camera projection mask type %d, should be CV_8UC1", projMask.type());
|
||||||
|
wrongMaskFormatWarned = true;
|
||||||
|
}
|
||||||
|
else if(projMask.cols == iter->second[0].imageWidth() * (int)iter->second.size() &&
|
||||||
|
projMask.rows == iter->second[0].imageHeight())
|
||||||
|
{
|
||||||
|
validProjMask = projMask;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
UWARN("Camera projection mask (%dx%d) is not valid for current "
|
||||||
|
"camera model(s) (count=%ld, image size=%dx%d). It will be "
|
||||||
|
"ignored for node %d",
|
||||||
|
projMask.cols, projMask.rows,
|
||||||
|
iter->second.size(),
|
||||||
|
iter->second[0].imageWidth(),
|
||||||
|
iter->second[0].imageHeight(),
|
||||||
|
pter->first);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for(size_t camIndex=0; camIndex<iter->second.size(); ++camIndex)
|
||||||
|
{
|
||||||
|
Transform cameraTransform = (pter->second * iter->second[camIndex].localTransform());
|
||||||
UASSERT(!cameraTransform.isNull());
|
UASSERT(!cameraTransform.isNull());
|
||||||
cv::Mat cameraMatrixK = iter->second[i].K();
|
cv::Mat cameraMatrixK = iter->second[camIndex].K();
|
||||||
UASSERT(cameraMatrixK.type() == CV_64FC1 && cameraMatrixK.cols == 3 && cameraMatrixK.cols == 3);
|
UASSERT(cameraMatrixK.type() == CV_64FC1 && cameraMatrixK.cols == 3 && cameraMatrixK.cols == 3);
|
||||||
const cv::Size & imageSize = iter->second[i].imageSize();
|
const cv::Size & imageSize = iter->second[camIndex].imageSize();
|
||||||
|
|
||||||
float fx = cameraMatrixK.at<double>(0,0);
|
float fx = cameraMatrixK.at<double>(0,0);
|
||||||
float fy = cameraMatrixK.at<double>(1,1);
|
float fy = cameraMatrixK.at<double>(1,1);
|
||||||
@@ -2921,7 +2952,8 @@ std::vector<std::pair< std::pair<int, int>, pcl::PointXY> > projectCloudToCamera
|
|||||||
int dx_high = dx + 0.5f;
|
int dx_high = dx + 0.5f;
|
||||||
int dy_high = dy + 0.5f;
|
int dy_high = dy + 0.5f;
|
||||||
int zMM = z * 1000;
|
int zMM = z * 1000;
|
||||||
if(uIsInBounds(dx_low, roi.x, roi.x+roi.width) && uIsInBounds(dy_low, roi.y, roi.y+roi.height))
|
if(uIsInBounds(dx_low, roi.x, roi.x+roi.width) && uIsInBounds(dy_low, roi.y, roi.y+roi.height) &&
|
||||||
|
(validProjMask.empty() || validProjMask.at<unsigned char>(dy_low, imageSize.width*camIndex+dx_low) > 0))
|
||||||
{
|
{
|
||||||
set = true;
|
set = true;
|
||||||
cv::Vec2i &zReg = registered.at<cv::Vec2i>(dy_low, dx_low);
|
cv::Vec2i &zReg = registered.at<cv::Vec2i>(dy_low, dx_low);
|
||||||
@@ -2932,7 +2964,8 @@ std::vector<std::pair< std::pair<int, int>, pcl::PointXY> > projectCloudToCamera
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if((dx_low != dx_high || dy_low != dy_high) &&
|
if((dx_low != dx_high || dy_low != dy_high) &&
|
||||||
uIsInBounds(dx_high, roi.x, roi.x+roi.width) && uIsInBounds(dy_high, roi.y, roi.y+roi.height))
|
uIsInBounds(dx_high, roi.x, roi.x+roi.width) && uIsInBounds(dy_high, roi.y, roi.y+roi.height) &&
|
||||||
|
(validProjMask.empty() || validProjMask.at<unsigned char>(dy_high, imageSize.width*camIndex+dx_high) > 0))
|
||||||
{
|
{
|
||||||
set = true;
|
set = true;
|
||||||
cv::Vec2i &zReg = registered.at<cv::Vec2i>(dy_high, dx_high);
|
cv::Vec2i &zReg = registered.at<cv::Vec2i>(dy_high, dx_high);
|
||||||
@@ -2951,11 +2984,11 @@ std::vector<std::pair< std::pair<int, int>, pcl::PointXY> > projectCloudToCamera
|
|||||||
if(count == 0)
|
if(count == 0)
|
||||||
{
|
{
|
||||||
registered = cv::Mat();
|
registered = cv::Mat();
|
||||||
UINFO("No points projected in camera %d/%d", pter->first, i);
|
UINFO("No points projected in camera %d/%d", pter->first, camIndex);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
UDEBUG("%d points projected in camera %d/%d", count, pter->first, i);
|
UDEBUG("%d points projected in camera %d/%d", count, pter->first, camIndex);
|
||||||
}
|
}
|
||||||
for(int u=0; u<registered.cols; ++u)
|
for(int u=0; u<registered.cols; ++u)
|
||||||
{
|
{
|
||||||
@@ -2966,7 +2999,7 @@ std::vector<std::pair< std::pair<int, int>, pcl::PointXY> > projectCloudToCamera
|
|||||||
{
|
{
|
||||||
ProjectionInfo info;
|
ProjectionInfo info;
|
||||||
info.nodeID = pter->first;
|
info.nodeID = pter->first;
|
||||||
info.cameraIndex = i;
|
info.cameraIndex = camIndex;
|
||||||
info.uv.x = float(u)/float(imageSize.width);
|
info.uv.x = float(u)/float(imageSize.width);
|
||||||
info.uv.y = float(v)/float(imageSize.height);
|
info.uv.y = float(v)/float(imageSize.height);
|
||||||
const Transform & cam = cameraPoses.at(info.nodeID);
|
const Transform & cam = cameraPoses.at(info.nodeID);
|
||||||
@@ -3070,6 +3103,7 @@ std::vector<std::pair< std::pair<int, int>, pcl::PointXY> > projectCloudToCamera
|
|||||||
float maxDistance,
|
float maxDistance,
|
||||||
float maxAngle,
|
float maxAngle,
|
||||||
const std::vector<float> & roiRatios,
|
const std::vector<float> & roiRatios,
|
||||||
|
const cv::Mat & projMask,
|
||||||
bool distanceToCamPolicy,
|
bool distanceToCamPolicy,
|
||||||
const ProgressState * state)
|
const ProgressState * state)
|
||||||
{
|
{
|
||||||
@@ -3079,6 +3113,7 @@ std::vector<std::pair< std::pair<int, int>, pcl::PointXY> > projectCloudToCamera
|
|||||||
maxDistance,
|
maxDistance,
|
||||||
maxAngle,
|
maxAngle,
|
||||||
roiRatios,
|
roiRatios,
|
||||||
|
projMask,
|
||||||
distanceToCamPolicy,
|
distanceToCamPolicy,
|
||||||
state);
|
state);
|
||||||
}
|
}
|
||||||
@@ -3090,6 +3125,7 @@ std::vector<std::pair< std::pair<int, int>, pcl::PointXY> > projectCloudToCamera
|
|||||||
float maxDistance,
|
float maxDistance,
|
||||||
float maxAngle,
|
float maxAngle,
|
||||||
const std::vector<float> & roiRatios,
|
const std::vector<float> & roiRatios,
|
||||||
|
const cv::Mat & projMask,
|
||||||
bool distanceToCamPolicy,
|
bool distanceToCamPolicy,
|
||||||
const ProgressState * state)
|
const ProgressState * state)
|
||||||
{
|
{
|
||||||
@@ -3099,6 +3135,7 @@ std::vector<std::pair< std::pair<int, int>, pcl::PointXY> > projectCloudToCamera
|
|||||||
maxDistance,
|
maxDistance,
|
||||||
maxAngle,
|
maxAngle,
|
||||||
roiRatios,
|
roiRatios,
|
||||||
|
projMask,
|
||||||
distanceToCamPolicy,
|
distanceToCamPolicy,
|
||||||
state);
|
state);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3566,7 +3566,8 @@ void adjustNormalsToViewPointsImpl(
|
|||||||
const std::map<int, Transform> & poses,
|
const std::map<int, Transform> & poses,
|
||||||
const pcl::PointCloud<pcl::PointXYZ>::Ptr & rawCloud,
|
const pcl::PointCloud<pcl::PointXYZ>::Ptr & rawCloud,
|
||||||
const std::vector<int> & rawCameraIndices,
|
const std::vector<int> & rawCameraIndices,
|
||||||
typename pcl::PointCloud<PointT>::Ptr & cloud)
|
typename pcl::PointCloud<PointT>::Ptr & cloud,
|
||||||
|
float groundNormalsUp)
|
||||||
{
|
{
|
||||||
if(poses.size() && rawCloud->size() && rawCloud->size() == rawCameraIndices.size() && cloud->size())
|
if(poses.size() && rawCloud->size() && rawCloud->size() == rawCameraIndices.size() && cloud->size())
|
||||||
{
|
{
|
||||||
@@ -3592,7 +3593,8 @@ void adjustNormalsToViewPointsImpl(
|
|||||||
Eigen::Vector3f n(normal.x, normal.y, normal.z);
|
Eigen::Vector3f n(normal.x, normal.y, normal.z);
|
||||||
|
|
||||||
float result = v.dot(n);
|
float result = v.dot(n);
|
||||||
if(result < 0)
|
if(result < 0 ||
|
||||||
|
(groundNormalsUp>0.0f && normal.z < -groundNormalsUp && cloud->points[i].z < viewpoint.z)) // some far velodyne rays on road can have normals toward ground)
|
||||||
{
|
{
|
||||||
//reverse normal
|
//reverse normal
|
||||||
cloud->points[i].normal_x *= -1.0f;
|
cloud->points[i].normal_x *= -1.0f;
|
||||||
@@ -3613,34 +3615,38 @@ void adjustNormalsToViewPoints(
|
|||||||
const std::map<int, Transform> & poses,
|
const std::map<int, Transform> & poses,
|
||||||
const pcl::PointCloud<pcl::PointXYZ>::Ptr & rawCloud,
|
const pcl::PointCloud<pcl::PointXYZ>::Ptr & rawCloud,
|
||||||
const std::vector<int> & rawCameraIndices,
|
const std::vector<int> & rawCameraIndices,
|
||||||
pcl::PointCloud<pcl::PointNormal>::Ptr & cloud)
|
pcl::PointCloud<pcl::PointNormal>::Ptr & cloud,
|
||||||
|
float groundNormalsUp)
|
||||||
{
|
{
|
||||||
adjustNormalsToViewPointsImpl<pcl::PointNormal>(poses, rawCloud, rawCameraIndices, cloud);
|
adjustNormalsToViewPointsImpl<pcl::PointNormal>(poses, rawCloud, rawCameraIndices, cloud, groundNormalsUp);
|
||||||
}
|
}
|
||||||
|
|
||||||
void adjustNormalsToViewPoints(
|
void adjustNormalsToViewPoints(
|
||||||
const std::map<int, Transform> & poses,
|
const std::map<int, Transform> & poses,
|
||||||
const pcl::PointCloud<pcl::PointXYZ>::Ptr & rawCloud,
|
const pcl::PointCloud<pcl::PointXYZ>::Ptr & rawCloud,
|
||||||
const std::vector<int> & rawCameraIndices,
|
const std::vector<int> & rawCameraIndices,
|
||||||
pcl::PointCloud<pcl::PointXYZRGBNormal>::Ptr & cloud)
|
pcl::PointCloud<pcl::PointXYZRGBNormal>::Ptr & cloud,
|
||||||
|
float groundNormalsUp)
|
||||||
{
|
{
|
||||||
adjustNormalsToViewPointsImpl<pcl::PointXYZRGBNormal>(poses, rawCloud, rawCameraIndices, cloud);
|
adjustNormalsToViewPointsImpl<pcl::PointXYZRGBNormal>(poses, rawCloud, rawCameraIndices, cloud, groundNormalsUp);
|
||||||
}
|
}
|
||||||
|
|
||||||
void adjustNormalsToViewPoints(
|
void adjustNormalsToViewPoints(
|
||||||
const std::map<int, Transform> & poses,
|
const std::map<int, Transform> & poses,
|
||||||
const pcl::PointCloud<pcl::PointXYZ>::Ptr & rawCloud,
|
const pcl::PointCloud<pcl::PointXYZ>::Ptr & rawCloud,
|
||||||
const std::vector<int> & rawCameraIndices,
|
const std::vector<int> & rawCameraIndices,
|
||||||
pcl::PointCloud<pcl::PointXYZINormal>::Ptr & cloud)
|
pcl::PointCloud<pcl::PointXYZINormal>::Ptr & cloud,
|
||||||
|
float groundNormalsUp)
|
||||||
{
|
{
|
||||||
adjustNormalsToViewPointsImpl<pcl::PointXYZINormal>(poses, rawCloud, rawCameraIndices, cloud);
|
adjustNormalsToViewPointsImpl<pcl::PointXYZINormal>(poses, rawCloud, rawCameraIndices, cloud, groundNormalsUp);
|
||||||
}
|
}
|
||||||
|
|
||||||
void adjustNormalsToViewPoints(
|
void adjustNormalsToViewPoints(
|
||||||
const std::map<int, Transform> & viewpoints,
|
const std::map<int, Transform> & viewpoints,
|
||||||
const LaserScan & rawScan,
|
const LaserScan & rawScan,
|
||||||
const std::vector<int> & viewpointIds,
|
const std::vector<int> & viewpointIds,
|
||||||
LaserScan & scan)
|
LaserScan & scan,
|
||||||
|
float groundNormalsUp)
|
||||||
{
|
{
|
||||||
UDEBUG("poses=%d, rawCloud=%d, rawCameraIndices=%d, cloud=%d", (int)viewpoints.size(), (int)rawScan.size(), (int)viewpointIds.size(), (int)scan.size());
|
UDEBUG("poses=%d, rawCloud=%d, rawCameraIndices=%d, cloud=%d", (int)viewpoints.size(), (int)rawScan.size(), (int)viewpointIds.size(), (int)scan.size());
|
||||||
if(viewpoints.size() && rawScan.size() && rawScan.size() == (int)viewpointIds.size() && scan.size() && scan.hasNormals())
|
if(viewpoints.size() && rawScan.size() && rawScan.size() == (int)viewpointIds.size() && scan.size() && scan.hasNormals())
|
||||||
@@ -3669,7 +3675,8 @@ void adjustNormalsToViewPoints(
|
|||||||
Eigen::Vector3f n(normal.x, normal.y, normal.z);
|
Eigen::Vector3f n(normal.x, normal.y, normal.z);
|
||||||
|
|
||||||
float result = v.dot(n);
|
float result = v.dot(n);
|
||||||
if(result < 0)
|
if(result < 0 ||
|
||||||
|
(groundNormalsUp>0.0f && normal.z < -groundNormalsUp && point.z < viewpoint.z)) // some far velodyne rays on road can have normals toward ground))
|
||||||
{
|
{
|
||||||
//reverse normal
|
//reverse normal
|
||||||
scan.field(i, scan.getNormalsOffset()) *= -1.0f;
|
scan.field(i, scan.getNormalsOffset()) *= -1.0f;
|
||||||
|
|||||||
@@ -127,6 +127,7 @@ private Q_SLOTS:
|
|||||||
void saveSettings();
|
void saveSettings();
|
||||||
void updateReconstructionFlavor();
|
void updateReconstructionFlavor();
|
||||||
void selectDistortionModel();
|
void selectDistortionModel();
|
||||||
|
void selectCamProjMask();
|
||||||
void updateMLSGrpVisibility();
|
void updateMLSGrpVisibility();
|
||||||
void cancel();
|
void cancel();
|
||||||
|
|
||||||
|
|||||||
@@ -7767,32 +7767,30 @@ void DatabaseViewer::refineConstraint(int from, int to, bool silent)
|
|||||||
ui_->spinBox_icp_decimation->value()==0?1:ui_->spinBox_icp_decimation->value(),
|
ui_->spinBox_icp_decimation->value()==0?1:ui_->spinBox_icp_decimation->value(),
|
||||||
ui_->doubleSpinBox_icp_maxDepth->value(),
|
ui_->doubleSpinBox_icp_maxDepth->value(),
|
||||||
ui_->doubleSpinBox_icp_minDepth->value(),
|
ui_->doubleSpinBox_icp_minDepth->value(),
|
||||||
0,
|
|
||||||
ui_->parameters_toolbox->getParameters());
|
|
||||||
int maxLaserScans = cloudFrom->size();
|
|
||||||
0,
|
0,
|
||||||
toS->sensorData().setLaserScan(LaserScan(util3d::laserScanFromPointCloud(*util3d::removeNaNFromPointCloud(cloudTo), Transform()), maxLaserScans, 0));
|
ui_->parameters_toolbox->getParameters());
|
||||||
|
|
||||||
|
if(cloudFrom->empty() && cloudTo->empty())
|
||||||
|
{
|
||||||
|
std::string msg = "Option to generate scan from depth is checked (GUI Parameters->Refine), but "
|
||||||
|
"resulting clouds from depth are empty. Transformation estimation will likely "
|
||||||
|
"fails. Uncheck the parameter to use laser scans.";
|
||||||
|
UWARN(msg.c_str());
|
||||||
|
if(!silent)
|
||||||
|
{
|
||||||
|
QMessageBox::warning(this,
|
||||||
|
tr("Refine link"),
|
||||||
|
tr("%1").arg(msg.c_str()));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if(!fromS->sensorData().laserScanCompressed().isEmpty() || !toS->sensorData().laserScanCompressed().isEmpty())
|
else if(!fromS->sensorData().laserScanCompressed().isEmpty() || !toS->sensorData().laserScanCompressed().isEmpty())
|
||||||
{
|
{
|
||||||
UWARN("There are laser scans in data, but generate laser scan from "
|
UWARN("There are laser scans in data, but generate laser scan from "
|
||||||
"depth image option is activated (GUI Parameters->Refine). "
|
"depth image option is activated (GUI Parameters->Refine). "
|
||||||
"Ignoring saved laser scans...");
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
QString msg = tr("Generating laser scan from depth image is checked "
|
|
||||||
"(GUI Parameters->Refine), but selected nodes don't contain "
|
|
||||||
"depth data. Empty laser scans are generated, so transform "
|
|
||||||
"estimation will likely fail. Uncheck to use laser scans instead "
|
|
||||||
"(if there are some).");
|
|
||||||
"Ignoring saved laser scans...");
|
"Ignoring saved laser scans...");
|
||||||
{
|
}
|
||||||
|
|
||||||
QMessageBox::warning(this,
|
int maxLaserScans = cloudFrom->size();
|
||||||
tr("Refine a link"),
|
|
||||||
msg);
|
|
||||||
}
|
|
||||||
fromS->sensorData().setLaserScan(LaserScan(util3d::laserScanFromPointCloud(*util3d::removeNaNFromPointCloud(cloudFrom), Transform()), maxLaserScans, 0));
|
fromS->sensorData().setLaserScan(LaserScan(util3d::laserScanFromPointCloud(*util3d::removeNaNFromPointCloud(cloudFrom), Transform()), maxLaserScans, 0));
|
||||||
toS->sensorData().setLaserScan(LaserScan(util3d::laserScanFromPointCloud(*util3d::removeNaNFromPointCloud(cloudTo), Transform()), maxLaserScans, 0));
|
toS->sensorData().setLaserScan(LaserScan(util3d::laserScanFromPointCloud(*util3d::removeNaNFromPointCloud(cloudTo), Transform()), maxLaserScans, 0));
|
||||||
}
|
}
|
||||||
@@ -8046,25 +8044,46 @@ bool DatabaseViewer::addConstraint(int from, int to, bool silent)
|
|||||||
ui_->spinBox_icp_decimation->value()==0?1:ui_->spinBox_icp_decimation->value(),
|
ui_->spinBox_icp_decimation->value()==0?1:ui_->spinBox_icp_decimation->value(),
|
||||||
ui_->doubleSpinBox_icp_maxDepth->value(),
|
ui_->doubleSpinBox_icp_maxDepth->value(),
|
||||||
ui_->doubleSpinBox_icp_minDepth->value(),
|
ui_->doubleSpinBox_icp_minDepth->value(),
|
||||||
|
0,
|
||||||
|
ui_->parameters_toolbox->getParameters());
|
||||||
|
|
||||||
|
if(cloudFrom->empty() && cloudTo->empty())
|
||||||
|
{
|
||||||
|
std::string msg = "Option to generate scan from depth is checked (GUI Parameters->Refine), but "
|
||||||
|
"resulting clouds from depth are empty. Transformation estimation will likely "
|
||||||
|
"fails. Uncheck the parameter to use laser scans.";
|
||||||
|
UWARN(msg.c_str());
|
||||||
|
if(!silent)
|
||||||
|
{
|
||||||
|
QMessageBox::warning(this,
|
||||||
|
tr("Add link"),
|
||||||
|
tr("%1").arg(msg.c_str()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if(!fromS->sensorData().laserScanCompressed().isEmpty() || !toS->sensorData().laserScanCompressed().isEmpty())
|
||||||
|
{
|
||||||
|
UWARN("There are laser scans in data, but generate laser scan from "
|
||||||
|
"depth image option is activated (GUI Parameters->Refine). Ignoring saved laser scans...");
|
||||||
}
|
}
|
||||||
|
|
||||||
int maxLaserScans = cloudFrom->size();
|
int maxLaserScans = cloudFrom->size();
|
||||||
fromS->sensorData().setLaserScan(LaserScan(util3d::laserScanFromPointCloud(*util3d::removeNaNFromPointCloud(cloudFrom), Transform()), maxLaserScans, 0));
|
|
||||||
toS->sensorData().setLaserScan(LaserScan(util3d::laserScanFromPointCloud(*util3d::removeNaNFromPointCloud(cloudTo), Transform()), maxLaserScans, 0));
|
|
||||||
|
|
||||||
if(!fromS->sensorData().laserScanCompressed().isEmpty() || !toS->sensorData().laserScanCompressed().isEmpty())
|
|
||||||
{
|
|
||||||
UWARN("There are laser scans in data, but generate laser scan from "
|
|
||||||
fromS->sensorData().setLaserScan(LaserScan(util3d::laserScanFromPointCloud(*util3d::removeNaNFromPointCloud(cloudFrom), Transform()), maxLaserScans, 0));
|
fromS->sensorData().setLaserScan(LaserScan(util3d::laserScanFromPointCloud(*util3d::removeNaNFromPointCloud(cloudFrom), Transform()), maxLaserScans, 0));
|
||||||
toS->sensorData().setLaserScan(LaserScan(util3d::laserScanFromPointCloud(*util3d::removeNaNFromPointCloud(cloudTo), Transform()), maxLaserScans, 0));
|
toS->sensorData().setLaserScan(LaserScan(util3d::laserScanFromPointCloud(*util3d::removeNaNFromPointCloud(cloudTo), Transform()), maxLaserScans, 0));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if(!reextractVisualFeatures && fromS->getWords().empty() && toS->getWords().empty())
|
else if(!reextractVisualFeatures && fromS->getWords().empty() && toS->getWords().empty())
|
||||||
{
|
{
|
||||||
std::string msg = uFormat("\"%s\" is false and signatures (%d and %d) don't have words, "
|
std::string msg = uFormat("\"%s\" is false and signatures (%d and %d) don't have words, "
|
||||||
"registration will not be possible. Set \"%s\" to true.",
|
"registration will not be possible. Set \"%s\" to true.",
|
||||||
Parameters::kRGBDLoopClosureReextractFeatures().c_str(),
|
Parameters::kRGBDLoopClosureReextractFeatures().c_str(),
|
||||||
fromS->id(),
|
fromS->id(),
|
||||||
|
toS->id(),
|
||||||
|
Parameters::kRGBDLoopClosureReextractFeatures().c_str());
|
||||||
|
UWARN(msg.c_str());
|
||||||
|
if(!silent)
|
||||||
|
{
|
||||||
|
QMessageBox::warning(this,
|
||||||
|
tr("Add link"),
|
||||||
tr("%1").arg(msg.c_str()));
|
tr("%1").arg(msg.c_str()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -106,6 +106,7 @@ ExportCloudsDialog::ExportCloudsDialog(QWidget *parent) :
|
|||||||
connect(_ui->checkBox_binary, SIGNAL(stateChanged(int)), this, SIGNAL(configChanged()));
|
connect(_ui->checkBox_binary, SIGNAL(stateChanged(int)), this, SIGNAL(configChanged()));
|
||||||
connect(_ui->spinBox_normalKSearch, SIGNAL(valueChanged(int)), this, SIGNAL(configChanged()));
|
connect(_ui->spinBox_normalKSearch, SIGNAL(valueChanged(int)), this, SIGNAL(configChanged()));
|
||||||
connect(_ui->doubleSpinBox_normalRadiusSearch, SIGNAL(valueChanged(double)), this, SIGNAL(configChanged()));
|
connect(_ui->doubleSpinBox_normalRadiusSearch, SIGNAL(valueChanged(double)), this, SIGNAL(configChanged()));
|
||||||
|
connect(_ui->doubleSpinBox_groundNormalsUp, SIGNAL(valueChanged(double)), this, SIGNAL(configChanged()));
|
||||||
connect(_ui->comboBox_pipeline, SIGNAL(currentIndexChanged(int)), this, SIGNAL(configChanged()));
|
connect(_ui->comboBox_pipeline, SIGNAL(currentIndexChanged(int)), this, SIGNAL(configChanged()));
|
||||||
connect(_ui->comboBox_pipeline, SIGNAL(currentIndexChanged(int)), this, SLOT(updateReconstructionFlavor()));
|
connect(_ui->comboBox_pipeline, SIGNAL(currentIndexChanged(int)), this, SLOT(updateReconstructionFlavor()));
|
||||||
connect(_ui->comboBox_meshingApproach, SIGNAL(currentIndexChanged(int)), this, SIGNAL(configChanged()));
|
connect(_ui->comboBox_meshingApproach, SIGNAL(currentIndexChanged(int)), this, SIGNAL(configChanged()));
|
||||||
@@ -192,6 +193,9 @@ ExportCloudsDialog::ExportCloudsDialog(QWidget *parent) :
|
|||||||
connect(_ui->checkBox_cameraProjection, SIGNAL(stateChanged(int)), this, SIGNAL(configChanged()));
|
connect(_ui->checkBox_cameraProjection, SIGNAL(stateChanged(int)), this, SIGNAL(configChanged()));
|
||||||
connect(_ui->checkBox_cameraProjection, SIGNAL(stateChanged(int)), this, SLOT(updateReconstructionFlavor()));
|
connect(_ui->checkBox_cameraProjection, SIGNAL(stateChanged(int)), this, SLOT(updateReconstructionFlavor()));
|
||||||
connect(_ui->lineEdit_camProjRoiRatios, SIGNAL(textChanged(const QString &)), this, SIGNAL(configChanged()));
|
connect(_ui->lineEdit_camProjRoiRatios, SIGNAL(textChanged(const QString &)), this, SIGNAL(configChanged()));
|
||||||
|
connect(_ui->toolButton_camProjMaskFilePath, SIGNAL(clicked()), this, SLOT(selectCamProjMask()));
|
||||||
|
connect(_ui->lineEdit_camProjMaskFilePath, SIGNAL(textChanged(const QString &)), this, SIGNAL(configChanged()));
|
||||||
|
connect(_ui->spinBox_camProjDecimation, SIGNAL(valueChanged(int)), this, SIGNAL(configChanged()));
|
||||||
connect(_ui->doubleSpinBox_camProjMaxDistance, SIGNAL(valueChanged(double)), this, SIGNAL(configChanged()));
|
connect(_ui->doubleSpinBox_camProjMaxDistance, SIGNAL(valueChanged(double)), this, SIGNAL(configChanged()));
|
||||||
connect(_ui->doubleSpinBox_camProjMaxAngle, SIGNAL(valueChanged(double)), this, SIGNAL(configChanged()));
|
connect(_ui->doubleSpinBox_camProjMaxAngle, SIGNAL(valueChanged(double)), this, SIGNAL(configChanged()));
|
||||||
connect(_ui->checkBox_camProjDistanceToCamPolicy, SIGNAL(stateChanged(int)), this, SIGNAL(configChanged()));
|
connect(_ui->checkBox_camProjDistanceToCamPolicy, SIGNAL(stateChanged(int)), this, SIGNAL(configChanged()));
|
||||||
@@ -348,6 +352,7 @@ void ExportCloudsDialog::saveSettings(QSettings & settings, const QString & grou
|
|||||||
settings.setValue("binary", _ui->checkBox_binary->isChecked());
|
settings.setValue("binary", _ui->checkBox_binary->isChecked());
|
||||||
settings.setValue("normals_k", _ui->spinBox_normalKSearch->value());
|
settings.setValue("normals_k", _ui->spinBox_normalKSearch->value());
|
||||||
settings.setValue("normals_radius", _ui->doubleSpinBox_normalRadiusSearch->value());
|
settings.setValue("normals_radius", _ui->doubleSpinBox_normalRadiusSearch->value());
|
||||||
|
settings.setValue("normals_ground_normals_up", _ui->doubleSpinBox_groundNormalsUp->value());
|
||||||
settings.setValue("intensity_colormap", _ui->comboBox_intensityColormap->currentIndex());
|
settings.setValue("intensity_colormap", _ui->comboBox_intensityColormap->currentIndex());
|
||||||
|
|
||||||
settings.setValue("nodes_filtering", _ui->checkBox_nodes_filtering->isChecked());
|
settings.setValue("nodes_filtering", _ui->checkBox_nodes_filtering->isChecked());
|
||||||
@@ -413,6 +418,8 @@ void ExportCloudsDialog::saveSettings(QSettings & settings, const QString & grou
|
|||||||
|
|
||||||
settings.setValue("cam_proj", _ui->checkBox_cameraProjection->isChecked());
|
settings.setValue("cam_proj", _ui->checkBox_cameraProjection->isChecked());
|
||||||
settings.setValue("cam_proj_roi_ratios", _ui->lineEdit_camProjRoiRatios->text());
|
settings.setValue("cam_proj_roi_ratios", _ui->lineEdit_camProjRoiRatios->text());
|
||||||
|
settings.setValue("cam_proj_mask", _ui->lineEdit_camProjMaskFilePath->text());
|
||||||
|
settings.setValue("cam_proj_decimation", _ui->spinBox_camProjDecimation->value());
|
||||||
settings.setValue("cam_proj_max_distance", _ui->doubleSpinBox_camProjMaxDistance->value());
|
settings.setValue("cam_proj_max_distance", _ui->doubleSpinBox_camProjMaxDistance->value());
|
||||||
settings.setValue("cam_proj_max_angle", _ui->doubleSpinBox_camProjMaxAngle->value());
|
settings.setValue("cam_proj_max_angle", _ui->doubleSpinBox_camProjMaxAngle->value());
|
||||||
settings.setValue("cam_proj_distance_policy", _ui->checkBox_camProjDistanceToCamPolicy->isChecked());
|
settings.setValue("cam_proj_distance_policy", _ui->checkBox_camProjDistanceToCamPolicy->isChecked());
|
||||||
@@ -518,6 +525,7 @@ void ExportCloudsDialog::loadSettings(QSettings & settings, const QString & grou
|
|||||||
_ui->checkBox_binary->setChecked(settings.value("binary", _ui->checkBox_binary->isChecked()).toBool());
|
_ui->checkBox_binary->setChecked(settings.value("binary", _ui->checkBox_binary->isChecked()).toBool());
|
||||||
_ui->spinBox_normalKSearch->setValue(settings.value("normals_k", _ui->spinBox_normalKSearch->value()).toInt());
|
_ui->spinBox_normalKSearch->setValue(settings.value("normals_k", _ui->spinBox_normalKSearch->value()).toInt());
|
||||||
_ui->doubleSpinBox_normalRadiusSearch->setValue(settings.value("normals_radius", _ui->doubleSpinBox_normalRadiusSearch->value()).toDouble());
|
_ui->doubleSpinBox_normalRadiusSearch->setValue(settings.value("normals_radius", _ui->doubleSpinBox_normalRadiusSearch->value()).toDouble());
|
||||||
|
_ui->doubleSpinBox_groundNormalsUp->setValue(settings.value("normals_ground_normals_up", _ui->doubleSpinBox_groundNormalsUp->value()).toDouble());
|
||||||
_ui->comboBox_intensityColormap->setCurrentIndex(settings.value("intensity_colormap", _ui->comboBox_intensityColormap->currentIndex()).toInt());
|
_ui->comboBox_intensityColormap->setCurrentIndex(settings.value("intensity_colormap", _ui->comboBox_intensityColormap->currentIndex()).toInt());
|
||||||
|
|
||||||
_ui->checkBox_nodes_filtering->setChecked(settings.value("nodes_filtering", _ui->checkBox_nodes_filtering->isChecked()).toBool());
|
_ui->checkBox_nodes_filtering->setChecked(settings.value("nodes_filtering", _ui->checkBox_nodes_filtering->isChecked()).toBool());
|
||||||
@@ -586,6 +594,8 @@ void ExportCloudsDialog::loadSettings(QSettings & settings, const QString & grou
|
|||||||
|
|
||||||
_ui->checkBox_cameraProjection->setChecked(settings.value("cam_proj", _ui->checkBox_cameraProjection->isChecked()).toBool());
|
_ui->checkBox_cameraProjection->setChecked(settings.value("cam_proj", _ui->checkBox_cameraProjection->isChecked()).toBool());
|
||||||
_ui->lineEdit_camProjRoiRatios->setText(settings.value("cam_proj_roi_ratios", _ui->lineEdit_camProjRoiRatios->text()).toString());
|
_ui->lineEdit_camProjRoiRatios->setText(settings.value("cam_proj_roi_ratios", _ui->lineEdit_camProjRoiRatios->text()).toString());
|
||||||
|
_ui->lineEdit_camProjMaskFilePath->setText(settings.value("cam_proj_mask", _ui->lineEdit_camProjMaskFilePath->text()).toString());
|
||||||
|
_ui->spinBox_camProjDecimation->setValue(settings.value("cam_proj_decimation", _ui->spinBox_camProjDecimation->value()).toInt());
|
||||||
_ui->doubleSpinBox_camProjMaxDistance->setValue(settings.value("cam_proj_max_distance", _ui->doubleSpinBox_camProjMaxDistance->value()).toDouble());
|
_ui->doubleSpinBox_camProjMaxDistance->setValue(settings.value("cam_proj_max_distance", _ui->doubleSpinBox_camProjMaxDistance->value()).toDouble());
|
||||||
_ui->doubleSpinBox_camProjMaxAngle->setValue(settings.value("cam_proj_max_angle", _ui->doubleSpinBox_camProjMaxAngle->value()).toDouble());
|
_ui->doubleSpinBox_camProjMaxAngle->setValue(settings.value("cam_proj_max_angle", _ui->doubleSpinBox_camProjMaxAngle->value()).toDouble());
|
||||||
_ui->checkBox_camProjDistanceToCamPolicy->setChecked(settings.value("cam_proj_distance_policy", _ui->checkBox_camProjDistanceToCamPolicy->isChecked()).toBool());
|
_ui->checkBox_camProjDistanceToCamPolicy->setChecked(settings.value("cam_proj_distance_policy", _ui->checkBox_camProjDistanceToCamPolicy->isChecked()).toBool());
|
||||||
@@ -691,6 +701,7 @@ void ExportCloudsDialog::restoreDefaults()
|
|||||||
_ui->checkBox_binary->setChecked(true);
|
_ui->checkBox_binary->setChecked(true);
|
||||||
_ui->spinBox_normalKSearch->setValue(20);
|
_ui->spinBox_normalKSearch->setValue(20);
|
||||||
_ui->doubleSpinBox_normalRadiusSearch->setValue(0.0);
|
_ui->doubleSpinBox_normalRadiusSearch->setValue(0.0);
|
||||||
|
_ui->doubleSpinBox_groundNormalsUp->setValue(0.0);
|
||||||
_ui->comboBox_intensityColormap->setCurrentIndex(0);
|
_ui->comboBox_intensityColormap->setCurrentIndex(0);
|
||||||
|
|
||||||
_ui->checkBox_nodes_filtering->setChecked(false);
|
_ui->checkBox_nodes_filtering->setChecked(false);
|
||||||
@@ -756,6 +767,8 @@ void ExportCloudsDialog::restoreDefaults()
|
|||||||
|
|
||||||
_ui->checkBox_cameraProjection->setChecked(false);
|
_ui->checkBox_cameraProjection->setChecked(false);
|
||||||
_ui->lineEdit_camProjRoiRatios->setText("0.0 0.0 0.0 0.0");
|
_ui->lineEdit_camProjRoiRatios->setText("0.0 0.0 0.0 0.0");
|
||||||
|
_ui->lineEdit_camProjMaskFilePath->setText("");
|
||||||
|
_ui->spinBox_camProjDecimation->setValue(1);
|
||||||
_ui->doubleSpinBox_camProjMaxDistance->setValue(0);
|
_ui->doubleSpinBox_camProjMaxDistance->setValue(0);
|
||||||
_ui->doubleSpinBox_camProjMaxAngle->setValue(0);
|
_ui->doubleSpinBox_camProjMaxAngle->setValue(0);
|
||||||
_ui->checkBox_camProjDistanceToCamPolicy->setChecked(true);
|
_ui->checkBox_camProjDistanceToCamPolicy->setChecked(true);
|
||||||
@@ -1018,6 +1031,20 @@ void ExportCloudsDialog::selectDistortionModel()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ExportCloudsDialog::selectCamProjMask()
|
||||||
|
{
|
||||||
|
QString dir = _ui->lineEdit_camProjMaskFilePath->text();
|
||||||
|
if(dir.isEmpty())
|
||||||
|
{
|
||||||
|
dir = _workingDirectory;
|
||||||
|
}
|
||||||
|
QString path = QFileDialog::getOpenFileName(this, tr("Select file"), dir, tr("Mask (grayscale) (*.png *.pgm *bmp)"));
|
||||||
|
if(path.size())
|
||||||
|
{
|
||||||
|
_ui->lineEdit_camProjMaskFilePath->setText(path);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void ExportCloudsDialog::setSaveButton()
|
void ExportCloudsDialog::setSaveButton()
|
||||||
{
|
{
|
||||||
_ui->buttonBox->button(QDialogButtonBox::Ok)->setVisible(false);
|
_ui->buttonBox->button(QDialogButtonBox::Ok)->setVisible(false);
|
||||||
@@ -1913,7 +1940,8 @@ bool ExportCloudsDialog::getExportedClouds(
|
|||||||
normalViewpoints,
|
normalViewpoints,
|
||||||
rawAssembledCloud,
|
rawAssembledCloud,
|
||||||
rawCameraIndices,
|
rawCameraIndices,
|
||||||
assembledCloud);
|
assembledCloud,
|
||||||
|
_ui->doubleSpinBox_groundNormalsUp->value());
|
||||||
}
|
}
|
||||||
|
|
||||||
if(_ui->spinBox_randomSamples_assembled->value()>0 &&
|
if(_ui->spinBox_randomSamples_assembled->value()>0 &&
|
||||||
@@ -2724,17 +2752,56 @@ bool ExportCloudsDialog::getExportedClouds(
|
|||||||
_progressDialog->setAutoClose(false);
|
_progressDialog->setAutoClose(false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::map<int, std::vector<rtabmap::CameraModel> > cameraModelsProj;
|
||||||
|
if(_ui->spinBox_camProjDecimation->value()>1)
|
||||||
|
{
|
||||||
|
for(std::map<int, std::vector<rtabmap::CameraModel> >::iterator iter=cameraModels.begin();
|
||||||
|
iter!=cameraModels.end();
|
||||||
|
++iter)
|
||||||
|
{
|
||||||
|
std::vector<rtabmap::CameraModel> models;
|
||||||
|
for(size_t i=0; i<iter->second.size(); ++i)
|
||||||
|
{
|
||||||
|
models.push_back(iter->second[i].scaled(1.0/double(_ui->spinBox_camProjDecimation->value())));
|
||||||
|
}
|
||||||
|
cameraModelsProj.insert(std::make_pair(iter->first, models));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
cameraModelsProj = cameraModels;
|
||||||
|
}
|
||||||
|
|
||||||
|
cv::Mat projMask;
|
||||||
|
if(!_ui->lineEdit_camProjMaskFilePath->text().isEmpty())
|
||||||
|
{
|
||||||
|
projMask = cv::imread(_ui->lineEdit_camProjMaskFilePath->text().toStdString(), cv::IMREAD_GRAYSCALE);
|
||||||
|
if(_ui->spinBox_camProjDecimation->value()>1)
|
||||||
|
{
|
||||||
|
cv::Mat out = projMask;
|
||||||
|
cv::resize(projMask, out, cv::Size(), 1.0f/float(_ui->spinBox_camProjDecimation->value()), 1.0f/float(_ui->spinBox_camProjDecimation->value()), cv::INTER_NEAREST);
|
||||||
|
projMask = out;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
std::vector<std::pair< std::pair<int, int>, pcl::PointXY> > pointToPixel;
|
std::vector<std::pair< std::pair<int, int>, pcl::PointXY> > pointToPixel;
|
||||||
pointToPixel = util3d::projectCloudToCameras(
|
pointToPixel = util3d::projectCloudToCameras(
|
||||||
*assembledCloud,
|
*assembledCloud,
|
||||||
cameraPoses,
|
cameraPoses,
|
||||||
cameraModels,
|
cameraModelsProj,
|
||||||
_ui->doubleSpinBox_camProjMaxDistance->value(),
|
_ui->doubleSpinBox_camProjMaxDistance->value(),
|
||||||
_ui->doubleSpinBox_camProjMaxAngle->value()*M_PI/180.0,
|
_ui->doubleSpinBox_camProjMaxAngle->value()*M_PI/180.0,
|
||||||
roiRatios,
|
roiRatios,
|
||||||
|
projMask,
|
||||||
_ui->checkBox_camProjDistanceToCamPolicy->isChecked(),
|
_ui->checkBox_camProjDistanceToCamPolicy->isChecked(),
|
||||||
&texturingState);
|
&texturingState);
|
||||||
|
|
||||||
|
if(texturingState.isCanceled())
|
||||||
|
{
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
// color the cloud
|
// color the cloud
|
||||||
UASSERT(pointToPixel.empty() || pointToPixel.size() == assembledCloud->size());
|
UASSERT(pointToPixel.empty() || pointToPixel.size() == assembledCloud->size());
|
||||||
pcl::PointCloud<pcl::PointXYZRGBNormal>::Ptr assembledCloudValidPoints;
|
pcl::PointCloud<pcl::PointXYZRGBNormal>::Ptr assembledCloudValidPoints;
|
||||||
@@ -2752,7 +2819,7 @@ bool ExportCloudsDialog::getExportedClouds(
|
|||||||
if(_ui->checkBox_camProjRecolorPoints->isChecked())
|
if(_ui->checkBox_camProjRecolorPoints->isChecked())
|
||||||
{
|
{
|
||||||
int imagesDone = 1;
|
int imagesDone = 1;
|
||||||
for(std::map<int, rtabmap::Transform>::iterator iter=cameraPoses.begin(); iter!=cameraPoses.end(); ++iter)
|
for(std::map<int, rtabmap::Transform>::iterator iter=cameraPoses.begin(); iter!=cameraPoses.end() && !_canceled; ++iter)
|
||||||
{
|
{
|
||||||
int nodeID = iter->first;
|
int nodeID = iter->first;
|
||||||
|
|
||||||
@@ -2769,15 +2836,19 @@ bool ExportCloudsDialog::getExportedClouds(
|
|||||||
}
|
}
|
||||||
if(!image.empty())
|
if(!image.empty())
|
||||||
{
|
{
|
||||||
UASSERT(cameraModels.find(nodeID) != cameraModels.end());
|
|
||||||
int modelsSize = cameraModels.at(nodeID).size();
|
if(_ui->spinBox_camProjDecimation->value()>1)
|
||||||
|
{
|
||||||
|
image = util2d::decimate(image, _ui->spinBox_camProjDecimation->value());
|
||||||
|
}
|
||||||
|
|
||||||
|
UASSERT(cameraModelsProj.find(nodeID) != cameraModelsProj.end());
|
||||||
|
int modelsSize = cameraModelsProj.at(nodeID).size();
|
||||||
for(size_t i=0; i<pointToPixel.size(); ++i)
|
for(size_t i=0; i<pointToPixel.size(); ++i)
|
||||||
{
|
{
|
||||||
int cameraIndex = pointToPixel[i].first.second;
|
int cameraIndex = pointToPixel[i].first.second;
|
||||||
if(nodeID == pointToPixel[i].first.first && cameraIndex>=0)
|
if(nodeID == pointToPixel[i].first.first && cameraIndex>=0)
|
||||||
{
|
{
|
||||||
pcl::PointXYZRGBNormal & pt = assembledCloud->at(i);
|
|
||||||
|
|
||||||
int subImageWidth = image.cols / modelsSize;
|
int subImageWidth = image.cols / modelsSize;
|
||||||
cv::Mat subImage = image(cv::Range::all(), cv::Range(cameraIndex*subImageWidth, (cameraIndex+1)*subImageWidth));
|
cv::Mat subImage = image(cv::Range::all(), cv::Range(cameraIndex*subImageWidth, (cameraIndex+1)*subImageWidth));
|
||||||
|
|
||||||
@@ -2786,6 +2857,7 @@ bool ExportCloudsDialog::getExportedClouds(
|
|||||||
UASSERT(x>=0 && x<subImage.cols);
|
UASSERT(x>=0 && x<subImage.cols);
|
||||||
UASSERT(y>=0 && y<subImage.rows);
|
UASSERT(y>=0 && y<subImage.rows);
|
||||||
|
|
||||||
|
pcl::PointXYZRGBNormal & pt = assembledCloud->at(i);
|
||||||
if(subImage.type()==CV_8UC3)
|
if(subImage.type()==CV_8UC3)
|
||||||
{
|
{
|
||||||
cv::Vec3b bgr = subImage.at<cv::Vec3b>(y, x);
|
cv::Vec3b bgr = subImage.at<cv::Vec3b>(y, x);
|
||||||
@@ -2804,12 +2876,13 @@ bool ExportCloudsDialog::getExportedClouds(
|
|||||||
QString msg = tr("Processed %1/%2 images").arg(imagesDone++).arg(cameraPoses.size());
|
QString msg = tr("Processed %1/%2 images").arg(imagesDone++).arg(cameraPoses.size());
|
||||||
UINFO(msg.toStdString().c_str());
|
UINFO(msg.toStdString().c_str());
|
||||||
_progressDialog->appendText(msg);
|
_progressDialog->appendText(msg);
|
||||||
|
QApplication::processEvents();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pcl::IndicesPtr validIndices(new std::vector<int>(pointToPixel.size()));
|
pcl::IndicesPtr validIndices(new std::vector<int>(pointToPixel.size()));
|
||||||
size_t oi = 0;
|
size_t oi = 0;
|
||||||
for(size_t i=0; i<pointToPixel.size(); ++i)
|
for(size_t i=0; i<pointToPixel.size() && !_canceled; ++i)
|
||||||
{
|
{
|
||||||
pcl::PointXYZRGBNormal & pt = assembledCloud->at(i);
|
pcl::PointXYZRGBNormal & pt = assembledCloud->at(i);
|
||||||
if(pointToPixel[i].first.first <=0)
|
if(pointToPixel[i].first.first <=0)
|
||||||
@@ -3589,6 +3662,10 @@ std::map<int, std::pair<pcl::PointCloud<pcl::PointXYZRGBNormal>::Ptr, pcl::Indic
|
|||||||
{
|
{
|
||||||
pcl::PointCloud<pcl::Normal>::Ptr normals = util3d::computeNormals(cloudWithoutNormals, indices, _ui->spinBox_normalKSearch->value(), _ui->doubleSpinBox_normalRadiusSearch->value(), viewPoint);
|
pcl::PointCloud<pcl::Normal>::Ptr normals = util3d::computeNormals(cloudWithoutNormals, indices, _ui->spinBox_normalKSearch->value(), _ui->doubleSpinBox_normalRadiusSearch->value(), viewPoint);
|
||||||
pcl::concatenateFields(*cloudWithoutNormals, *normals, *cloud);
|
pcl::concatenateFields(*cloudWithoutNormals, *normals, *cloud);
|
||||||
|
if(_ui->doubleSpinBox_groundNormalsUp->value() > 0.0)
|
||||||
|
{
|
||||||
|
util3d::adjustNormalsToViewPoint(cloud, viewPoint, (float)_ui->doubleSpinBox_groundNormalsUp->value());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@@ -3724,6 +3801,10 @@ std::map<int, std::pair<pcl::PointCloud<pcl::PointXYZRGBNormal>::Ptr, pcl::Indic
|
|||||||
{
|
{
|
||||||
pcl::PointCloud<pcl::Normal>::Ptr normals = util3d::computeNormals(cloudWithoutNormals, indices, _ui->spinBox_normalKSearch->value(), _ui->doubleSpinBox_normalRadiusSearch->value(), viewPoint);
|
pcl::PointCloud<pcl::Normal>::Ptr normals = util3d::computeNormals(cloudWithoutNormals, indices, _ui->spinBox_normalKSearch->value(), _ui->doubleSpinBox_normalRadiusSearch->value(), viewPoint);
|
||||||
pcl::concatenateFields(*cloudWithoutNormals, *normals, *cloud);
|
pcl::concatenateFields(*cloudWithoutNormals, *normals, *cloud);
|
||||||
|
if(_ui->doubleSpinBox_groundNormalsUp->value() > 0.0)
|
||||||
|
{
|
||||||
|
util3d::adjustNormalsToViewPoint(cloud, viewPoint, (float)_ui->doubleSpinBox_groundNormalsUp->value());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -23,22 +23,43 @@
|
|||||||
<property name="geometry">
|
<property name="geometry">
|
||||||
<rect>
|
<rect>
|
||||||
<x>0</x>
|
<x>0</x>
|
||||||
<y>0</y>
|
<y>-2140</y>
|
||||||
<width>998</width>
|
<width>998</width>
|
||||||
<height>5713</height>
|
<height>5850</height>
|
||||||
</rect>
|
</rect>
|
||||||
</property>
|
</property>
|
||||||
<layout class="QVBoxLayout" name="verticalLayout_13">
|
<layout class="QVBoxLayout" name="verticalLayout_13">
|
||||||
<item>
|
<item>
|
||||||
<layout class="QGridLayout" name="gridLayout_8" columnstretch="0,1">
|
<layout class="QGridLayout" name="gridLayout_8" columnstretch="0,1">
|
||||||
<item row="17" column="0">
|
<item row="17" column="0">
|
||||||
<widget class="QCheckBox" name="checkBox_meshing">
|
<widget class="QCheckBox" name="checkBox_cameraProjection">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string/>
|
<string/>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="17" column="1">
|
<item row="1" column="1">
|
||||||
|
<widget class="QLabel" name="label_12">
|
||||||
|
<property name="text">
|
||||||
|
<string>Reconstruction flavor.</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="14" column="0">
|
||||||
|
<widget class="QCheckBox" name="checkBox_filtering">
|
||||||
|
<property name="text">
|
||||||
|
<string/>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="13" column="0">
|
||||||
|
<widget class="QCheckBox" name="checkBox_regenerate">
|
||||||
|
<property name="text">
|
||||||
|
<string/>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="18" column="1">
|
||||||
<widget class="QLabel" name="label_binaryFile_12">
|
<widget class="QLabel" name="label_binaryFile_12">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Meshing.</string>
|
<string>Meshing.</string>
|
||||||
@@ -48,13 +69,40 @@
|
|||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="6" column="0">
|
<item row="14" column="1">
|
||||||
<widget class="QSpinBox" name="spinBox_normalKSearch">
|
<widget class="QLabel" name="label_binaryFile_9">
|
||||||
<property name="minimum">
|
<property name="text">
|
||||||
<number>0</number>
|
<string>Cloud filtering.</string>
|
||||||
</property>
|
</property>
|
||||||
<property name="value">
|
<property name="wordWrap">
|
||||||
<number>20</number>
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="7" column="1">
|
||||||
|
<widget class="QLabel" name="label_normal_2">
|
||||||
|
<property name="text">
|
||||||
|
<string>Set the search radius for the normal estimation.</string>
|
||||||
|
</property>
|
||||||
|
<property name="wordWrap">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="18" column="0">
|
||||||
|
<widget class="QCheckBox" name="checkBox_meshing">
|
||||||
|
<property name="text">
|
||||||
|
<string/>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="16" column="1">
|
||||||
|
<widget class="QLabel" name="label_gainCompensation">
|
||||||
|
<property name="text">
|
||||||
|
<string>Gain compensation. Normalize brightness of images.</string>
|
||||||
|
</property>
|
||||||
|
<property name="wordWrap">
|
||||||
|
<bool>true</bool>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
@@ -68,64 +116,36 @@
|
|||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="11" column="1">
|
<item row="4" column="0">
|
||||||
<widget class="QLabel" name="label_binaryFile_10">
|
<widget class="QCheckBox" name="checkBox_assemble">
|
||||||
<property name="text">
|
|
||||||
<string>Nodes filtering. Filter nodes to be exported in a specified region .</string>
|
|
||||||
</property>
|
|
||||||
<property name="wordWrap">
|
|
||||||
<bool>true</bool>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="14" column="0">
|
|
||||||
<widget class="QCheckBox" name="checkBox_smoothing">
|
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string/>
|
<string/>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="14" column="1">
|
<item row="3" column="0">
|
||||||
<widget class="QLabel" name="label_smoothing">
|
<widget class="QCheckBox" name="checkBox_binary">
|
||||||
<property name="text">
|
|
||||||
<string>Cloud smoothing using Moving Least Squares algorithm (MLS).</string>
|
|
||||||
</property>
|
|
||||||
<property name="wordWrap">
|
|
||||||
<bool>true</bool>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="3" column="1">
|
|
||||||
<widget class="QLabel" name="label_binaryFile">
|
|
||||||
<property name="text">
|
|
||||||
<string>Binary file (for ply and pcd outputs).</string>
|
|
||||||
</property>
|
|
||||||
<property name="wordWrap">
|
|
||||||
<bool>true</bool>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="16" column="0">
|
|
||||||
<widget class="QCheckBox" name="checkBox_cameraProjection">
|
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string/>
|
<string/>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
<property name="checked">
|
||||||
</item>
|
|
||||||
<item row="0" column="1">
|
|
||||||
<widget class="QLabel" name="label_binaryFile_11">
|
|
||||||
<property name="text">
|
|
||||||
<string>From RGB-D images. If not checked, clouds will be generated from laser scans.</string>
|
|
||||||
</property>
|
|
||||||
<property name="wordWrap">
|
|
||||||
<bool>true</bool>
|
<bool>true</bool>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="11" column="0">
|
<item row="10" column="0">
|
||||||
<widget class="QCheckBox" name="checkBox_nodes_filtering">
|
<widget class="QSpinBox" name="spinBox_randomSamples_assembled">
|
||||||
<property name="text">
|
<property name="minimum">
|
||||||
<string/>
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="maximum">
|
||||||
|
<number>99999999</number>
|
||||||
|
</property>
|
||||||
|
<property name="singleStep">
|
||||||
|
<number>10000</number>
|
||||||
|
</property>
|
||||||
|
<property name="value">
|
||||||
|
<number>0</number>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
@@ -139,98 +159,17 @@
|
|||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="12" column="0">
|
<item row="0" column="1">
|
||||||
<widget class="QCheckBox" name="checkBox_regenerate">
|
<widget class="QLabel" name="label_binaryFile_11">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string/>
|
<string>From RGB-D images. If not checked, clouds will be generated from laser scans.</string>
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="15" column="1">
|
|
||||||
<widget class="QLabel" name="label_gainCompensation">
|
|
||||||
<property name="text">
|
|
||||||
<string>Gain compensation. Normalize brightness of images.</string>
|
|
||||||
</property>
|
</property>
|
||||||
<property name="wordWrap">
|
<property name="wordWrap">
|
||||||
<bool>true</bool>
|
<bool>true</bool>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="1" column="0">
|
<item row="9" column="0">
|
||||||
<widget class="QComboBox" name="comboBox_pipeline">
|
|
||||||
<item>
|
|
||||||
<property name="text">
|
|
||||||
<string>Organized Point Cloud</string>
|
|
||||||
</property>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<property name="text">
|
|
||||||
<string>Dense Point Cloud</string>
|
|
||||||
</property>
|
|
||||||
</item>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="10" column="0">
|
|
||||||
<widget class="QComboBox" name="comboBox_intensityColormap">
|
|
||||||
<item>
|
|
||||||
<property name="text">
|
|
||||||
<string>GrayScale</string>
|
|
||||||
</property>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<property name="text">
|
|
||||||
<string>RedYellow</string>
|
|
||||||
</property>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<property name="text">
|
|
||||||
<string>Rainbow</string>
|
|
||||||
</property>
|
|
||||||
</item>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="5" column="0">
|
|
||||||
<widget class="QComboBox" name="comboBox_frame">
|
|
||||||
<item>
|
|
||||||
<property name="text">
|
|
||||||
<string>Map</string>
|
|
||||||
</property>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<property name="text">
|
|
||||||
<string>Robot</string>
|
|
||||||
</property>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<property name="text">
|
|
||||||
<string>Camera</string>
|
|
||||||
</property>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<property name="text">
|
|
||||||
<string>Scan</string>
|
|
||||||
</property>
|
|
||||||
</item>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="4" column="0">
|
|
||||||
<widget class="QCheckBox" name="checkBox_assemble">
|
|
||||||
<property name="text">
|
|
||||||
<string/>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="10" column="1">
|
|
||||||
<widget class="QLabel" name="label_intensityColormap">
|
|
||||||
<property name="text">
|
|
||||||
<string>Intensity colormap.</string>
|
|
||||||
</property>
|
|
||||||
<property name="wordWrap">
|
|
||||||
<bool>true</bool>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="8" column="0">
|
|
||||||
<widget class="QDoubleSpinBox" name="doubleSpinBox_voxelSize_assembled">
|
<widget class="QDoubleSpinBox" name="doubleSpinBox_voxelSize_assembled">
|
||||||
<property name="suffix">
|
<property name="suffix">
|
||||||
<string> m</string>
|
<string> m</string>
|
||||||
@@ -259,6 +198,130 @@
|
|||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
<item row="6" column="0">
|
||||||
|
<widget class="QSpinBox" name="spinBox_normalKSearch">
|
||||||
|
<property name="minimum">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="value">
|
||||||
|
<number>20</number>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="15" column="0">
|
||||||
|
<widget class="QCheckBox" name="checkBox_smoothing">
|
||||||
|
<property name="text">
|
||||||
|
<string/>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="1" column="0">
|
||||||
|
<widget class="QComboBox" name="comboBox_pipeline">
|
||||||
|
<item>
|
||||||
|
<property name="text">
|
||||||
|
<string>Organized Point Cloud</string>
|
||||||
|
</property>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<property name="text">
|
||||||
|
<string>Dense Point Cloud</string>
|
||||||
|
</property>
|
||||||
|
</item>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="15" column="1">
|
||||||
|
<widget class="QLabel" name="label_smoothing">
|
||||||
|
<property name="text">
|
||||||
|
<string>Cloud smoothing using Moving Least Squares algorithm (MLS).</string>
|
||||||
|
</property>
|
||||||
|
<property name="wordWrap">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="11" column="1">
|
||||||
|
<widget class="QLabel" name="label_intensityColormap">
|
||||||
|
<property name="text">
|
||||||
|
<string>Intensity colormap.</string>
|
||||||
|
</property>
|
||||||
|
<property name="wordWrap">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="9" column="1">
|
||||||
|
<widget class="QLabel" name="label_voxel">
|
||||||
|
<property name="text">
|
||||||
|
<string>Voxel size. Set 0 to disable. When organized meshes are assembled, this is the radius in which the vertices of the polygons are merged.</string>
|
||||||
|
</property>
|
||||||
|
<property name="wordWrap">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="11" column="0">
|
||||||
|
<widget class="QComboBox" name="comboBox_intensityColormap">
|
||||||
|
<item>
|
||||||
|
<property name="text">
|
||||||
|
<string>GrayScale</string>
|
||||||
|
</property>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<property name="text">
|
||||||
|
<string>RedYellow</string>
|
||||||
|
</property>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<property name="text">
|
||||||
|
<string>Rainbow</string>
|
||||||
|
</property>
|
||||||
|
</item>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="17" column="1">
|
||||||
|
<widget class="QLabel" name="label_cameraProjection">
|
||||||
|
<property name="text">
|
||||||
|
<string>Camera projection. This can be used to colorize point cloud created from scans and/or export camera IDs for each point of the cloud.</string>
|
||||||
|
</property>
|
||||||
|
<property name="wordWrap">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="12" column="1">
|
||||||
|
<widget class="QLabel" name="label_binaryFile_10">
|
||||||
|
<property name="text">
|
||||||
|
<string>Nodes filtering. Filter nodes to be exported in a specified region .</string>
|
||||||
|
</property>
|
||||||
|
<property name="wordWrap">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="5" column="0">
|
||||||
|
<widget class="QComboBox" name="comboBox_frame">
|
||||||
|
<item>
|
||||||
|
<property name="text">
|
||||||
|
<string>Map</string>
|
||||||
|
</property>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<property name="text">
|
||||||
|
<string>Robot</string>
|
||||||
|
</property>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<property name="text">
|
||||||
|
<string>Camera</string>
|
||||||
|
</property>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<property name="text">
|
||||||
|
<string>Scan</string>
|
||||||
|
</property>
|
||||||
|
</item>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
<item row="7" column="0">
|
<item row="7" column="0">
|
||||||
<widget class="QDoubleSpinBox" name="doubleSpinBox_normalRadiusSearch">
|
<widget class="QDoubleSpinBox" name="doubleSpinBox_normalRadiusSearch">
|
||||||
<property name="singleStep">
|
<property name="singleStep">
|
||||||
@@ -266,14 +329,34 @@
|
|||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="15" column="0">
|
<item row="16" column="0">
|
||||||
<widget class="QCheckBox" name="checkBox_gainCompensation">
|
<widget class="QCheckBox" name="checkBox_gainCompensation">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string/>
|
<string/>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="12" column="1">
|
<item row="10" column="1">
|
||||||
|
<widget class="QLabel" name="label_voxel_2">
|
||||||
|
<property name="text">
|
||||||
|
<string>Number of samples to keep, done with a random sample filter. Only used when clouds are assembled. Set 0 to disable.</string>
|
||||||
|
</property>
|
||||||
|
<property name="wordWrap">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="3" column="1">
|
||||||
|
<widget class="QLabel" name="label_binaryFile">
|
||||||
|
<property name="text">
|
||||||
|
<string>Binary file (for ply and pcd outputs).</string>
|
||||||
|
</property>
|
||||||
|
<property name="wordWrap">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="13" column="1">
|
||||||
<widget class="QLabel" name="label_regenerate">
|
<widget class="QLabel" name="label_regenerate">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Regenerate clouds. This can be used to regenerate the point clouds at higher density than those used for online visualization.</string>
|
<string>Regenerate clouds. This can be used to regenerate the point clouds at higher density than those used for online visualization.</string>
|
||||||
@@ -283,15 +366,8 @@
|
|||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="1" column="1">
|
<item row="12" column="0">
|
||||||
<widget class="QLabel" name="label_12">
|
<widget class="QCheckBox" name="checkBox_nodes_filtering">
|
||||||
<property name="text">
|
|
||||||
<string>Reconstruction flavor.</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="13" column="0">
|
|
||||||
<widget class="QCheckBox" name="checkBox_filtering">
|
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string/>
|
<string/>
|
||||||
</property>
|
</property>
|
||||||
@@ -307,79 +383,23 @@
|
|||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="3" column="0">
|
|
||||||
<widget class="QCheckBox" name="checkBox_binary">
|
|
||||||
<property name="text">
|
|
||||||
<string/>
|
|
||||||
</property>
|
|
||||||
<property name="checked">
|
|
||||||
<bool>true</bool>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="8" column="1">
|
<item row="8" column="1">
|
||||||
<widget class="QLabel" name="label_voxel">
|
<widget class="QLabel" name="label_normal_3">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Voxel size. Set 0 to disable. When organized meshes are assembled, this is the radius in which the vertices of the polygons are merged.</string>
|
<string>Flip ground normals up if close to -z axis. Set to 0.9 to begin with, increase to limit normals very close to -z axis. Set 0 to disable.</string>
|
||||||
</property>
|
</property>
|
||||||
<property name="wordWrap">
|
<property name="wordWrap">
|
||||||
<bool>true</bool>
|
<bool>true</bool>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="13" column="1">
|
<item row="8" column="0">
|
||||||
<widget class="QLabel" name="label_binaryFile_9">
|
<widget class="QDoubleSpinBox" name="doubleSpinBox_groundNormalsUp">
|
||||||
<property name="text">
|
|
||||||
<string>Cloud filtering.</string>
|
|
||||||
</property>
|
|
||||||
<property name="wordWrap">
|
|
||||||
<bool>true</bool>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="7" column="1">
|
|
||||||
<widget class="QLabel" name="label_normal_2">
|
|
||||||
<property name="text">
|
|
||||||
<string>Set the search radius for the normal estimation.</string>
|
|
||||||
</property>
|
|
||||||
<property name="wordWrap">
|
|
||||||
<bool>true</bool>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="16" column="1">
|
|
||||||
<widget class="QLabel" name="label_cameraProjection">
|
|
||||||
<property name="text">
|
|
||||||
<string>Camera projection. This can be used to colorize point cloud created from scans and/or export camera IDs for each point of the cloud.</string>
|
|
||||||
</property>
|
|
||||||
<property name="wordWrap">
|
|
||||||
<bool>true</bool>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="9" column="1">
|
|
||||||
<widget class="QLabel" name="label_voxel_2">
|
|
||||||
<property name="text">
|
|
||||||
<string>Number of samples to keep, done with a random sample filter. Only used when clouds are assembled. Set 0 to disable.</string>
|
|
||||||
</property>
|
|
||||||
<property name="wordWrap">
|
|
||||||
<bool>true</bool>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="9" column="0">
|
|
||||||
<widget class="QSpinBox" name="spinBox_randomSamples_assembled">
|
|
||||||
<property name="minimum">
|
|
||||||
<number>0</number>
|
|
||||||
</property>
|
|
||||||
<property name="maximum">
|
<property name="maximum">
|
||||||
<number>99999999</number>
|
<double>1.000000000000000</double>
|
||||||
</property>
|
</property>
|
||||||
<property name="singleStep">
|
<property name="singleStep">
|
||||||
<number>10000</number>
|
<double>0.010000000000000</double>
|
||||||
</property>
|
|
||||||
<property name="value">
|
|
||||||
<number>0</number>
|
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
@@ -1850,39 +1870,7 @@ Guidelines: 4 times the voxel size, 0.025 for voxel=0.</string>
|
|||||||
<bool>false</bool>
|
<bool>false</bool>
|
||||||
</property>
|
</property>
|
||||||
<layout class="QGridLayout" name="gridLayout_20" columnstretch="0,0,0,1">
|
<layout class="QGridLayout" name="gridLayout_20" columnstretch="0,0,0,1">
|
||||||
<item row="3" column="1">
|
<item row="6" column="1">
|
||||||
<widget class="QDoubleSpinBox" name="doubleSpinBox_camProjMaxAngle">
|
|
||||||
<property name="suffix">
|
|
||||||
<string> deg</string>
|
|
||||||
</property>
|
|
||||||
<property name="decimals">
|
|
||||||
<number>0</number>
|
|
||||||
</property>
|
|
||||||
<property name="minimum">
|
|
||||||
<double>0.000000000000000</double>
|
|
||||||
</property>
|
|
||||||
<property name="maximum">
|
|
||||||
<double>180.000000000000000</double>
|
|
||||||
</property>
|
|
||||||
<property name="singleStep">
|
|
||||||
<double>1.000000000000000</double>
|
|
||||||
</property>
|
|
||||||
<property name="value">
|
|
||||||
<double>0.000000000000000</double>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="5" column="2" colspan="2">
|
|
||||||
<widget class="QLabel" name="label_meshingTextureSize_15">
|
|
||||||
<property name="text">
|
|
||||||
<string>Keep points not seen by the cameras. These points will be set with a pure red color (255,0,0) if the cloud was created from laser scans.</string>
|
|
||||||
</property>
|
|
||||||
<property name="wordWrap">
|
|
||||||
<bool>true</bool>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="4" column="1">
|
|
||||||
<widget class="QCheckBox" name="checkBox_camProjDistanceToCamPolicy">
|
<widget class="QCheckBox" name="checkBox_camProjDistanceToCamPolicy">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string/>
|
<string/>
|
||||||
@@ -1890,9 +1878,19 @@ Guidelines: 4 times the voxel size, 0.025 for voxel=0.</string>
|
|||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="4" column="2" colspan="2">
|
<item row="4" column="2" colspan="2">
|
||||||
<widget class="QLabel" name="label_meshingTextureSize_14">
|
<widget class="QLabel" name="label_meshingTextureSize_16">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Distance to camera policy. The closest camera from a point is used to colorize the point. If disabled, the camera for which the point projection is the closest of the image center is used to colorize the point.</string>
|
<string>Decimation of camera resolution before projection. This can help to correctly estimate points hidden by other points, in case the point cloud is sparse.</string>
|
||||||
|
</property>
|
||||||
|
<property name="wordWrap">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="9" column="2" colspan="2">
|
||||||
|
<widget class="QLabel" name="label_camProjExportCamera">
|
||||||
|
<property name="text">
|
||||||
|
<string>ID format of the camera selected for each point.</string>
|
||||||
</property>
|
</property>
|
||||||
<property name="wordWrap">
|
<property name="wordWrap">
|
||||||
<bool>true</bool>
|
<bool>true</bool>
|
||||||
@@ -1909,6 +1907,35 @@ Guidelines: 4 times the voxel size, 0.025 for voxel=0.</string>
|
|||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
<item row="4" column="1">
|
||||||
|
<widget class="QSpinBox" name="spinBox_camProjDecimation">
|
||||||
|
<property name="suffix">
|
||||||
|
<string/>
|
||||||
|
</property>
|
||||||
|
<property name="minimum">
|
||||||
|
<number>1</number>
|
||||||
|
</property>
|
||||||
|
<property name="maximum">
|
||||||
|
<number>9999</number>
|
||||||
|
</property>
|
||||||
|
<property name="singleStep">
|
||||||
|
<number>1</number>
|
||||||
|
</property>
|
||||||
|
<property name="value">
|
||||||
|
<number>1</number>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="1" column="2" colspan="2">
|
||||||
|
<widget class="QLabel" name="label_meshingTextureSize_17">
|
||||||
|
<property name="text">
|
||||||
|
<string>ROI ratios [left right top bottom] between 0 and 1. This can be used to ignore black borders of RGB images caused by calibration. </string>
|
||||||
|
</property>
|
||||||
|
<property name="wordWrap">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
<item row="3" column="2" colspan="2">
|
<item row="3" column="2" colspan="2">
|
||||||
<widget class="QLabel" name="label_meshingTextureSize_12">
|
<widget class="QLabel" name="label_meshingTextureSize_12">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
@@ -1919,46 +1946,24 @@ Guidelines: 4 times the voxel size, 0.025 for voxel=0.</string>
|
|||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="2" column="1">
|
<item row="8" column="1">
|
||||||
<widget class="QDoubleSpinBox" name="doubleSpinBox_camProjMaxDistance">
|
<widget class="QCheckBox" name="checkBox_camProjRecolorPoints">
|
||||||
<property name="suffix">
|
<property name="text">
|
||||||
<string> m</string>
|
<string/>
|
||||||
</property>
|
|
||||||
<property name="decimals">
|
|
||||||
<number>1</number>
|
|
||||||
</property>
|
|
||||||
<property name="minimum">
|
|
||||||
<double>0.000000000000000</double>
|
|
||||||
</property>
|
|
||||||
<property name="maximum">
|
|
||||||
<double>99.000000000000000</double>
|
|
||||||
</property>
|
|
||||||
<property name="singleStep">
|
|
||||||
<double>1.000000000000000</double>
|
|
||||||
</property>
|
|
||||||
<property name="value">
|
|
||||||
<double>0.000000000000000</double>
|
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="5" column="1">
|
<item row="5" column="1">
|
||||||
|
<widget class="QLineEdit" name="lineEdit_camProjMaskFilePath"/>
|
||||||
|
</item>
|
||||||
|
<item row="7" column="1">
|
||||||
<widget class="QCheckBox" name="checkBox_camProjKeepPointsNotSeenByCameras">
|
<widget class="QCheckBox" name="checkBox_camProjKeepPointsNotSeenByCameras">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string/>
|
<string/>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="7" column="2" colspan="2">
|
<item row="9" column="1">
|
||||||
<widget class="QLabel" name="label_camProjExportCamera">
|
|
||||||
<property name="text">
|
|
||||||
<string>ID format of the camera selected for each point.</string>
|
|
||||||
</property>
|
|
||||||
<property name="wordWrap">
|
|
||||||
<bool>true</bool>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="7" column="1">
|
|
||||||
<widget class="QComboBox" name="comboBox_camProjExportCamera">
|
<widget class="QComboBox" name="comboBox_camProjExportCamera">
|
||||||
<property name="toolTip">
|
<property name="toolTip">
|
||||||
<string>By Node ID: cameras of same node have same ID
|
<string>By Node ID: cameras of same node have same ID
|
||||||
@@ -1987,20 +1992,74 @@ By Node ID and Camera Index: NodeID*10+CameraIndex</string>
|
|||||||
</item>
|
</item>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="1" column="1">
|
<item row="6" column="2" colspan="2">
|
||||||
<widget class="QLineEdit" name="lineEdit_camProjRoiRatios"/>
|
<widget class="QLabel" name="label_meshingTextureSize_14">
|
||||||
</item>
|
|
||||||
<item row="1" column="2" colspan="2">
|
|
||||||
<widget class="QLabel" name="label_meshingTextureSize_17">
|
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>ROI ratios [left right top bottom] between 0 and 1. This can be used to ignore black borders of RGB images caused by calibration. </string>
|
<string>Distance to camera policy. The closest camera from a point is used to colorize the point. If disabled, the camera for which the point projection is the closest of the image center is used to colorize the point.</string>
|
||||||
</property>
|
</property>
|
||||||
<property name="wordWrap">
|
<property name="wordWrap">
|
||||||
<bool>true</bool>
|
<bool>true</bool>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="6" column="2">
|
<item row="1" column="1">
|
||||||
|
<widget class="QLineEdit" name="lineEdit_camProjRoiRatios"/>
|
||||||
|
</item>
|
||||||
|
<item row="3" column="1">
|
||||||
|
<widget class="QDoubleSpinBox" name="doubleSpinBox_camProjMaxAngle">
|
||||||
|
<property name="suffix">
|
||||||
|
<string> deg</string>
|
||||||
|
</property>
|
||||||
|
<property name="decimals">
|
||||||
|
<number>0</number>
|
||||||
|
</property>
|
||||||
|
<property name="minimum">
|
||||||
|
<double>0.000000000000000</double>
|
||||||
|
</property>
|
||||||
|
<property name="maximum">
|
||||||
|
<double>180.000000000000000</double>
|
||||||
|
</property>
|
||||||
|
<property name="singleStep">
|
||||||
|
<double>1.000000000000000</double>
|
||||||
|
</property>
|
||||||
|
<property name="value">
|
||||||
|
<double>0.000000000000000</double>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="2" column="1">
|
||||||
|
<widget class="QDoubleSpinBox" name="doubleSpinBox_camProjMaxDistance">
|
||||||
|
<property name="suffix">
|
||||||
|
<string> m</string>
|
||||||
|
</property>
|
||||||
|
<property name="decimals">
|
||||||
|
<number>1</number>
|
||||||
|
</property>
|
||||||
|
<property name="minimum">
|
||||||
|
<double>0.000000000000000</double>
|
||||||
|
</property>
|
||||||
|
<property name="maximum">
|
||||||
|
<double>99.000000000000000</double>
|
||||||
|
</property>
|
||||||
|
<property name="singleStep">
|
||||||
|
<double>1.000000000000000</double>
|
||||||
|
</property>
|
||||||
|
<property name="value">
|
||||||
|
<double>0.000000000000000</double>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="7" column="2" colspan="2">
|
||||||
|
<widget class="QLabel" name="label_meshingTextureSize_15">
|
||||||
|
<property name="text">
|
||||||
|
<string>Keep points not seen by the cameras. These points will be set with a pure red color (255,0,0) if the cloud was created from laser scans.</string>
|
||||||
|
</property>
|
||||||
|
<property name="wordWrap">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="8" column="2">
|
||||||
<widget class="QLabel" name="label_meshingTextureSize_18">
|
<widget class="QLabel" name="label_meshingTextureSize_18">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Recolor points from camera projection. This would be used to color laser scans with the cameras.</string>
|
<string>Recolor points from camera projection. This would be used to color laser scans with the cameras.</string>
|
||||||
@@ -2010,10 +2069,20 @@ By Node ID and Camera Index: NodeID*10+CameraIndex</string>
|
|||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="6" column="1">
|
<item row="5" column="2" colspan="2">
|
||||||
<widget class="QCheckBox" name="checkBox_camProjRecolorPoints">
|
<widget class="QLabel" name="label_meshingTextureSize_19">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string/>
|
<string>File path for a mask. Format should be 8-bits grayscale. The mask should cover all cameras in case multi-camera is used and have the same resolution.</string>
|
||||||
|
</property>
|
||||||
|
<property name="wordWrap">
|
||||||
|
<bool>true</bool>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="5" column="0">
|
||||||
|
<widget class="QToolButton" name="toolButton_camProjMaskFilePath">
|
||||||
|
<property name="text">
|
||||||
|
<string>...</string>
|
||||||
</property>
|
</property>
|
||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
|
|||||||
@@ -58,7 +58,7 @@ void showUsage()
|
|||||||
"Options:\n"
|
"Options:\n"
|
||||||
" --output \"\" Output name (default: name of the database is used).\n"
|
" --output \"\" Output name (default: name of the database is used).\n"
|
||||||
" --output_dir \"\" Output directory (default: same directory than the database).\n"
|
" --output_dir \"\" Output directory (default: same directory than the database).\n"
|
||||||
" --bin Export PLY in binary format.\n"
|
" --ascii Export PLY in ascii format.\n"
|
||||||
" --las Export cloud in LAS instead of PLY (PDAL dependency required).\n"
|
" --las Export cloud in LAS instead of PLY (PDAL dependency required).\n"
|
||||||
" --mesh Create a mesh.\n"
|
" --mesh Create a mesh.\n"
|
||||||
" --texture Create a mesh with texture.\n"
|
" --texture Create a mesh with texture.\n"
|
||||||
@@ -67,11 +67,12 @@ void showUsage()
|
|||||||
" --texture_range # Maximum camera range for texturing a polygon (default 0 meters: no limit).\n"
|
" --texture_range # Maximum camera range for texturing a polygon (default 0 meters: no limit).\n"
|
||||||
" --texture_angle # Maximum camera angle for texturing a polygon (default 0 deg: no limit).\n"
|
" --texture_angle # Maximum camera angle for texturing a polygon (default 0 deg: no limit).\n"
|
||||||
" --texture_depth_error # Maximum depth error between reprojected mesh and depth image to texture a face (-1=disabled, 0=edge length is used, default=0).\n"
|
" --texture_depth_error # Maximum depth error between reprojected mesh and depth image to texture a face (-1=disabled, 0=edge length is used, default=0).\n"
|
||||||
" --texture_roi_ratios \"# # # #\" Region of interest from images to texture or to color scans. Format is \"left right top bottom\" (e.g. \"0 0 0 0.1\" means 10% of the image bottom not used).\n"
|
" --texture_roi_ratios \"# # # #\" Region of interest from images to texture or to color scans. Format is \"left right top bottom\" (e.g. \"0 0 0 0.1\" means 10%% of the image bottom not used).\n"
|
||||||
" --texture_d2c Distance to camera policy.\n"
|
" --texture_d2c Distance to camera policy.\n"
|
||||||
" --cam_projection Camera projection on assembled cloud and export node ID on each point (in PointSourceId field).\n"
|
" --cam_projection Camera projection on assembled cloud and export node ID on each point (in PointSourceId field).\n"
|
||||||
" --cam_projection_keep_all Keep not colored points from cameras (node ID will be 0 and color will be red).\n"
|
" --cam_projection_keep_all Keep not colored points from cameras (node ID will be 0 and color will be red).\n"
|
||||||
" --cam_projection_decimation Decimate images before projecting the points.\n"
|
" --cam_projection_decimation Decimate images before projecting the points.\n"
|
||||||
|
" --cam_projection_mask \"\" File path for a mask. Format should be 8-bits grayscale. The mask should cover all cameras in case multi-camera is used and have the same resolution.\n"
|
||||||
" --poses Export optimized poses of the robot frame (e.g., base_link).\n"
|
" --poses Export optimized poses of the robot frame (e.g., base_link).\n"
|
||||||
" --poses_camera Export optimized poses of the camera frame (e.g., optical frame).\n"
|
" --poses_camera Export optimized poses of the camera frame (e.g., optical frame).\n"
|
||||||
" --poses_scan Export optimized poses of the scan frame.\n"
|
" --poses_scan Export optimized poses of the scan frame.\n"
|
||||||
@@ -108,6 +109,7 @@ void showUsage()
|
|||||||
" --max_range # Maximum range of the created clouds (default 4 m, 0 m with --scan).\n"
|
" --max_range # Maximum range of the created clouds (default 4 m, 0 m with --scan).\n"
|
||||||
" --decimation # Depth image decimation before creating the clouds (default 4, 1 with --scan).\n"
|
" --decimation # Depth image decimation before creating the clouds (default 4, 1 with --scan).\n"
|
||||||
" --voxel # Voxel size of the created clouds (default 0.01 m, 0 m with --scan).\n"
|
" --voxel # Voxel size of the created clouds (default 0.01 m, 0 m with --scan).\n"
|
||||||
|
" --ground_normals_up # Flip ground normals up if close to -z axis (default 0, 0=disabled, value should be >0 and <1, typical 0.9).\n"
|
||||||
" --noise_radius # Noise filtering search radius (default 0, 0=disabled).\n"
|
" --noise_radius # Noise filtering search radius (default 0, 0=disabled).\n"
|
||||||
" --noise_k # Noise filtering minimum neighbors in search radius (default 5, 0=disabled).\n"
|
" --noise_k # Noise filtering minimum neighbors in search radius (default 5, 0=disabled).\n"
|
||||||
" --prop_radius_factor # Proportional radius filter factor (default 0, 0=disabled). Start tuning from 0.01.\n"
|
" --prop_radius_factor # Proportional radius filter factor (default 0, 0=disabled). Start tuning from 0.01.\n"
|
||||||
@@ -150,7 +152,7 @@ int main(int argc, char * argv[])
|
|||||||
showUsage();
|
showUsage();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool binary = false;
|
bool binary = true;
|
||||||
bool las = false;
|
bool las = false;
|
||||||
bool mesh = false;
|
bool mesh = false;
|
||||||
bool texture = false;
|
bool texture = false;
|
||||||
@@ -166,6 +168,7 @@ int main(int argc, char * argv[])
|
|||||||
int decimation = -1;
|
int decimation = -1;
|
||||||
float maxRange = -1.0f;
|
float maxRange = -1.0f;
|
||||||
float voxelSize = -1.0f;
|
float voxelSize = -1.0f;
|
||||||
|
float groundNormalsUp = 0.0f;
|
||||||
float noiseRadius = 0.0f;
|
float noiseRadius = 0.0f;
|
||||||
int noiseMinNeighbors = 5;
|
int noiseMinNeighbors = 5;
|
||||||
float proportionalRadiusFactor = 0.0f;
|
float proportionalRadiusFactor = 0.0f;
|
||||||
@@ -195,6 +198,7 @@ int main(int argc, char * argv[])
|
|||||||
bool camProjection = false;
|
bool camProjection = false;
|
||||||
bool camProjectionKeepAll = false;
|
bool camProjectionKeepAll = false;
|
||||||
int cameraProjDecimation = 1;
|
int cameraProjDecimation = 1;
|
||||||
|
std::string cameraProjMask;
|
||||||
bool exportPoses = false;
|
bool exportPoses = false;
|
||||||
bool exportPosesCamera = false;
|
bool exportPosesCamera = false;
|
||||||
bool exportPosesScan = false;
|
bool exportPosesScan = false;
|
||||||
@@ -238,7 +242,11 @@ int main(int argc, char * argv[])
|
|||||||
}
|
}
|
||||||
else if(std::strcmp(argv[i], "--bin") == 0)
|
else if(std::strcmp(argv[i], "--bin") == 0)
|
||||||
{
|
{
|
||||||
binary = true;
|
printf("No need to set --bin anymore, ply are now automatically exported in binary by default. Set --ascii to export as text.\n")
|
||||||
|
}
|
||||||
|
else if(std::strcmp(argv[i], "--ascii") == 0)
|
||||||
|
{
|
||||||
|
binary = false;
|
||||||
}
|
}
|
||||||
else if(std::strcmp(argv[i], "--las") == 0)
|
else if(std::strcmp(argv[i], "--las") == 0)
|
||||||
{
|
{
|
||||||
@@ -387,6 +395,23 @@ int main(int argc, char * argv[])
|
|||||||
showUsage();
|
showUsage();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if(std::strcmp(argv[i], "--cam_projection_mask") == 0)
|
||||||
|
{
|
||||||
|
++i;
|
||||||
|
if(i<argc-1)
|
||||||
|
{
|
||||||
|
cameraProjMask = argv[i];
|
||||||
|
if(!UFile::exists(cameraProjMask))
|
||||||
|
{
|
||||||
|
printf("--cam_projection_mask is set with a file not existing or don't have permissions to open it. Path=\"%s\"\n", argv[i]);
|
||||||
|
showUsage();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
showUsage();
|
||||||
|
}
|
||||||
|
}
|
||||||
else if(std::strcmp(argv[i], "--poses") == 0)
|
else if(std::strcmp(argv[i], "--poses") == 0)
|
||||||
{
|
{
|
||||||
exportPoses = true;
|
exportPoses = true;
|
||||||
@@ -626,6 +651,18 @@ int main(int argc, char * argv[])
|
|||||||
showUsage();
|
showUsage();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if(std::strcmp(argv[i], "--ground_normals_up") == 0)
|
||||||
|
{
|
||||||
|
++i;
|
||||||
|
if(i<argc-1)
|
||||||
|
{
|
||||||
|
groundNormalsUp = uStr2Float(argv[i]);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
showUsage();
|
||||||
|
}
|
||||||
|
}
|
||||||
else if(std::strcmp(argv[i], "--noise_radius") == 0)
|
else if(std::strcmp(argv[i], "--noise_radius") == 0)
|
||||||
{
|
{
|
||||||
++i;
|
++i;
|
||||||
@@ -1340,7 +1377,8 @@ int main(int argc, char * argv[])
|
|||||||
rawViewpoints,
|
rawViewpoints,
|
||||||
rawAssembledCloud,
|
rawAssembledCloud,
|
||||||
rawViewpointIndices,
|
rawViewpointIndices,
|
||||||
cloudToExport);
|
cloudToExport,
|
||||||
|
groundNormalsUp);
|
||||||
printf("Adjust normals to viewpoints of the assembled cloud... (%fs, %d points)\n", timer.ticks(), (int)cloudToExport->size());
|
printf("Adjust normals to viewpoints of the assembled cloud... (%fs, %d points)\n", timer.ticks(), (int)cloudToExport->size());
|
||||||
}
|
}
|
||||||
else if(!assembledCloudI->empty())
|
else if(!assembledCloudI->empty())
|
||||||
@@ -1356,7 +1394,8 @@ int main(int argc, char * argv[])
|
|||||||
rawViewpoints,
|
rawViewpoints,
|
||||||
rawAssembledCloud,
|
rawAssembledCloud,
|
||||||
rawViewpointIndices,
|
rawViewpointIndices,
|
||||||
cloudIToExport);
|
cloudIToExport,
|
||||||
|
groundNormalsUp);
|
||||||
printf("Adjust normals to viewpoints of the assembled cloud... (%fs, %d points)\n", timer.ticks(), (int)cloudIToExport->size());
|
printf("Adjust normals to viewpoints of the assembled cloud... (%fs, %d points)\n", timer.ticks(), (int)cloudIToExport->size());
|
||||||
}
|
}
|
||||||
cloudWithoutNormals->clear();
|
cloudWithoutNormals->clear();
|
||||||
@@ -1400,6 +1439,19 @@ int main(int argc, char * argv[])
|
|||||||
{
|
{
|
||||||
cameraModelsProj = cameraModels;
|
cameraModelsProj = cameraModels;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cv::Mat projMask;
|
||||||
|
if(!cameraProjMask.empty())
|
||||||
|
{
|
||||||
|
projMask = cv::imread(cameraProjMask, cv::IMREAD_GRAYSCALE);
|
||||||
|
if(cameraProjDecimation>1)
|
||||||
|
{
|
||||||
|
cv::Mat out = projMask;
|
||||||
|
cv::resize(projMask, out, cv::Size(), 1.0f/float(cameraProjDecimation), 1.0f/float(cameraProjDecimation), cv::INTER_NEAREST);
|
||||||
|
projMask = out;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pointToCamId.resize(!cloudToExport->empty()?cloudToExport->size():cloudIToExport->size());
|
pointToCamId.resize(!cloudToExport->empty()?cloudToExport->size():cloudIToExport->size());
|
||||||
std::vector<std::pair< std::pair<int, int>, pcl::PointXY> > pointToPixel;
|
std::vector<std::pair< std::pair<int, int>, pcl::PointXY> > pointToPixel;
|
||||||
if(!cloudToExport->empty())
|
if(!cloudToExport->empty())
|
||||||
@@ -1411,6 +1463,7 @@ int main(int argc, char * argv[])
|
|||||||
textureRange,
|
textureRange,
|
||||||
textureAngle,
|
textureAngle,
|
||||||
textureRoiRatios,
|
textureRoiRatios,
|
||||||
|
projMask,
|
||||||
distanceToCamPolicy,
|
distanceToCamPolicy,
|
||||||
&progressState);
|
&progressState);
|
||||||
}
|
}
|
||||||
@@ -1423,6 +1476,7 @@ int main(int argc, char * argv[])
|
|||||||
textureRange,
|
textureRange,
|
||||||
textureAngle,
|
textureAngle,
|
||||||
textureRoiRatios,
|
textureRoiRatios,
|
||||||
|
projMask,
|
||||||
distanceToCamPolicy,
|
distanceToCamPolicy,
|
||||||
&progressState);
|
&progressState);
|
||||||
pointToCamIntensity.resize(pointToPixel.size());
|
pointToCamIntensity.resize(pointToPixel.size());
|
||||||
|
|||||||
Reference in New Issue
Block a user