26 #include <pcl/ModelCoefficients.h> 27 #include <pcl/common/time.h> 28 #include <pcl/common/transforms.h> 29 #include <pcl/features/integral_image_normal.h> 30 #include <pcl/features/normal_3d.h> 31 #include <pcl/filters/extract_indices.h> 32 #include <pcl/filters/voxel_grid.h> 33 #include <pcl/segmentation/organized_connected_component_segmentation.h> 34 #include <pcl/segmentation/organized_multi_plane_segmentation.h> 42 using namespace Eigen;
50 assert(hist1.size() == hist2.size());
52 double BhattachDist_aux = 0.0;
53 for (
unsigned i = 0; i < hist1.size(); i++)
54 BhattachDist_aux += sqrt(hist1[i] * hist2[i]);
56 BhattachDist = sqrt(1 - BhattachDist_aux);
121 "plane_segmentation",
"dist_threshold", 0.04,
true);
123 "plane_segmentation",
"angle_threshold", 0.069812,
true);
125 "plane_segmentation",
"minInliersRate", 0.01,
true);
129 config_file.
read_bool(
"map_construction",
"use_color",
false);
131 config_file.
read_float(
"map_construction",
"color_threshold", 0.09);
133 "map_construction",
"intensity_threshold", 255.0);
135 config_file.
read_float(
"unary",
"hue_threshold", 0.25);
137 "map_construction",
"proximity_neighbor_planes", 1.0);
139 config_file.
read_int(
"map_construction",
"graph_mode", 1);
141 "map_construction",
"max_cos_normal", 0.9848,
true);
143 "map_construction",
"max_dist_center_plane", 0.1,
true);
145 config_file.
read_float(
"map_construction",
"proximity_threshold", 0.15);
149 config_file.
read_bool(
"semantics",
"inferStructure",
true);
151 config_file.
read_bool(
"semantics",
"makeCovisibilityClusters",
false);
157 config_file.
read_bool(
"localisation",
"detect_loopClosure",
true);
160 "localisation",
"config_localiser",
"",
true);
164 config_file.
read_string(
"serialize",
"path_save_pbmap",
"map");
166 config_file.
read_bool(
"serialize",
"save_registered_cloud",
true);
168 "serialize",
"path_save_registered_cloud",
169 "/home/edu/Projects/PbMaps/PbMaps.txt");
174 cout <<
"readConfigFile configPbMap.ini dist_threshold " 179 PbMapMaker::PbMapMaker(
const string& config_file)
180 : cloudViewer(
"Cloud Viewer"),
181 mpPbMapLocaliser(nullptr),
182 m_pbmaker_must_stop(false),
183 m_pbmaker_finished(false)
201 Plane& plane1,
Plane& plane2,
const float distThreshold)
203 float distThres2 = distThreshold * distThreshold;
213 .squaredNorm() < distThres2)
219 .squaredNorm() < distThres2)
227 .squaredNorm() < distThres2)
291 pcl::PointCloud<PointT>::Ptr& pointCloudPtr_arg, Eigen::Matrix4f& poseKF,
292 double distThreshold,
double angleThreshold,
double minInliersF)
296 unsigned minInliers = minInliersF * pointCloudPtr_arg->size();
299 cout <<
"detectPlanes in a cloud with " << pointCloudPtr_arg->size()
300 <<
" points " << minInliers <<
" minInliers\n";
303 pcl::PointCloud<PointT>::Ptr pointCloudPtr_arg2(
304 new pcl::PointCloud<PointT>);
305 pcl::copyPointCloud(*pointCloudPtr_arg, *pointCloudPtr_arg2);
307 pcl::PointCloud<pcl::PointXYZRGBA>::Ptr alignedCloudPtr(
308 new pcl::PointCloud<pcl::PointXYZRGBA>);
309 pcl::transformPointCloud(*pointCloudPtr_arg, *alignedCloudPtr, poseKF);
315 static pcl::VoxelGrid<pcl::PointXYZRGBA> grid;
316 grid.setLeafSize(0.02, 0.02, 0.02);
317 pcl::PointCloud<pcl::PointXYZRGBA> globalMap;
319 grid.filter(globalMap);
324 pcl::IntegralImageNormalEstimation<PointT, pcl::Normal> ne;
325 ne.setNormalEstimationMethod(ne.COVARIANCE_MATRIX);
326 ne.setMaxDepthChangeFactor(0.02f);
327 ne.setNormalSmoothingSize(10.0f);
328 ne.setDepthDependentSmoothing(
true);
330 pcl::OrganizedMultiPlaneSegmentation<PointT, pcl::Normal, pcl::Label> mps;
331 mps.setMinInliers(minInliers);
332 cout <<
"Params " << minInliers <<
" " << angleThreshold <<
" " 333 << distThreshold << endl;
334 mps.setAngularThreshold(angleThreshold);
335 mps.setDistanceThreshold(distThreshold);
337 pcl::PointCloud<pcl::Normal>::Ptr normal_cloud(
338 new pcl::PointCloud<pcl::Normal>);
339 ne.setInputCloud(pointCloudPtr_arg2);
340 ne.compute(*normal_cloud);
343 double plane_extract_start = pcl::getTime();
345 mps.setInputNormals(normal_cloud);
346 mps.setInputCloud(pointCloudPtr_arg2);
349 pcl::PlanarRegion<PointT>, aligned_allocator<pcl::PlanarRegion<PointT>>>
351 std::vector<pcl::ModelCoefficients> model_coefficients;
352 std::vector<pcl::PointIndices> inlier_indices;
353 pcl::PointCloud<pcl::Label>::Ptr labels(
new pcl::PointCloud<pcl::Label>);
354 std::vector<pcl::PointIndices> label_indices;
355 std::vector<pcl::PointIndices> boundary_indices;
356 mps.segmentAndRefine(
357 regions, model_coefficients, inlier_indices, labels, label_indices,
361 double plane_extract_end = pcl::getTime();
362 std::cout <<
"Plane extraction took " 363 << double(plane_extract_end - plane_extract_start) << std::endl;
366 cout << regions.size() <<
" planes detected\n";
372 vector<Plane> detectedPlanes;
373 for (
size_t i = 0; i < regions.size(); i++)
377 Vector3f centroid = regions[i].getCentroid();
380 poseKF.block<3, 3>(0, 0) * Vector3f(
381 model_coefficients[i].
values[0],
382 model_coefficients[i].
values[1],
383 model_coefficients[i].
values[2]);
390 pcl::ExtractIndices<pcl::PointXYZRGBA> extract;
391 extract.setInputCloud(pointCloudPtr_arg2);
393 boost::make_shared<const pcl::PointIndices>(inlier_indices[i]));
394 extract.setNegative(
false);
398 static pcl::VoxelGrid<pcl::PointXYZRGBA> plane_grid;
399 plane_grid.setLeafSize(0.05, 0.05, 0.05);
400 pcl::PointCloud<pcl::PointXYZRGBA> planeCloud;
402 plane_grid.filter(planeCloud);
406 pcl::PointCloud<pcl::PointXYZRGBA>::Ptr contourPtr(
407 new pcl::PointCloud<pcl::PointXYZRGBA>);
408 contourPtr->points = regions[i].getContour();
409 plane_grid.setLeafSize(0.1, 0.1, 0.1);
410 plane_grid.setInputCloud(contourPtr);
420 cout <<
"Area plane region " << plane.
areaVoxels <<
" of Chull " 428 bool isSamePlane =
false;
429 for (
size_t j = 0; j < detectedPlanes.size(); j++)
441 cout <<
"\tTwo regions support the same plane in the same " 447 if (!isSamePlane) detectedPlanes.push_back(plane);
451 cout << detectedPlanes.size() <<
" Planes detected\n";
460 for (
size_t i = 0; i < detectedPlanes.size(); i++)
463 bool isSamePlane =
false;
466 for (
size_t j = 0; j < numPrevPlanes;
521 cout <<
"Same plane\n";
525 for (
size_t k = j + 1; k < numPrevPlanes;
554 for (
size_t h = k + 1; h < numPrevPlanes; h++)
557 for (
size_t h = 0; h < numPrevPlanes; h++)
559 if (k == h)
continue;
574 .neighborPlanes.begin();
581 .neighborPlanes[it->first - 1] =
592 cout <<
"MERGE TWO PREVIOUS PLANES WHEREBY THE " 593 "INCORPORATION OF A NEW REGION \n";
603 detectedPlanes[i].numObservations = 1;
604 detectedPlanes[i].bFullExtent =
false;
605 detectedPlanes[i].nFramesAreaIsStable = 0;
609 detectedPlanes[i].semanticGroup =
612 .push_back(detectedPlanes[i].
id);
616 cout <<
"New plane " << detectedPlanes[i].id <<
" area " 617 << detectedPlanes[i].areaVoxels <<
" of polygon " 618 << detectedPlanes[i].areaHull << endl;
633 detectedPlanes[i].neighborPlanes[*it] = 1;
646 cout <<
"\n\tobservedPlanes: ";
667 cout <<
"Plane " << observedPlane.
id <<
" color\n" 682 cout <<
"Verify that the observed planes centers are above the floor\n";
721 cout <<
"DetectedPlanesCloud finished\n";
729 const pcl::visualization::KeyboardEvent& event,
void* viewer_void)
731 if ((event.getKeySym() ==
"r" ||
event.getKeySym() ==
"R") &&
743 Plane& plane1,
Plane& plane2,
const float& cosAngleThreshold,
744 const float& distThreshold,
const float& proxThreshold)
755 float thres_max_dist =
758 if (fabs(dist_normal) >
783 static pcl::VoxelGrid<pcl::PointXYZRGBA> merge_grid;
784 merge_grid.setLeafSize(0.05, 0.05, 0.05);
785 pcl::PointCloud<pcl::PointXYZRGBA> mergeCloud;
787 merge_grid.filter(mergeCloud);
810 unsigned char red[10] = {255, 0, 0, 255, 255, 0, 255, 204, 0, 255};
811 unsigned char grn[10] = {0, 255, 0, 255, 0, 255, 160, 51, 128, 222};
812 unsigned char blu[10] = {0, 0, 255, 0, 255, 255, 0, 204, 0, 173};
814 double ared[10] = {1.0, 0, 0, 1.0, 1.0, 0, 1.0, 0.8, 0, 1.0};
815 double agrn[10] = {0, 1.0, 0, 1.0, 0, 1.0, 0.6, 0.2, 0.5, 0.9};
816 double ablu[10] = {0, 0, 1.0, 0, 1.0, 1.0, 0, 0.8, 0, 0.7};
822 std::this_thread::sleep_for(10ms);
831 viz.removeAllShapes();
832 viz.removeAllPointClouds();
924 if (!viz.updatePointCloud(
931 name,
"PointCloud size %u",
933 viz.addText(
name, 10, 20);
946 sprintf(
name,
"normal_%u", static_cast<unsigned>(i));
947 pcl::PointXYZ pt1, pt2;
1002 sprintf(
name,
"plane_%02u", static_cast<unsigned>(i));
1038 pcl::visualization::PointCloudColorHandlerCustom<PointT>
1059 viz.setPointCloudRenderingProperties(
1060 pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 10,
1133 it->first, it->second, 0.3, 0.9, 0.9, 0.9,
1146 size_t numPrevKFs = 0;
1147 size_t minGrowPlanes = 5;
1152 std::this_thread::sleep_for(10ms);
1167 int size_partition =
1169 cout <<
"PARTITION SIZE " << size_partition << endl;
1170 assert(size_partition < 2);
1191 updateLock.unlock();
1198 cout <<
"Waiting for PbMapMaker thread to die.." << endl;
1212 cout <<
" .. PbMapMaker has died." << endl;
Eigen::Vector3f diffPoints(const POINT &P1, const POINT &P2)
PlaneInferredInfo * mpPlaneInferInfo
std::string read_string(const std::string §ion, const std::string &name, const std::string &defaultValue, bool failIfNotFound=false) const
std::map< std::string, pcl::PointXYZ > foundPlaces
pcl::PointCloud< pcl::PointXYZRGBA >::Ptr polygonContourPtr
std::set< unsigned > observedPlanes
GLboolean GLenum GLenum GLvoid * values
A class used to store a planar feature (Plane for short).
PbMapLocaliser * mpPbMapLocaliser
bool areSamePlane(Plane &plane1, Plane &plane2, const float &cosAngleThreshold, const float &distThreshold, const float &proxThreshold)
void checkProximity(Plane &plane, float proximity)
void serializePbMap(std::string path)
This class allows loading and storing values and vectors of different types from ".ini" files easily.
void keyboardEventOccurred(const pcl::visualization::KeyboardEvent &event, void *viewer_void)
boost::mutex mtx_pbmap_busy
float read_float(const std::string §ion, const std::string &name, float defaultValue, bool failIfNotFound=false) const
void viz_cb(pcl::visualization::PCLVisualizer &viz)
Eigen::Vector3f v3colorNrgb
! Radiometric description
float intensity_threshold
struct config_pbmap configPbMap
int read_int(const std::string §ion, const std::string &name, int defaultValue, bool failIfNotFound=false) const
void calcElongationAndPpalDir()
A class used to infer some semantic meaning to the planes of a PbMap.
std::string path_save_registered_cloud
std::map< unsigned, std::vector< unsigned > > groups
pcl::PointCloud< pcl::PointXYZRGBA >::Ptr alignedModelPtr
void mergePlanes(Plane &updatePlane, Plane &discardPlane)
void isFullExtent(Plane &plane, double newArea)
! Check if the area of input plane is stable and bounded (e.g < 1 m2) along the last keyframes that o...
std::string path_save_pbmap
std::set< unsigned > nearbyPlanes
pcl::PointCloud< pcl::PointXYZRGBA >::Ptr planePointCloudPtr
bool searchTheFloor(Eigen::Matrix4f &poseSensor, Plane &plane)
! Check if the input plane correpond to the floor.
void forcePtsLayOnPlane()
SemanticClustering * clusterize
float proximity_threshold
GLsizei const GLchar ** string
std::vector< unsigned > vQueueObservedPlanes
pcl::PointCloud< PointT >::Ptr globalMapPtr
bool arePlanesNearby(Plane &plane1, Plane &plane2, const float distThreshold)
float proximity_neighbor_planes
bool save_registered_cloud
float compute2DPolygonalArea()
Compute the area of a 2D planar polygon patch - using a given normal.
float dist3D_Segment_to_Segment2(Segment S1, Segment S2)
void detectPlanesCloud(pcl::PointCloud< PointT >::Ptr &pointCloudPtr_arg, Eigen::Matrix4f &poseKF, double distThreshold, double angleThreshold, double minInliersF)
int evalPartition(std::set< unsigned > &observedPlanes)
bool read_bool(const std::string §ion, const std::string &name, bool defaultValue, bool failIfNotFound=false) const
unsigned id
! Parameters to allow the plane-based representation of the map by a graph
bool isInHull(PointT &point3D, pcl::PointCloud< PointT >::Ptr hull3D)
void computeMassCenterAndArea()
Compute the patch's convex-hull area and mass center.
GLuint const GLchar * name
std::vector< frameRGBDandPose > frameQueue
Eigen::Vector3f v3center
! Geometric description
void readConfigFile(const string &config_file_name)
void savePbMap(std::string filePath)
std::vector< Plane > vPlanes
float max_dist_center_plane
#define ASSERT_FILE_EXISTS_(FIL)
unsigned currentSemanticGroup
int sprintf(char *buf, size_t bufSize, const char *format,...) noexcept MRPT_printf_format_check(3
An OS-independent version of sprintf (Notice the bufSize param, which may be ignored in some compiler...
void calcConvexHull(pcl::PointCloud< pcl::PointXYZRGBA >::Ptr &pointCloud, std::vector< size_t > &indices=DEFAULT_VECTOR)
! Calculate the plane's convex hull with the monotone chain algorithm.
CONTAINER::Scalar norm(const CONTAINER &v)
pcl::visualization::CloudViewer cloudViewer
Eigen::Vector3f getVector3fromPointXYZ(pointPCL &pt)
Eigen::Matrix< dataType, 3, 1 > compose(Eigen::Matrix< dataType, 4, 4 > &pose, Eigen::Matrix< dataType, 3, 1 > &point)
double BhattacharyyaDist(std::vector< float > &hist1, std::vector< float > &hist2)