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>
41 #define WATCH_BINARY 0
45 using namespace Eigen;
53 assert(hist1.size() == hist2.size());
55 double BhattachDist_aux = 0.0;
56 for (
unsigned i = 0; i < hist1.size(); i++)
57 BhattachDist_aux += sqrt(hist1[i] * hist2[i]);
59 BhattachDist = sqrt(1 - BhattachDist_aux);
124 "plane_segmentation",
"dist_threshold", 0.04,
true);
126 "plane_segmentation",
"angle_threshold", 0.069812,
true);
128 "plane_segmentation",
"minInliersRate", 0.01,
true);
132 config_file.
read_bool(
"map_construction",
"use_color",
false);
134 config_file.
read_float(
"map_construction",
"color_threshold", 0.09);
136 "map_construction",
"intensity_threshold", 255.0);
138 config_file.
read_float(
"unary",
"hue_threshold", 0.25);
140 "map_construction",
"proximity_neighbor_planes", 1.0);
142 config_file.
read_int(
"map_construction",
"graph_mode", 1);
144 "map_construction",
"max_cos_normal", 0.9848,
true);
146 "map_construction",
"max_dist_center_plane", 0.1,
true);
148 config_file.
read_float(
"map_construction",
"proximity_threshold", 0.15);
152 config_file.
read_bool(
"semantics",
"inferStructure",
true);
154 config_file.
read_bool(
"semantics",
"makeCovisibilityClusters",
false);
160 config_file.
read_bool(
"localisation",
"detect_loopClosure",
true);
163 "localisation",
"config_localiser",
"",
true);
167 config_file.
read_string(
"serialize",
"path_save_pbmap",
"map");
169 config_file.
read_bool(
"serialize",
"save_registered_cloud",
true);
171 "serialize",
"path_save_registered_cloud",
172 "/home/edu/Projects/PbMaps/PbMaps.txt");
177 cout <<
"readConfigFile configPbMap.ini dist_threshold "
182 PbMapMaker::PbMapMaker(
const string& config_file)
183 : cloudViewer(
"Cloud Viewer"),
184 mpPbMapLocaliser(nullptr),
185 m_pbmaker_must_stop(false),
186 m_pbmaker_finished(false)
215 Plane& plane1,
Plane& plane2,
const float distThreshold)
217 float distThres2 = distThreshold * distThreshold;
227 .squaredNorm() < distThres2)
233 .squaredNorm() < distThres2)
241 .squaredNorm() < distThres2)
357 set<unsigned>& observedPlanes,
Plane& observedPlane)
370 for (
size_t i = 0; i < observedPlane.
prog_Nrgb.size(); i++)
376 double rel_areas = observedPlane.area / observedPlane.
prog_area[i];
377 if (rel_areas < area_THRESHOLD_inv ||
390 if (rel_ratios < elongation_THRESHOLD_inv ||
458 if (i == observedPlane.
id)
continue;
469 double rel_areas = observedPlane.area / prevPlane.area;
470 if (rel_areas < area_THRESHOLD_inv ||
481 if (rel_ratios < elongation_THRESHOLD_inv ||
556 observedPlane.
prog_area.push_back(observedPlane.area);
572 cout <<
" ...Watching finished\n";
577 cout <<
"PbMapMaker::saveInfoFiles(...)\n";
599 results_file =
"results/areaRestriction.txt";
600 file.open(results_file.c_str(), ios::app);
605 results_file =
"results/elongRestriction.txt";
606 file.open(results_file.c_str(), ios::app);
613 results_file =
"results/c1c2c3Restriction.txt";
614 file.open(results_file.c_str(), ios::app);
620 results_file =
"results/NrgbRestriction.txt";
621 file.open(results_file.c_str(), ios::app);
626 results_file =
"results/IntensityRestriction.txt";
627 file.open(results_file.c_str(), ios::app);
633 results_file =
"results/ColorRestriction.txt";
634 file.open(results_file.c_str(), ios::app);
640 results_file =
"results/HueRestriction.txt";
641 file.open(results_file.c_str(), ios::app);
650 pcl::PointCloud<PointT>::Ptr& pointCloudPtr_arg, Eigen::Matrix4f& poseKF,
651 double distThreshold,
double angleThreshold,
double minInliersF)
655 unsigned minInliers = minInliersF * pointCloudPtr_arg->size();
658 cout <<
"detectPlanes in a cloud with " << pointCloudPtr_arg->size()
659 <<
" points " << minInliers <<
" minInliers\n";
662 pcl::PointCloud<PointT>::Ptr pointCloudPtr_arg2(
663 new pcl::PointCloud<PointT>);
664 pcl::copyPointCloud(*pointCloudPtr_arg, *pointCloudPtr_arg2);
666 pcl::PointCloud<pcl::PointXYZRGBA>::Ptr alignedCloudPtr(
667 new pcl::PointCloud<pcl::PointXYZRGBA>);
668 pcl::transformPointCloud(*pointCloudPtr_arg, *alignedCloudPtr, poseKF);
674 static pcl::VoxelGrid<pcl::PointXYZRGBA> grid;
675 grid.setLeafSize(0.02, 0.02, 0.02);
676 pcl::PointCloud<pcl::PointXYZRGBA> globalMap;
678 grid.filter(globalMap);
683 pcl::IntegralImageNormalEstimation<PointT, pcl::Normal> ne;
684 ne.setNormalEstimationMethod(ne.COVARIANCE_MATRIX);
685 ne.setMaxDepthChangeFactor(0.02f);
686 ne.setNormalSmoothingSize(10.0f);
687 ne.setDepthDependentSmoothing(
true);
689 pcl::OrganizedMultiPlaneSegmentation<PointT, pcl::Normal, pcl::Label> mps;
690 mps.setMinInliers(minInliers);
691 cout <<
"Params " << minInliers <<
" " << angleThreshold <<
" "
692 << distThreshold << endl;
693 mps.setAngularThreshold(angleThreshold);
694 mps.setDistanceThreshold(distThreshold);
696 pcl::PointCloud<pcl::Normal>::Ptr normal_cloud(
697 new pcl::PointCloud<pcl::Normal>);
698 ne.setInputCloud(pointCloudPtr_arg2);
699 ne.compute(*normal_cloud);
702 double plane_extract_start = pcl::getTime();
704 mps.setInputNormals(normal_cloud);
705 mps.setInputCloud(pointCloudPtr_arg2);
707 std::vector<pcl::PlanarRegion<PointT>,
708 aligned_allocator<pcl::PlanarRegion<PointT>>>
710 std::vector<pcl::ModelCoefficients> model_coefficients;
711 std::vector<pcl::PointIndices> inlier_indices;
712 pcl::PointCloud<pcl::Label>::Ptr labels(
new pcl::PointCloud<pcl::Label>);
713 std::vector<pcl::PointIndices> label_indices;
714 std::vector<pcl::PointIndices> boundary_indices;
715 mps.segmentAndRefine(
716 regions, model_coefficients, inlier_indices, labels, label_indices,
720 double plane_extract_end = pcl::getTime();
721 std::cout <<
"Plane extraction took "
722 << double(plane_extract_end - plane_extract_start) << std::endl;
725 cout << regions.size() <<
" planes detected\n";
731 vector<Plane> detectedPlanes;
732 for (
size_t i = 0; i < regions.size(); i++)
736 Vector3f centroid = regions[i].getCentroid();
739 poseKF.block(0, 0, 3, 3) * Vector3f(
740 model_coefficients[i].
values[0],
741 model_coefficients[i].
values[1],
742 model_coefficients[i].
values[2]);
749 pcl::ExtractIndices<pcl::PointXYZRGBA> extract;
750 extract.setInputCloud(pointCloudPtr_arg2);
752 boost::make_shared<const pcl::PointIndices>(inlier_indices[i]));
753 extract.setNegative(
false);
757 static pcl::VoxelGrid<pcl::PointXYZRGBA> plane_grid;
758 plane_grid.setLeafSize(0.05, 0.05, 0.05);
759 pcl::PointCloud<pcl::PointXYZRGBA> planeCloud;
761 plane_grid.filter(planeCloud);
765 pcl::PointCloud<pcl::PointXYZRGBA>::Ptr contourPtr(
766 new pcl::PointCloud<pcl::PointXYZRGBA>);
767 contourPtr->points = regions[i].getContour();
768 plane_grid.setLeafSize(0.1, 0.1, 0.1);
769 plane_grid.setInputCloud(contourPtr);
779 cout <<
"Area plane region " << plane.
areaVoxels <<
" of Chull "
787 bool isSamePlane =
false;
788 for (
size_t j = 0; j < detectedPlanes.size(); j++)
800 cout <<
"\tTwo regions support the same plane in the same "
806 if (!isSamePlane) detectedPlanes.push_back(plane);
810 cout << detectedPlanes.size() <<
" Planes detected\n";
819 for (
size_t i = 0; i < detectedPlanes.size(); i++)
822 bool isSamePlane =
false;
825 for (
size_t j = 0; j < numPrevPlanes;
979 cout <<
"Same plane\n";
983 for (
size_t k = j + 1; k < numPrevPlanes;
1015 for (
size_t h = k + 1; h < numPrevPlanes; h++)
1018 for (
size_t h = 0; h < numPrevPlanes; h++)
1020 if (k == h)
continue;
1036 .neighborPlanes.begin();
1043 .neighborPlanes[it->first - 1] =
1054 cout <<
"MERGE TWO PREVIOUS PLANES WHEREBY THE "
1055 "INCORPORATION OF A NEW REGION \n";
1065 detectedPlanes[i].numObservations = 1;
1066 detectedPlanes[i].bFullExtent =
false;
1067 detectedPlanes[i].nFramesAreaIsStable = 0;
1071 detectedPlanes[i].semanticGroup =
1074 .push_back(detectedPlanes[i].
id);
1078 cout <<
"New plane " << detectedPlanes[i].id <<
" area "
1079 << detectedPlanes[i].areaVoxels <<
" of polygon "
1080 << detectedPlanes[i].areaHull << endl;
1095 detectedPlanes[i].neighborPlanes[*it] = 1;
1114 cout <<
"\n\tobservedPlanes: ";
1136 cout <<
"Plane " << observedPlane.
id <<
" color\n"
1159 cout <<
"Verify that the observed planes centers are above the floor\n";
1162 for (set<unsigned>::reverse_iterator it =
observedPlanes.rbegin();
1199 cout <<
"DetectedPlanesCloud finished\n";
1202 updateLock.unlock();
1207 const pcl::visualization::KeyboardEvent& event,
void* viewer_void)
1209 if ((event.getKeySym() ==
"r" || event.getKeySym() ==
"R") &&
1221 Plane& plane1,
Plane& plane2,
const float& cosAngleThreshold,
1222 const float& distThreshold,
const float& proxThreshold)
1225 if (plane1.
v3normal.dot(plane2.
v3normal) < cosAngleThreshold)
return false;
1236 float thres_max_dist =
1239 if (fabs(dist_normal) >
1271 static pcl::VoxelGrid<pcl::PointXYZRGBA> merge_grid;
1272 merge_grid.setLeafSize(0.05, 0.05, 0.05);
1273 pcl::PointCloud<pcl::PointXYZRGBA> mergeCloud;
1275 merge_grid.filter(mergeCloud);
1298 unsigned char red[10] = {255, 0, 0, 255, 255, 0, 255, 204, 0, 255};
1299 unsigned char grn[10] = {0, 255, 0, 255, 0, 255, 160, 51, 128, 222};
1300 unsigned char blu[10] = {0, 0, 255, 0, 255, 255, 0, 204, 0, 173};
1302 double ared[10] = {1.0, 0, 0, 1.0, 1.0, 0, 1.0, 0.8, 0, 1.0};
1303 double agrn[10] = {0, 1.0, 0, 1.0, 0, 1.0, 0.6, 0.2, 0.5, 0.9};
1304 double ablu[10] = {0, 0, 1.0, 0, 1.0, 1.0, 0, 0.8, 0, 0.7};
1310 std::this_thread::sleep_for(10ms);
1319 viz.removeAllShapes();
1320 viz.removeAllPointClouds();
1412 if (!viz.updatePointCloud(
1419 name,
"PointCloud size %u",
1421 viz.addText(
name, 10, 20);
1434 sprintf(
name,
"normal_%u",
static_cast<unsigned>(i));
1435 pcl::PointXYZ pt1, pt2;
1437 pt1 = pcl::PointXYZ(
1440 pt2 = pcl::PointXYZ(
1490 sprintf(
name,
"plane_%02u",
static_cast<unsigned>(i));
1526 pcl::visualization::PointCloudColorHandlerCustom<PointT>
1547 viz.setPointCloudRenderingProperties(
1548 pcl::visualization::PCL_VISUALIZER_POINT_SIZE, 10,
1622 it->first, it->second, 0.3, 0.9, 0.9, 0.9,
1635 size_t numPrevKFs = 0;
1636 size_t minGrowPlanes = 5;
1641 std::this_thread::sleep_for(10ms);
1656 int size_partition =
1658 cout <<
"PARTITION SIZE " << size_partition << endl;
1659 assert(size_partition < 2);
1680 updateLock.unlock();
1687 cout <<
"Waiting for PbMapMaker thread to die.." << endl;
1696 cout <<
"\n\n\nPbMapMaker destructor called -> Save color information to "
1705 cout <<
" .. PbMapMaker has died." << endl;