Galaxis Codebase  1.0.0
Team Galaxis software stack for the Carolo Cup 2023 - ROS2 based software
PCLObjectDetector.cpp
Go to the documentation of this file.
1 #include "PCLObjectDetector.hpp"
2 
3 #include <utils/logger.hpp>
4 
5 using namespace galaxis::utils;
6 
7 std::shared_ptr<std::vector<pcl::PointCloud<pcl::PointXYZ>::Ptr>> EuclideanDetector::cluster_data(pclPtrType p_pclPtr, std::vector<Object>& p_objectsVecRef, float clusterTolerance, int minClusterSize, int maxClusterSize) const {
8 
9  auto pointCloudPtrVectorSPtr = std::make_shared<std::vector<pcl::PointCloud<pcl::PointXYZ>::Ptr>>();
10 
11  // check if filtered cloud is empty to skip unnecessary computation
12  if(p_pclPtr->size() == 0) return pointCloudPtrVectorSPtr;
13 
14  pcl::search::KdTree<pcl::PointXYZ>::Ptr tree(new pcl::search::KdTree<pcl::PointXYZ>);
15  tree->setInputCloud(p_pclPtr);
16 
17  std::vector<pcl::PointIndices> clusterIndices;
18  pcl::EuclideanClusterExtraction<pcl::PointXYZ> ec;
19  ec.setClusterTolerance(clusterTolerance); // m
20  ec.setMinClusterSize(minClusterSize);
21  ec.setMaxClusterSize(maxClusterSize);
22  ec.setSearchMethod(tree);
23  ec.setInputCloud(p_pclPtr);
24  ec.extract(clusterIndices);
25 
26 
27  float sizeX, sizeY, sizeZ;
28  for(std::vector<pcl::PointIndices>::const_iterator it = clusterIndices.begin(); it != clusterIndices.end(); ++it) {
29  pcl::PointCloud<pcl::PointXYZ>::Ptr cloudClusterPtr(new pcl::PointCloud<pcl::PointXYZ>);
30 
31  // create a sub cloud with all the indices extracted above
32  for(std::vector<int>::const_iterator pit = it->indices.begin(); pit != it->indices.end(); ++pit) {
33  cloudClusterPtr->points.push_back(p_pclPtr->points[*pit]);
34  }
35 
36  // post processing
37  pcl::PointXYZ minDimensions;
38  pcl::PointXYZ maxDimensions;
39  pcl::getMinMax3D(*cloudClusterPtr, minDimensions, maxDimensions);
40 
41  sizeX = std::fabs(maxDimensions.x - minDimensions.x);
42  sizeY = std::fabs(maxDimensions.y - minDimensions.y);
43  sizeZ = std::fabs(maxDimensions.z - minDimensions.z);
44 
45  if(cloudClusterPtr->size() < m_postProcessingClusterSizeMin) {
46  log_debug("[RealSense] Object too small (min cluster points)");
47  continue;
48  }
49 
50  if(cloudClusterPtr->size() > m_postProcessingClusterSizeMax) {
51  log_debug("[RealSense] Object too large (max cluster points)");
52  continue;
53  }
54 
55  if(sizeX > m_maxSizeX) {
56  log_debug("[RealSense] Object too large (x)");
57  continue;
58  }
59  if (sizeY > m_maxSizeY) {
60  log_debug("[RealSense] Object too large (y)");
61  continue;
62  }
63  if(sizeZ > m_maxSizeZ) {
64  log_debug("[RealSense] Object too large (z)");
65  continue;
66  }
67 
68  if(sizeX < m_minSizeX) {
69  log_debug("[RealSense] Object too small (x)");
70  continue;
71  }
72  if (sizeY < m_minSizeY) {
73  log_debug("[RealSense] Object too small (y)");
74  continue;
75  }
76  if(sizeZ < m_minSizeZ) {
77  log_debug("[RealSense] Object too small (z)");
78  continue;
79  }
80 
81  pcl::PointXYZ centerPoint;
82  // get centerpoint and MinMax dimensions
83  int centroidReturnValue = pcl::computeCentroid(*cloudClusterPtr, centerPoint);
84 
85  // store object in return vector
86  Object foundObject;
87  foundObject.set_max_dimensions(maxDimensions);
88  foundObject.set_min_dimensions(minDimensions);
89  foundObject.set_center_point(centerPoint);
90  foundObject.size = cloudClusterPtr->size();
91  p_objectsVecRef.push_back(foundObject);
92 
93  pointCloudPtrVectorSPtr->push_back(cloudClusterPtr);
94  }
95 
96  log_debug("Objects Detected: ", p_objectsVecRef.size());
97 
98  return pointCloudPtrVectorSPtr;
99 }
100 
101 void PCLObjectDetector::downsampling(pclPtrType p_inputCloudPtr, pclPtrType p_outputCloudPtr, float p_leafSize) {
102  pcl::VoxelGrid<pcl::PointXYZ> sor;
103  sor.setInputCloud(p_inputCloudPtr);
104  sor.setLeafSize(p_leafSize, p_leafSize, p_leafSize);
105  sor.filter(*p_outputCloudPtr);
106 }
107 
108 void PCLObjectDetector::passThroughFilter(pclPtrType p_inputCloudPtr, pclPtrType p_outputCloudPtr, float y_min, float y_max) {
109  // pcl::PassThrough<pcl::PointXYZ> pass_z;
110  // pass_z.setInputCloud(p_inputCloudPtr);
111  // pass_z.setFilterFieldName("z");
112  // pass_z.setFilterLimits(0.18, 2.0);
113  // pass_z.filter(*p_outputCloudPtr);
114 
115  // pcl::PassThrough<pcl::PointXYZ> pass_y;
116  // pass_y.setInputCloud(p_inputCloudPtr);
117  // pass_y.setFilterFieldName("y");
118  // pass_y.setFilterLimits(y_min, y_max);
119  // pass_y.filter(*p_outputCloudPtr);
120 }
PCLObjectDetector::downsampling
void downsampling(pclPtrType p_inputCloudPtr, pclPtrType p_outputCloudPtr, float p_leafSize)
Definition: PCLObjectDetector.cpp:101
PCLObjectDetector.hpp
pclPtrType
pcl::PointCloud< pcl::PointXYZ >::Ptr pclPtrType
Definition: PCLObjectDetector.hpp:22
Object
Definition: Object.hpp:7
Object::set_min_dimensions
void set_min_dimensions(pcl::PointXYZ &p_rightmostPoint)
Definition: Object.cpp:23
Object::set_max_dimensions
void set_max_dimensions(pcl::PointXYZ &p_leftmostPoint)
Definition: Object.cpp:19
PCLObjectDetector::passThroughFilter
void passThroughFilter(pclPtrType p_inputCloudPtr, pclPtrType p_outputCloudPtr, float y_min, float y_max)
Definition: PCLObjectDetector.cpp:108
EuclideanDetector::cluster_data
std::shared_ptr< std::vector< pcl::PointCloud< pcl::PointXYZ >::Ptr > > cluster_data(pclPtrType p_pclPtr, std::vector< Object > &p_objectsVecRef, float clusterTolerance, int minClusterSize, int maxClusterSize) const
Definition: PCLObjectDetector.cpp:7
logger.hpp
galaxis::utils
Definition: clock.hpp:5
Object::set_center_point
void set_center_point(pcl::PointXYZ &p_centerPoint)
Definition: Object.cpp:15
Object::size
double size
Definition: Object.hpp:18
galaxis::utils::log_debug
void log_debug(const Args &... args)
Definition: logger.hpp:62