24 #include <pcl/features/integral_image_normal.h> 25 #include <pcl/features/normal_3d.h> 26 #include <pcl/ModelCoefficients.h> 27 #include <pcl/segmentation/organized_multi_plane_segmentation.h> 28 #include <pcl/segmentation/organized_connected_component_segmentation.h> 29 #include <pcl/filters/extract_indices.h> 30 #include <pcl/filters/voxel_grid.h> 31 #include <pcl/common/transforms.h> 32 #include <pcl/common/time.h> 40 #define WATCH_BINARY 0 44 using namespace Eigen;
52 assert(hist1.size() == hist2.size());
54 double BhattachDist_aux = 0.0;
55 for (
unsigned i = 0; i < hist1.size(); i++)
56 BhattachDist_aux += sqrt(hist1[i] * hist2[i]);
58 BhattachDist = sqrt(1 - BhattachDist_aux);
123 "plane_segmentation",
"dist_threshold", 0.04,
true);
125 "plane_segmentation",
"angle_threshold", 0.069812,
true);
127 "plane_segmentation",
"minInliersRate", 0.01,
true);
131 config_file.
read_bool(
"map_construction",
"use_color",
false);
133 config_file.
read_float(
"map_construction",
"color_threshold", 0.09);
135 "map_construction",
"intensity_threshold", 255.0);
137 config_file.
read_float(
"unary",
"hue_threshold", 0.25);
139 "map_construction",
"proximity_neighbor_planes", 1.0);
141 config_file.
read_int(
"map_construction",
"graph_mode", 1);
143 "map_construction",
"max_cos_normal", 0.9848,
true);
145 "map_construction",
"max_dist_center_plane", 0.1,
true);
147 config_file.
read_float(
"map_construction",
"proximity_threshold", 0.15);
151 config_file.
read_bool(
"semantics",
"inferStructure",
true);
153 config_file.
read_bool(
"semantics",
"makeCovisibilityClusters",
false);
159 config_file.
read_bool(
"localisation",
"detect_loopClosure",
true);
162 "localisation",
"config_localiser",
"",
true);
166 config_file.
read_string(
"serialize",
"path_save_pbmap",
"map");
168 config_file.
read_bool(
"serialize",
"save_registered_cloud",
true);
170 "serialize",
"path_save_registered_cloud",
171 "/home/edu/Projects/PbMaps/PbMaps.txt");
176 cout <<
"readConfigFile configPbMap.ini dist_threshold " 181 PbMapMaker::PbMapMaker(
const string& config_file)
182 : cloudViewer(
"Cloud Viewer"),
183 mpPbMapLocaliser(nullptr),
184 m_pbmaker_must_stop(false),
185 m_pbmaker_finished(false)
214 Plane& plane1,
Plane& plane2,
const float distThreshold)
216 float distThres2 = distThreshold * distThreshold;
226 .squaredNorm() < distThres2)
232 .squaredNorm() < distThres2)
240 .squaredNorm() < distThres2)
356 set<unsigned>& observedPlanes,
Plane& observedPlane)
369 for (
size_t i = 0; i < observedPlane.
prog_Nrgb.size(); i++)
375 double rel_areas = observedPlane.area / observedPlane.
prog_area[i];
376 if (rel_areas < area_THRESHOLD_inv ||
389 if (rel_ratios < elongation_THRESHOLD_inv ||
457 if (i == observedPlane.
id)
continue;
466 double rel_areas = observedPlane.area / prevPlane.area;
467 if (rel_areas < area_THRESHOLD_inv ||
478 if (rel_ratios < elongation_THRESHOLD_inv ||
553 observedPlane.
prog_area.push_back(observedPlane.area);
569 cout <<
" ...Watching finished\n";
574 cout <<
"PbMapMaker::saveInfoFiles(...)\n";
596 results_file =
"results/areaRestriction.txt";
597 file.open(results_file.c_str(), ios::app);
602 results_file =
"results/elongRestriction.txt";
603 file.open(results_file.c_str(), ios::app);
610 results_file =
"results/c1c2c3Restriction.txt";
611 file.open(results_file.c_str(), ios::app);
617 results_file =
"results/NrgbRestriction.txt";
618 file.open(results_file.c_str(), ios::app);
623 results_file =
"results/IntensityRestriction.txt";
624 file.open(results_file.c_str(), ios::app);
630 results_file =
"results/ColorRestriction.txt";
631 file.open(results_file.c_str(), ios::app);
637 results_file =
"results/HueRestriction.txt";
638 file.open(results_file.c_str(), ios::app);
647 pcl::PointCloud<PointT>::Ptr& pointCloudPtr_arg, Eigen::Matrix4f& poseKF,
648 double distThreshold,
double angleThreshold,
double minInliersF)
652 unsigned minInliers = minInliersF * pointCloudPtr_arg->size();
655 cout <<
"detectPlanes in a cloud with " << pointCloudPtr_arg->size()
656 <<
" points " << minInliers <<
" minInliers\n";
659 pcl::PointCloud<PointT>::Ptr pointCloudPtr_arg2(
660 new pcl::PointCloud<PointT>);
661 pcl::copyPointCloud(*pointCloudPtr_arg, *pointCloudPtr_arg2);
663 pcl::PointCloud<pcl::PointXYZRGBA>::Ptr alignedCloudPtr(
664 new pcl::PointCloud<pcl::PointXYZRGBA>);
665 pcl::transformPointCloud(*pointCloudPtr_arg, *alignedCloudPtr, poseKF);
671 static pcl::VoxelGrid<pcl::PointXYZRGBA> grid;
672 grid.setLeafSize(0.02, 0.02, 0.02);
673 pcl::PointCloud<pcl::PointXYZRGBA> globalMap;
675 grid.filter(globalMap);
680 pcl::IntegralImageNormalEstimation<PointT, pcl::Normal> ne;
681 ne.setNormalEstimationMethod(ne.COVARIANCE_MATRIX);
682 ne.setMaxDepthChangeFactor(0.02f);
683 ne.setNormalSmoothingSize(10.0f);
684 ne.setDepthDependentSmoothing(
true);
686 pcl::OrganizedMultiPlaneSegmentation<PointT, pcl::Normal, pcl::Label> mps;
687 mps.setMinInliers(minInliers);
688 cout <<
"Params " << minInliers <<
" " << angleThreshold <<
" " 689 << distThreshold << endl;
690 mps.setAngularThreshold(angleThreshold);
691 mps.setDistanceThreshold(distThreshold);
693 pcl::PointCloud<pcl::Normal>::Ptr normal_cloud(
694 new pcl::PointCloud<pcl::Normal>);
695 ne.setInputCloud(pointCloudPtr_arg2);
696 ne.compute(*normal_cloud);
699 double plane_extract_start = pcl::getTime();
701 mps.setInputNormals(normal_cloud);
702 mps.setInputCloud(pointCloudPtr_arg2);
704 std::vector<pcl::PlanarRegion<PointT>,
707 std::vector<pcl::ModelCoefficients> model_coefficients;
708 std::vector<pcl::PointIndices> inlier_indices;
709 pcl::PointCloud<pcl::Label>::Ptr labels(
new pcl::PointCloud<pcl::Label>);
710 std::vector<pcl::PointIndices> label_indices;
711 std::vector<pcl::PointIndices> boundary_indices;
712 mps.segmentAndRefine(
713 regions, model_coefficients, inlier_indices, labels, label_indices,
717 double plane_extract_end = pcl::getTime();
718 std::cout <<
"Plane extraction took " 719 << double(plane_extract_end - plane_extract_start) << std::endl;
722 cout << regions.size() <<
" planes detected\n";
728 vector<Plane> detectedPlanes;
729 for (
size_t i = 0; i < regions.size(); i++)
733 Vector3f centroid = regions[i].getCentroid();
736 poseKF.block(0, 0, 3, 3) * Vector3f(
737 model_coefficients[i].
values[0],
738 model_coefficients[i].
values[1],
739 model_coefficients[i].
values[2]);
746 pcl::ExtractIndices<pcl::PointXYZRGBA> extract;
747 extract.setInputCloud(pointCloudPtr_arg2);
749 boost::make_shared<const pcl::PointIndices>(inlier_indices[i]));
750 extract.setNegative(
false);
754 static pcl::VoxelGrid<pcl::PointXYZRGBA> plane_grid;
755 plane_grid.setLeafSize(0.05, 0.05, 0.05);
756 pcl::PointCloud<pcl::PointXYZRGBA> planeCloud;
758 plane_grid.filter(planeCloud);
762 pcl::PointCloud<pcl::PointXYZRGBA>::Ptr contourPtr(
763 new pcl::PointCloud<pcl::PointXYZRGBA>);
764 contourPtr->points = regions[i].getContour();
765 plane_grid.setLeafSize(0.1, 0.1, 0.1);
766 plane_grid.setInputCloud(contourPtr);
776 cout <<
"Area plane region " << plane.
areaVoxels <<
" of Chull " 784 bool isSamePlane =
false;
785 for (
size_t j = 0; j < detectedPlanes.size(); j++)
797 cout <<
"\tTwo regions support the same plane in the same " 803 if (!isSamePlane) detectedPlanes.push_back(plane);
807 cout << detectedPlanes.size() <<
" Planes detected\n";
816 for (
size_t i = 0; i < detectedPlanes.size(); i++)
819 bool isSamePlane =
false;
822 for (
size_t j = 0; j < numPrevPlanes;
976 cout <<
"Same plane\n";
980 for (
size_t k = j + 1; k < numPrevPlanes;
1012 for (
size_t h = k + 1; h < numPrevPlanes; h++)
1015 for (
size_t h = 0; h < numPrevPlanes; h++)
1017 if (k == h)
continue;
1033 .neighborPlanes.begin();
1040 .neighborPlanes[it->first - 1] =
1051 cout <<
"MERGE TWO PREVIOUS PLANES WHEREBY THE " 1052 "INCORPORATION OF A NEW REGION \n";
1062 detectedPlanes[i].numObservations = 1;
1063 detectedPlanes[i].bFullExtent =
false;
1064 detectedPlanes[i].nFramesAreaIsStable = 0;
1068 detectedPlanes[i].semanticGroup =
1071 .push_back(detectedPlanes[i].
id);
1075 cout <<
"New plane " << detectedPlanes[i].id <<
" area " 1076 << detectedPlanes[i].areaVoxels <<
" of polygon " 1077 << detectedPlanes[i].areaHull << endl;
1092 detectedPlanes[i].neighborPlanes[*it] = 1;
1111 cout <<
"\n\tobservedPlanes: ";
1133 cout <<
"Plane " << observedPlane.
id <<
" color\n" 1156 cout <<
"Verify that the observed planes centers are above the floor\n";
1159 for (set<unsigned>::reverse_iterator it =
observedPlanes.rbegin();
1196 cout <<
"DetectedPlanesCloud finished\n";
1199 updateLock.unlock();
1204 const pcl::visualization::KeyboardEvent& event,
void* viewer_void)
1206 if ((event.getKeySym() ==
"r" ||
event.getKeySym() ==
"R") &&
1218 Plane& plane1,
Plane& plane2,
const float& cosAngleThreshold,
1219 const float& distThreshold,
const float& proxThreshold)
1222 if (plane1.
v3normal.dot(plane2.
v3normal) < cosAngleThreshold)
return false;
1233 float thres_max_dist =
1236 if (fabs(dist_normal) >
1268 static pcl::VoxelGrid<pcl::PointXYZRGBA> merge_grid;
1269 merge_grid.setLeafSize(0.05, 0.05, 0.05);
1270 pcl::PointCloud<pcl::PointXYZRGBA> mergeCloud;
1272 merge_grid.filter(mergeCloud);
1295 unsigned char red[10] = {255, 0, 0, 255, 255, 0, 255, 204, 0, 255};
1296 unsigned char grn[10] = {0, 255, 0, 255, 0, 255, 160, 51, 128, 222};
1297 unsigned char blu[10] = {0, 0, 255, 0, 255, 255, 0, 204, 0, 173};
1299 double ared[10] = {1.0, 0, 0, 1.0, 1.0, 0, 1.0, 0.8, 0, 1.0};
1300 double agrn[10] = {0, 1.0, 0, 1.0, 0, 1.0, 0.6, 0.2, 0.5, 0.9};
1301 double ablu[10] = {0, 0, 1.0, 0, 1.0, 1.0, 0, 0.8, 0, 0.7};
1307 std::this_thread::sleep_for(10ms);
1316 viz.removeAllShapes();
1317 viz.removeAllPointClouds();
1409 if (!viz.updatePointCloud(
1416 name,
"PointCloud size %u",
1418 viz.addText(
name, 10, 20);
1431 sprintf(
name,
"normal_%u", static_cast<unsigned>(i));
1432 pcl::PointXYZ pt1, pt2;
1434 pt1 = pcl::PointXYZ(
1437 pt2 = pcl::PointXYZ(
1487 sprintf(
name,
"plane_%02u", static_cast<unsigned>(i));
1523 pcl::visualization::PointCloudColorHandlerCustom<PointT>
1544 viz.setPointCloudRenderingProperties(
1545 pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 10,
1619 it->first, it->second, 0.3, 0.9, 0.9, 0.9,
1632 size_t numPrevKFs = 0;
1633 size_t minGrowPlanes = 5;
1638 std::this_thread::sleep_for(10ms);
1653 int size_partition =
1655 cout <<
"PARTITION SIZE " << size_partition << endl;
1656 assert(size_partition < 2);
1677 updateLock.unlock();
1684 cout <<
"Waiting for PbMapMaker thread to die.." << endl;
1693 cout <<
"\n\n\nPbMapMaker destructor called -> Save color information to " 1702 cout <<
" .. PbMapMaker has died." << endl;
Eigen::Vector3f diffPoints(const POINT &P1, const POINT &P2)
PlaneInferredInfo * mpPlaneInferInfo
bool read_bool(const std::string §ion, const std::string &name, bool defaultValue, bool failIfNotFound=false) const
std::vector< double > prog_area
std::vector< Eigen::Vector3f > prog_Nrgb
std::map< std::string, pcl::PointXYZ > foundPlaces
float read_float(const std::string §ion, const std::string &name, float defaultValue, bool failIfNotFound=false) const
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)
This class allows loading and storing values and vectors of different types from ".ini" files easily.
void checkProximity(Plane &plane, float proximity)
void serializePbMap(std::string path)
void keyboardEventOccurred(const pcl::visualization::KeyboardEvent &event, void *viewer_void)
boost::mutex mtx_pbmap_busy
std::string read_string(const std::string §ion, const std::string &name, const std::string &defaultValue, bool failIfNotFound=false) const
for(ctr=DCTSIZE;ctr > 0;ctr--)
void viz_cb(pcl::visualization::PCLVisualizer &viz)
Eigen::Vector3f v3colorNrgb
! Radiometric description
float intensity_threshold
void watchProperties(std::set< unsigned > &observedPlanes, Plane &observedPlane)
double dist_THRESHOLDFull = 1.2; double dist_THRESHOLDFull_inv = 1/dist_THRESHOLDFull; ...
struct config_pbmap configPbMap
void calcElongationAndPpalDir()
A class used to infer some semantic meaning to the planes of a PbMap.
int read_int(const std::string §ion, const std::string &name, int defaultValue, bool failIfNotFound=false) const
std::string path_save_registered_cloud
std::map< unsigned, std::vector< unsigned > > groups
std::vector< Eigen::Vector3f > prog_C1C2C3
pcl::PointCloud< pcl::PointXYZRGBA >::Ptr alignedModelPtr
std::vector< float > prog_intensity
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()
std::vector< double > prog_elongation
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)
std::vector< std::vector< float > > prog_hist_H
void detectPlanesCloud(pcl::PointCloud< PointT >::Ptr &pointCloudPtr_arg, Eigen::Matrix4f &poseKF, double distThreshold, double angleThreshold, double minInliersF)
int evalPartition(std::set< unsigned > &observedPlanes)
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.
std::vector< float > hist_H
GLuint const GLchar * name
std::vector< frameRGBDandPose > frameQueue
#define ASSERT_FILE_EXISTS_(FIL)
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
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...
Eigen::Vector3f v3colorC1C2C3
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)