Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040 #ifndef PCL_SEGMENTATION_IMPL_ORGANIZED_CONNECTED_COMPONENT_SEGMENTATION_H_
00041 #define PCL_SEGMENTATION_IMPL_ORGANIZED_CONNECTED_COMPONENT_SEGMENTATION_H_
00042
00043 #include <pcl/segmentation/organized_connected_component_segmentation.h>
00044
00051
00052 template<typename PointT, typename PointLT> void
00053 pcl::OrganizedConnectedComponentSegmentation<PointT, PointLT>::findLabeledRegionBoundary (int start_idx, PointCloudLPtr labels, pcl::PointIndices& boundary_indices)
00054 {
00055 boundary_indices.indices.clear ();
00056 int curr_idx = start_idx;
00057 int curr_x = start_idx % labels->width;
00058 int curr_y = start_idx / labels->width;
00059 unsigned label = labels->points[start_idx].label;
00060
00061
00062 Neighbor directions [8] = {Neighbor(-1, 0, -1),
00063 Neighbor(-1, -1, -labels->width - 1),
00064 Neighbor( 0, -1, -labels->width ),
00065 Neighbor( 1, -1, -labels->width + 1),
00066 Neighbor( 1, 0, 1),
00067 Neighbor( 1, 1, labels->width + 1),
00068 Neighbor( 0, 1, labels->width ),
00069 Neighbor(-1, 1, labels->width - 1)};
00070
00071
00072 int direction = -1;
00073 int x;
00074 int y;
00075 int index;
00076 for (unsigned dIdx = 0; dIdx < 8; ++dIdx)
00077 {
00078 x = curr_x + directions [dIdx].d_x;
00079 y = curr_y + directions [dIdx].d_y;
00080 index = curr_idx + directions [dIdx].d_index;
00081 if (x >= 0 && x < int(labels->width) && y >= 0 && y < int(labels->height) && labels->points[index].label != label)
00082 {
00083 direction = dIdx;
00084 break;
00085 }
00086 }
00087
00088
00089 if (direction == -1)
00090 return;
00091
00092 boundary_indices.indices.push_back (start_idx);
00093
00094 do {
00095 unsigned nIdx;
00096 for (unsigned dIdx = 1; dIdx <= 8; ++dIdx)
00097 {
00098 nIdx = (direction + dIdx) & 7;
00099
00100 x = curr_x + directions [nIdx].d_x;
00101 y = curr_y + directions [nIdx].d_y;
00102 index = curr_idx + directions [nIdx].d_index;
00103 if (x >= 0 && y < int(labels->width) && y >= 0 && y < int(labels->height) && labels->points[index].label == label)
00104 break;
00105 }
00106
00107
00108 direction = (nIdx + 4) & 7;
00109 curr_idx += directions [nIdx].d_index;
00110 curr_x += directions [nIdx].d_x;
00111 curr_y += directions [nIdx].d_y;
00112 boundary_indices.indices.push_back(curr_idx);
00113 } while ( curr_idx != start_idx);
00114 }
00115
00117 template<typename PointT, typename PointLT> void
00118 pcl::OrganizedConnectedComponentSegmentation<PointT, PointLT>::segment (pcl::PointCloud<PointLT>& labels, std::vector<pcl::PointIndices>& label_indices) const
00119 {
00120 std::vector<unsigned> run_ids;
00121
00122 unsigned invalid_label = std::numeric_limits<unsigned>::max ();
00123 pcl::Label invalid_pt;
00124 invalid_pt.label = std::numeric_limits<unsigned>::max ();
00125 labels.points.resize (input_->points.size (), invalid_pt);
00126 labels.width = input_->width;
00127 labels.height = input_->height;
00128 unsigned int clust_id = 0;
00129
00130
00131 if (pcl_isfinite (input_->points[0].x))
00132 {
00133 labels[0].label = clust_id++;
00134 run_ids.push_back (labels[0].label );
00135 }
00136
00137
00138 for (int colIdx = 1; colIdx < static_cast<int> (input_->width); ++colIdx)
00139 {
00140 if (!pcl_isfinite (input_->points[colIdx].x))
00141 continue;
00142 else if (compare_->compare (colIdx, colIdx - 1 ))
00143 {
00144 labels[colIdx].label = labels[colIdx - 1].label;
00145 }
00146 else
00147 {
00148 labels[colIdx].label = clust_id++;
00149 run_ids.push_back (labels[colIdx].label );
00150 }
00151 }
00152
00153
00154 unsigned int current_row = input_->width;
00155 unsigned int previous_row = 0;
00156 for (size_t rowIdx = 1; rowIdx < input_->height; ++rowIdx, previous_row = current_row, current_row += input_->width)
00157 {
00158
00159 if (pcl_isfinite (input_->points[current_row].x))
00160 {
00161 if (compare_->compare (current_row, previous_row))
00162 {
00163 labels[current_row].label = labels[previous_row].label;
00164 }
00165 else
00166 {
00167 labels[current_row].label = clust_id++;
00168 run_ids.push_back (labels[current_row].label);
00169 }
00170 }
00171
00172
00173 for (int colIdx = 1; colIdx < static_cast<int> (input_->width); ++colIdx)
00174 {
00175 if (pcl_isfinite (input_->points[current_row + colIdx].x))
00176 {
00177 if (compare_->compare (current_row + colIdx, current_row + colIdx - 1))
00178 {
00179 labels[current_row + colIdx].label = labels[current_row + colIdx - 1].label;
00180 }
00181 if (compare_->compare (current_row + colIdx, previous_row + colIdx) )
00182 {
00183 if (labels[current_row + colIdx].label == invalid_label)
00184 labels[current_row + colIdx].label = labels[previous_row + colIdx].label;
00185 else
00186 {
00187 unsigned root1 = findRoot (run_ids, labels[current_row + colIdx].label);
00188 unsigned root2 = findRoot (run_ids, labels[previous_row + colIdx].label);
00189
00190 if (root1 < root2)
00191 run_ids[root2] = root1;
00192 else
00193 run_ids[root1] = root2;
00194 }
00195 }
00196
00197 if (labels[current_row + colIdx].label == invalid_label)
00198 {
00199 labels[current_row + colIdx].label = clust_id++;
00200 run_ids.push_back (labels[current_row + colIdx].label);
00201 }
00202
00203 }
00204 }
00205 }
00206
00207 std::vector<unsigned> map (clust_id);
00208 unsigned max_id = 0;
00209 for (unsigned runIdx = 0; runIdx < run_ids.size (); ++runIdx)
00210 {
00211
00212 if (run_ids[runIdx] == runIdx)
00213 map[runIdx] = max_id++;
00214 else
00215 map [runIdx] = map [findRoot (run_ids, runIdx)];
00216 }
00217
00218 label_indices.resize (max_id + 1);
00219 for (unsigned idx = 0; idx < input_->points.size (); idx++)
00220 {
00221 if (labels[idx].label != invalid_label)
00222 {
00223 labels[idx].label = map[labels[idx].label];
00224 label_indices[labels[idx].label].indices.push_back (idx);
00225 }
00226 }
00227 }
00228
00229 #define PCL_INSTANTIATE_OrganizedConnectedComponentSegmentation(T,LT) template class PCL_EXPORTS pcl::OrganizedConnectedComponentSegmentation<T,LT>;
00230
00231 #endif //#ifndef PCL_SEGMENTATION_IMPL_ORGANIZED_CONNECTED_COMPONENT_SEGMENTATION_H_