40 #ifndef PCL_SEGMENTATION_IMPL_ORGANIZED_CONNECTED_COMPONENT_SEGMENTATION_H_
41 #define PCL_SEGMENTATION_IMPL_ORGANIZED_CONNECTED_COMPONENT_SEGMENTATION_H_
43 #include <pcl/segmentation/organized_connected_component_segmentation.h>
52 template<
typename Po
intT,
typename Po
intLT>
void
55 boundary_indices.
indices.clear ();
56 int curr_idx = start_idx;
57 int curr_x = start_idx % labels->width;
58 int curr_y = start_idx / labels->width;
59 unsigned label = (*labels)[start_idx].label;
62 Neighbor directions [8] = {Neighbor(-1, 0, -1),
63 Neighbor(-1, -1, -labels->width - 1),
64 Neighbor( 0, -1, -labels->width ),
65 Neighbor( 1, -1, -labels->width + 1),
67 Neighbor( 1, 1, labels->width + 1),
68 Neighbor( 0, 1, labels->width ),
69 Neighbor(-1, 1, labels->width - 1)};
76 for (
unsigned dIdx = 0; dIdx < 8; ++dIdx)
78 x = curr_x + directions [dIdx].d_x;
79 y = curr_y + directions [dIdx].d_y;
80 index = curr_idx + directions [dIdx].d_index;
81 if (x >= 0 && x <
static_cast<int>(labels->width) && y >= 0 && y <
static_cast<int>(labels->height) && (*labels)[index].label != label)
92 boundary_indices.
indices.push_back (start_idx);
96 for (
unsigned dIdx = 1; dIdx <= 8; ++dIdx)
98 nIdx = (direction + dIdx) & 7;
100 x = curr_x + directions [nIdx].d_x;
101 y = curr_y + directions [nIdx].d_y;
102 index = curr_idx + directions [nIdx].d_index;
103 if (x >= 0 && x <
static_cast<int>(labels->width) && y >= 0 && y < static_cast<int>(labels->height) && (*labels)[index].label == label)
108 direction = (nIdx + 4) & 7;
109 curr_idx += directions [nIdx].d_index;
110 curr_x += directions [nIdx].d_x;
111 curr_y += directions [nIdx].d_y;
112 boundary_indices.
indices.push_back(curr_idx);
113 }
while ( curr_idx != start_idx);
117 template<
typename Po
intT,
typename Po
intLT>
void
120 std::vector<unsigned> run_ids;
122 unsigned invalid_label = std::numeric_limits<unsigned>::max ();
124 invalid_pt.label = std::numeric_limits<unsigned>::max ();
125 labels.
resize (input_->size (), invalid_pt);
126 labels.
width = input_->width;
127 labels.
height = input_->height;
128 std::size_t clust_id = 0;
131 if (std::isfinite ((*input_)[0].x))
133 labels[0].label = clust_id++;
138 for (
int colIdx = 1; colIdx < static_cast<int> (input_->width); ++colIdx)
140 if (!std::isfinite ((*input_)[colIdx].x))
142 if (compare_->compare (colIdx, colIdx - 1 ))
144 labels[colIdx].label = labels[colIdx - 1].label;
148 labels[colIdx].label = clust_id++;
149 run_ids.
push_back (labels[colIdx].label );
154 unsigned int current_row = input_->width;
155 unsigned int previous_row = 0;
156 for (std::size_t rowIdx = 1; rowIdx < input_->height; ++rowIdx, previous_row = current_row, current_row += input_->width)
159 if (std::isfinite ((*input_)[current_row].x))
161 if (compare_->compare (current_row, previous_row))
163 labels[current_row].label = labels[previous_row].label;
167 labels[current_row].label = clust_id++;
168 run_ids.
push_back (labels[current_row].label);
173 for (
int colIdx = 1; colIdx < static_cast<int> (input_->width); ++colIdx)
175 if (std::isfinite ((*input_)[current_row + colIdx].x))
177 if (compare_->compare (current_row + colIdx, current_row + colIdx - 1))
179 labels[current_row + colIdx].label = labels[current_row + colIdx - 1].label;
181 if (compare_->compare (current_row + colIdx, previous_row + colIdx) )
183 if (labels[current_row + colIdx].label == invalid_label)
184 labels[current_row + colIdx].label = labels[previous_row + colIdx].label;
185 else if (labels[previous_row + colIdx].label != invalid_label)
187 unsigned root1 = findRoot (run_ids, labels[current_row + colIdx].label);
188 unsigned root2 = findRoot (run_ids, labels[previous_row + colIdx].label);
191 run_ids[root2] = root1;
193 run_ids[root1] = root2;
197 if (labels[current_row + colIdx].label == invalid_label)
199 labels[current_row + colIdx].label = clust_id++;
200 run_ids.
push_back (labels[current_row + colIdx].label);
207 std::vector<unsigned> map (clust_id);
208 std::size_t max_id = 0;
209 for (std::size_t runIdx = 0; runIdx < run_ids.size (); ++runIdx)
212 if (run_ids[runIdx] == runIdx)
213 map[runIdx] = max_id++;
215 map [runIdx] = map [findRoot (run_ids, runIdx)];
218 label_indices.resize (max_id + 1);
219 for (std::size_t idx = 0; idx < input_->size (); idx++)
221 if (labels[idx].label != invalid_label)
223 labels[idx].label = map[labels[idx].label];
224 label_indices[labels[idx].label].indices.
push_back (idx);
229 #define PCL_INSTANTIATE_OrganizedConnectedComponentSegmentation(T,LT) template class PCL_EXPORTS pcl::OrganizedConnectedComponentSegmentation<T,LT>;
static void findLabeledRegionBoundary(int start_idx, PointCloudLPtr labels, pcl::PointIndices &boundary_indices)
Find the boundary points / contour of a connected component.
typename PointCloudL::Ptr PointCloudLPtr
void segment(pcl::PointCloud< PointLT > &labels, std::vector< pcl::PointIndices > &label_indices) const
Perform the connected component segmentation.
PointCloud represents the base class in PCL for storing collections of 3D points.
void push_back(const PointT &pt)
Insert a new point in the cloud, at the end of the container.
void resize(std::size_t count)
Resizes the container to contain count elements.
std::uint32_t width
The point cloud width (if organized as an image-structure).
std::uint32_t height
The point cloud height (if organized as an image-structure).