00001 /* 00002 * Software License Agreement (BSD License) 00003 * 00004 * Point Cloud Library (PCL) - www.pointclouds.org 00005 * 00006 * All rights reserved. 00007 * 00008 * Redistribution and use in source and binary forms, with or without 00009 * modification, are permitted provided that the following conditions 00010 * are met: 00011 * 00012 * * Redistributions of source code must retain the above copyright 00013 * notice, this list of conditions and the following disclaimer. 00014 * * Redistributions in binary form must reproduce the above 00015 * copyright notice, this list of conditions and the following 00016 * disclaimer in the documentation and/or other materials provided 00017 * with the distribution. 00018 * * Neither the name of the copyright holder(s) nor the names of its 00019 * contributors may be used to endorse or promote products derived 00020 * from this software without specific prior written permission. 00021 * 00022 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 00023 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 00024 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 00025 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 00026 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 00027 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 00028 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 00029 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 00030 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 00031 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 00032 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 00033 * POSSIBILITY OF SUCH DAMAGE. 00034 * 00035 * Author : Sergey Ushakov 00036 * Email : mine_all_mine@bk.ru 00037 * 00038 */ 00039 00040 #ifndef PCL_SEGMENTATION_REGION_GROWING_HPP_ 00041 #define PCL_SEGMENTATION_REGION_GROWING_HPP_ 00042 00043 #include <pcl/segmentation/region_growing.h> 00044 00045 #include <pcl/search/search.h> 00046 #include <pcl/search/kdtree.h> 00047 #include <pcl/point_cloud.h> 00048 #include <pcl/point_types.h> 00049 00050 #include <queue> 00051 #include <list> 00052 #include <cmath> 00053 #include <time.h> 00054 00055 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 00056 template <typename PointT, typename NormalT> 00057 pcl::RegionGrowing<PointT, NormalT>::RegionGrowing () : 00058 min_pts_per_cluster_ (1), 00059 max_pts_per_cluster_ (std::numeric_limits<int>::max ()), 00060 smooth_mode_flag_ (true), 00061 curvature_flag_ (true), 00062 residual_flag_ (false), 00063 theta_threshold_ (30.0f / 180.0f * static_cast<float> (M_PI)), 00064 residual_threshold_ (0.05f), 00065 curvature_threshold_ (0.05f), 00066 neighbour_number_ (30), 00067 search_ (), 00068 normals_ (), 00069 point_neighbours_ (0), 00070 point_labels_ (0), 00071 normal_flag_ (true), 00072 num_pts_in_segment_ (0), 00073 clusters_ (0), 00074 number_of_segments_ (0) 00075 { 00076 } 00077 00078 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 00079 template <typename PointT, typename NormalT> 00080 pcl::RegionGrowing<PointT, NormalT>::~RegionGrowing () 00081 { 00082 if (search_ != 0) 00083 search_.reset (); 00084 if (normals_ != 0) 00085 normals_.reset (); 00086 00087 point_neighbours_.clear (); 00088 point_labels_.clear (); 00089 num_pts_in_segment_.clear (); 00090 clusters_.clear (); 00091 } 00092 00093 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 00094 template <typename PointT, typename NormalT> int 00095 pcl::RegionGrowing<PointT, NormalT>::getMinClusterSize () 00096 { 00097 return (min_pts_per_cluster_); 00098 } 00099 00100 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 00101 template <typename PointT, typename NormalT> void 00102 pcl::RegionGrowing<PointT, NormalT>::setMinClusterSize (int min_cluster_size) 00103 { 00104 min_pts_per_cluster_ = min_cluster_size; 00105 } 00106 00107 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 00108 template <typename PointT, typename NormalT> int 00109 pcl::RegionGrowing<PointT, NormalT>::getMaxClusterSize () 00110 { 00111 return (max_pts_per_cluster_); 00112 } 00113 00114 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 00115 template <typename PointT, typename NormalT> void 00116 pcl::RegionGrowing<PointT, NormalT>::setMaxClusterSize (int max_cluster_size) 00117 { 00118 max_pts_per_cluster_ = max_cluster_size; 00119 } 00120 00121 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 00122 template <typename PointT, typename NormalT> bool 00123 pcl::RegionGrowing<PointT, NormalT>::getSmoothModeFlag () const 00124 { 00125 return (smooth_mode_flag_); 00126 } 00127 00128 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 00129 template <typename PointT, typename NormalT> void 00130 pcl::RegionGrowing<PointT, NormalT>::setSmoothModeFlag (bool value) 00131 { 00132 smooth_mode_flag_ = value; 00133 } 00134 00135 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 00136 template <typename PointT, typename NormalT> bool 00137 pcl::RegionGrowing<PointT, NormalT>::getCurvatureTestFlag () const 00138 { 00139 return (curvature_flag_); 00140 } 00141 00142 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 00143 template <typename PointT, typename NormalT> void 00144 pcl::RegionGrowing<PointT, NormalT>::setCurvatureTestFlag (bool value) 00145 { 00146 curvature_flag_ = value; 00147 00148 if (curvature_flag_ == false && residual_flag_ == false) 00149 residual_flag_ = true; 00150 } 00151 00152 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 00153 template <typename PointT, typename NormalT> bool 00154 pcl::RegionGrowing<PointT, NormalT>::getResidualTestFlag () const 00155 { 00156 return (residual_flag_); 00157 } 00158 00159 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 00160 template <typename PointT, typename NormalT> void 00161 pcl::RegionGrowing<PointT, NormalT>::setResidualTestFlag (bool value) 00162 { 00163 residual_flag_ = value; 00164 00165 if (curvature_flag_ == false && residual_flag_ == false) 00166 curvature_flag_ = true; 00167 } 00168 00169 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 00170 template <typename PointT, typename NormalT> float 00171 pcl::RegionGrowing<PointT, NormalT>::getSmoothnessThreshold () const 00172 { 00173 return (theta_threshold_); 00174 } 00175 00176 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 00177 template <typename PointT, typename NormalT> void 00178 pcl::RegionGrowing<PointT, NormalT>::setSmoothnessThreshold (float theta) 00179 { 00180 theta_threshold_ = theta; 00181 } 00182 00183 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 00184 template <typename PointT, typename NormalT> float 00185 pcl::RegionGrowing<PointT, NormalT>::getResidualThreshold () const 00186 { 00187 return (residual_threshold_); 00188 } 00189 00190 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 00191 template <typename PointT, typename NormalT> void 00192 pcl::RegionGrowing<PointT, NormalT>::setResidualThreshold (float residual) 00193 { 00194 residual_threshold_ = residual; 00195 } 00196 00197 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 00198 template <typename PointT, typename NormalT> float 00199 pcl::RegionGrowing<PointT, NormalT>::getCurvatureThreshold () const 00200 { 00201 return (curvature_threshold_); 00202 } 00203 00204 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 00205 template <typename PointT, typename NormalT> void 00206 pcl::RegionGrowing<PointT, NormalT>::setCurvatureThreshold (float curvature) 00207 { 00208 curvature_threshold_ = curvature; 00209 } 00210 00211 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 00212 template <typename PointT, typename NormalT> unsigned int 00213 pcl::RegionGrowing<PointT, NormalT>::getNumberOfNeighbours () const 00214 { 00215 return (neighbour_number_); 00216 } 00217 00218 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 00219 template <typename PointT, typename NormalT> void 00220 pcl::RegionGrowing<PointT, NormalT>::setNumberOfNeighbours (unsigned int neighbour_number) 00221 { 00222 neighbour_number_ = neighbour_number; 00223 } 00224 00225 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 00226 template <typename PointT, typename NormalT> typename pcl::RegionGrowing<PointT, NormalT>::KdTreePtr 00227 pcl::RegionGrowing<PointT, NormalT>::getSearchMethod () const 00228 { 00229 return (search_); 00230 } 00231 00232 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 00233 template <typename PointT, typename NormalT> void 00234 pcl::RegionGrowing<PointT, NormalT>::setSearchMethod (const KdTreePtr& tree) 00235 { 00236 if (search_ != 0) 00237 search_.reset (); 00238 00239 search_ = tree; 00240 } 00241 00242 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 00243 template <typename PointT, typename NormalT> typename pcl::RegionGrowing<PointT, NormalT>::NormalPtr 00244 pcl::RegionGrowing<PointT, NormalT>::getInputNormals () const 00245 { 00246 return (normals_); 00247 } 00248 00249 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 00250 template <typename PointT, typename NormalT> void 00251 pcl::RegionGrowing<PointT, NormalT>::setInputNormals (const NormalPtr& norm) 00252 { 00253 if (normals_ != 0) 00254 normals_.reset (); 00255 00256 normals_ = norm; 00257 } 00258 00259 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 00260 template <typename PointT, typename NormalT> void 00261 pcl::RegionGrowing<PointT, NormalT>::extract (std::vector <pcl::PointIndices>& clusters) 00262 { 00263 clusters_.clear (); 00264 clusters.clear (); 00265 point_neighbours_.clear (); 00266 point_labels_.clear (); 00267 num_pts_in_segment_.clear (); 00268 number_of_segments_ = 0; 00269 00270 bool segmentation_is_possible = initCompute (); 00271 if ( !segmentation_is_possible ) 00272 { 00273 deinitCompute (); 00274 return; 00275 } 00276 00277 segmentation_is_possible = prepareForSegmentation (); 00278 if ( !segmentation_is_possible ) 00279 { 00280 deinitCompute (); 00281 return; 00282 } 00283 00284 findPointNeighbours (); 00285 applySmoothRegionGrowingAlgorithm (); 00286 assembleRegions (); 00287 00288 clusters.resize (clusters_.size ()); 00289 std::vector<pcl::PointIndices>::iterator cluster_iter_input = clusters.begin (); 00290 for (std::vector<pcl::PointIndices>::const_iterator cluster_iter = clusters_.begin (); cluster_iter != clusters_.end (); cluster_iter++) 00291 { 00292 if ((cluster_iter->indices.size () >= min_pts_per_cluster_) && 00293 (cluster_iter->indices.size () <= max_pts_per_cluster_)) 00294 { 00295 *cluster_iter_input = *cluster_iter; 00296 cluster_iter_input++; 00297 } 00298 } 00299 00300 clusters_ = std::vector<pcl::PointIndices> (clusters.begin (), cluster_iter_input); 00301 clusters.resize(clusters_.size()); 00302 00303 deinitCompute (); 00304 } 00305 00306 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 00307 template <typename PointT, typename NormalT> bool 00308 pcl::RegionGrowing<PointT, NormalT>::prepareForSegmentation () 00309 { 00310 // if user forgot to pass point cloud or if it is empty 00311 if ( input_->points.size () == 0 ) 00312 return (false); 00313 00314 // if user forgot to pass normals or the sizes of point and normal cloud are different 00315 if ( normals_ == 0 || input_->points.size () != normals_->points.size () ) 00316 return (false); 00317 00318 // if residual test is on then we need to check if all needed parameters were correctly initialized 00319 if (residual_flag_) 00320 { 00321 if (residual_threshold_ <= 0.0f) 00322 return (false); 00323 } 00324 00325 // if curvature test is on ... 00326 // if (curvature_flag_) 00327 // { 00328 // in this case we do not need to check anything that related to it 00329 // so we simply commented it 00330 // } 00331 00332 // from here we check those parameters that are always valuable 00333 if (neighbour_number_ == 0) 00334 return (false); 00335 00336 // if user didn't set search method 00337 if (!search_) 00338 search_.reset (new pcl::search::KdTree<PointT>); 00339 00340 if (indices_) 00341 { 00342 if (indices_->empty ()) 00343 PCL_ERROR ("[pcl::RegionGrowing::prepareForSegmentation] Empty given indices!\n"); 00344 search_->setInputCloud (input_, indices_); 00345 } 00346 else 00347 search_->setInputCloud (input_); 00348 00349 return (true); 00350 } 00351 00352 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 00353 template <typename PointT, typename NormalT> void 00354 pcl::RegionGrowing<PointT, NormalT>::findPointNeighbours () 00355 { 00356 int point_number = static_cast<int> (indices_->size ()); 00357 std::vector<int> neighbours; 00358 std::vector<float> distances; 00359 00360 point_neighbours_.resize (input_->points.size (), neighbours); 00361 00362 for (int i_point = 0; i_point < point_number; i_point++) 00363 { 00364 int point_index = (*indices_)[i_point]; 00365 neighbours.clear (); 00366 search_->nearestKSearch (i_point, neighbour_number_, neighbours, distances); 00367 point_neighbours_[point_index].swap (neighbours); 00368 } 00369 } 00370 00371 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 00372 template <typename PointT, typename NormalT> void 00373 pcl::RegionGrowing<PointT, NormalT>::applySmoothRegionGrowingAlgorithm () 00374 { 00375 int num_of_pts = static_cast<int> (indices_->size ()); 00376 point_labels_.resize (input_->points.size (), -1); 00377 00378 std::vector< std::pair<float, int> > point_residual; 00379 std::pair<float, int> pair; 00380 point_residual.resize (num_of_pts, pair); 00381 00382 if (normal_flag_ == true) 00383 { 00384 for (int i_point = 0; i_point < num_of_pts; i_point++) 00385 { 00386 int point_index = (*indices_)[i_point]; 00387 point_residual[i_point].first = normals_->points[point_index].curvature; 00388 point_residual[i_point].second = point_index; 00389 } 00390 std::sort (point_residual.begin (), point_residual.end (), comparePair); 00391 } 00392 else 00393 { 00394 for (int i_point = 0; i_point < num_of_pts; i_point++) 00395 { 00396 int point_index = (*indices_)[i_point]; 00397 point_residual[i_point].first = 0; 00398 point_residual[i_point].second = point_index; 00399 } 00400 } 00401 int seed_counter = 0; 00402 int seed = point_residual[seed_counter].second; 00403 00404 int segmented_pts_num = 0; 00405 int number_of_segments = 0; 00406 while (segmented_pts_num < num_of_pts) 00407 { 00408 int pts_in_segment; 00409 pts_in_segment = growRegion (seed, number_of_segments); 00410 segmented_pts_num += pts_in_segment; 00411 num_pts_in_segment_.push_back (pts_in_segment); 00412 number_of_segments++; 00413 00414 //find next point that is not segmented yet 00415 for (int i_seed = seed_counter + 1; i_seed < num_of_pts; i_seed++) 00416 { 00417 int index = point_residual[i_seed].second; 00418 if (point_labels_[index] == -1) 00419 { 00420 seed = index; 00421 break; 00422 } 00423 } 00424 } 00425 } 00426 00427 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 00428 template <typename PointT, typename NormalT> int 00429 pcl::RegionGrowing<PointT, NormalT>::growRegion (int initial_seed, int segment_number) 00430 { 00431 std::queue<int> seeds; 00432 seeds.push (initial_seed); 00433 point_labels_[initial_seed] = segment_number; 00434 00435 int num_pts_in_segment = 1; 00436 00437 while (!seeds.empty ()) 00438 { 00439 int curr_seed; 00440 curr_seed = seeds.front (); 00441 seeds.pop (); 00442 00443 size_t i_nghbr = 0; 00444 while ( i_nghbr < neighbour_number_ && i_nghbr < point_neighbours_[curr_seed].size () ) 00445 { 00446 int index = point_neighbours_[curr_seed][i_nghbr]; 00447 if (point_labels_[index] != -1) 00448 { 00449 i_nghbr++; 00450 continue; 00451 } 00452 00453 bool is_a_seed = false; 00454 bool belongs_to_segment = validatePoint (initial_seed, curr_seed, index, is_a_seed); 00455 00456 if (belongs_to_segment == false) 00457 { 00458 i_nghbr++; 00459 continue; 00460 } 00461 00462 point_labels_[index] = segment_number; 00463 num_pts_in_segment++; 00464 00465 if (is_a_seed) 00466 { 00467 seeds.push (index); 00468 } 00469 00470 i_nghbr++; 00471 }// next neighbour 00472 }// next seed 00473 00474 return (num_pts_in_segment); 00475 } 00476 00477 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 00478 template <typename PointT, typename NormalT> bool 00479 pcl::RegionGrowing<PointT, NormalT>::validatePoint (int initial_seed, int point, int nghbr, bool& is_a_seed) const 00480 { 00481 is_a_seed = true; 00482 00483 float cosine_threshold = cosf (theta_threshold_); 00484 float data[4]; 00485 00486 data[0] = input_->points[point].data[0]; 00487 data[1] = input_->points[point].data[1]; 00488 data[2] = input_->points[point].data[2]; 00489 data[3] = input_->points[point].data[3]; 00490 Eigen::Map<Eigen::Vector3f> initial_point (static_cast<float*> (data)); 00491 Eigen::Map<Eigen::Vector3f> initial_normal (static_cast<float*> (normals_->points[point].normal)); 00492 00493 //check the angle between normals 00494 if (smooth_mode_flag_ == true) 00495 { 00496 Eigen::Map<Eigen::Vector3f> nghbr_normal (static_cast<float*> (normals_->points[nghbr].normal)); 00497 float dot_product = fabsf (nghbr_normal.dot (initial_normal)); 00498 if (dot_product < cosine_threshold) 00499 { 00500 return (false); 00501 } 00502 } 00503 else 00504 { 00505 Eigen::Map<Eigen::Vector3f> nghbr_normal (static_cast<float*> (normals_->points[nghbr].normal)); 00506 Eigen::Map<Eigen::Vector3f> initial_seed_normal (static_cast<float*> (normals_->points[initial_seed].normal)); 00507 float dot_product = fabsf (nghbr_normal.dot (initial_seed_normal)); 00508 if (dot_product < cosine_threshold) 00509 return (false); 00510 } 00511 00512 // check the curvature if needed 00513 if (curvature_flag_ && normals_->points[nghbr].curvature > curvature_threshold_) 00514 { 00515 is_a_seed = false; 00516 } 00517 00518 // check the residual if needed 00519 data[0] = input_->points[nghbr].data[0]; 00520 data[1] = input_->points[nghbr].data[1]; 00521 data[2] = input_->points[nghbr].data[2]; 00522 data[3] = input_->points[nghbr].data[3]; 00523 Eigen::Map<Eigen::Vector3f> nghbr_point (static_cast<float*> (data)); 00524 float residual = fabsf (initial_normal.dot (initial_point - nghbr_point)); 00525 if (residual_flag_ && residual > residual_threshold_) 00526 is_a_seed = false; 00527 00528 return (true); 00529 } 00530 00531 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 00532 template <typename PointT, typename NormalT> void 00533 pcl::RegionGrowing<PointT, NormalT>::assembleRegions () 00534 { 00535 int number_of_segments = static_cast<int> (num_pts_in_segment_.size ()); 00536 int number_of_points = static_cast<int> (input_->points.size ()); 00537 00538 pcl::PointIndices segment; 00539 clusters_.resize (number_of_segments, segment); 00540 00541 for (int i_seg = 0; i_seg < number_of_segments; i_seg++) 00542 { 00543 clusters_[i_seg].indices.resize ( num_pts_in_segment_[i_seg], 0); 00544 } 00545 00546 std::vector<int> counter; 00547 counter.resize (number_of_segments, 0); 00548 00549 for (int i_point = 0; i_point < number_of_points; i_point++) 00550 { 00551 int segment_index = point_labels_[i_point]; 00552 if (segment_index != -1) 00553 { 00554 int point_index = counter[segment_index]; 00555 clusters_[segment_index].indices[point_index] = i_point; 00556 counter[segment_index] = point_index + 1; 00557 } 00558 } 00559 00560 number_of_segments_ = number_of_segments; 00561 } 00562 00563 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 00564 template <typename PointT, typename NormalT> void 00565 pcl::RegionGrowing<PointT, NormalT>::getSegmentFromPoint (int index, pcl::PointIndices& cluster) 00566 { 00567 cluster.indices.clear (); 00568 00569 bool segmentation_is_possible = initCompute (); 00570 if ( !segmentation_is_possible ) 00571 { 00572 deinitCompute (); 00573 return; 00574 } 00575 00576 // first of all we need to find out if this point belongs to cloud 00577 bool point_was_found = false; 00578 int number_of_points = static_cast <int> (indices_->size ()); 00579 for (size_t point = 0; point < number_of_points; point++) 00580 if ( (*indices_)[point] == index) 00581 { 00582 point_was_found = true; 00583 break; 00584 } 00585 00586 if (point_was_found) 00587 { 00588 if (clusters_.empty ()) 00589 { 00590 point_neighbours_.clear (); 00591 point_labels_.clear (); 00592 num_pts_in_segment_.clear (); 00593 number_of_segments_ = 0; 00594 00595 segmentation_is_possible = prepareForSegmentation (); 00596 if ( !segmentation_is_possible ) 00597 { 00598 deinitCompute (); 00599 return; 00600 } 00601 00602 findPointNeighbours (); 00603 applySmoothRegionGrowingAlgorithm (); 00604 assembleRegions (); 00605 } 00606 // if we have already made the segmentation, then find the segment 00607 // to which this point belongs 00608 std::vector <pcl::PointIndices>::iterator i_segment; 00609 for (i_segment = clusters_.begin (); i_segment != clusters_.end (); i_segment++) 00610 { 00611 bool segment_was_found = false; 00612 for (size_t i_point = 0; i_point < i_segment->indices.size (); i_point++) 00613 { 00614 if (i_segment->indices[i_point] == index) 00615 { 00616 segment_was_found = true; 00617 cluster.indices.clear (); 00618 cluster.indices.reserve (i_segment->indices.size ()); 00619 std::copy (i_segment->indices.begin (), i_segment->indices.end (), std::back_inserter (cluster.indices)); 00620 break; 00621 } 00622 } 00623 if (segment_was_found) 00624 { 00625 break; 00626 } 00627 }// next segment 00628 }// end if point was found 00629 00630 deinitCompute (); 00631 } 00632 00633 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 00634 template <typename PointT, typename NormalT> pcl::PointCloud<pcl::PointXYZRGB>::Ptr 00635 pcl::RegionGrowing<PointT, NormalT>::getColoredCloud () 00636 { 00637 pcl::PointCloud<pcl::PointXYZRGB>::Ptr colored_cloud; 00638 00639 if (!clusters_.empty ()) 00640 { 00641 colored_cloud = (new pcl::PointCloud<pcl::PointXYZRGB>)->makeShared (); 00642 00643 srand (static_cast<unsigned int> (time (0))); 00644 std::vector<unsigned char> colors; 00645 for (size_t i_segment = 0; i_segment < clusters_.size (); i_segment++) 00646 { 00647 colors.push_back (static_cast<unsigned char> (rand () % 256)); 00648 colors.push_back (static_cast<unsigned char> (rand () % 256)); 00649 colors.push_back (static_cast<unsigned char> (rand () % 256)); 00650 } 00651 00652 colored_cloud->width = input_->width; 00653 colored_cloud->height = input_->height; 00654 colored_cloud->is_dense = input_->is_dense; 00655 for (size_t i_point = 0; i_point < input_->points.size (); i_point++) 00656 { 00657 pcl::PointXYZRGB point; 00658 point.x = *(input_->points[i_point].data); 00659 point.y = *(input_->points[i_point].data + 1); 00660 point.z = *(input_->points[i_point].data + 2); 00661 point.r = 255; 00662 point.g = 0; 00663 point.b = 0; 00664 colored_cloud->points.push_back (point); 00665 } 00666 00667 std::vector< pcl::PointIndices >::iterator i_segment; 00668 int next_color = 0; 00669 for (i_segment = clusters_.begin (); i_segment != clusters_.end (); i_segment++) 00670 { 00671 std::vector<int>::iterator i_point; 00672 for (i_point = i_segment->indices.begin (); i_point != i_segment->indices.end (); i_point++) 00673 { 00674 int index; 00675 index = *i_point; 00676 colored_cloud->points[index].r = colors[3 * next_color]; 00677 colored_cloud->points[index].g = colors[3 * next_color + 1]; 00678 colored_cloud->points[index].b = colors[3 * next_color + 2]; 00679 } 00680 next_color++; 00681 } 00682 } 00683 00684 return (colored_cloud); 00685 } 00686 00687 ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// 00688 template <typename PointT, typename NormalT> pcl::PointCloud<pcl::PointXYZRGBA>::Ptr 00689 pcl::RegionGrowing<PointT, NormalT>::getColoredCloudRGBA () 00690 { 00691 pcl::PointCloud<pcl::PointXYZRGBA>::Ptr colored_cloud; 00692 00693 if (!clusters_.empty ()) 00694 { 00695 colored_cloud = (new pcl::PointCloud<pcl::PointXYZRGBA>)->makeShared (); 00696 00697 srand (static_cast<unsigned int> (time (0))); 00698 std::vector<unsigned char> colors; 00699 for (size_t i_segment = 0; i_segment < clusters_.size (); i_segment++) 00700 { 00701 colors.push_back (static_cast<unsigned char> (rand () % 256)); 00702 colors.push_back (static_cast<unsigned char> (rand () % 256)); 00703 colors.push_back (static_cast<unsigned char> (rand () % 256)); 00704 } 00705 00706 colored_cloud->width = input_->width; 00707 colored_cloud->height = input_->height; 00708 colored_cloud->is_dense = input_->is_dense; 00709 for (size_t i_point = 0; i_point < input_->points.size (); i_point++) 00710 { 00711 pcl::PointXYZRGBA point; 00712 point.x = *(input_->points[i_point].data); 00713 point.y = *(input_->points[i_point].data + 1); 00714 point.z = *(input_->points[i_point].data + 2); 00715 point.r = 255; 00716 point.g = 0; 00717 point.b = 0; 00718 point.a = 0; 00719 colored_cloud->points.push_back (point); 00720 } 00721 00722 std::vector< pcl::PointIndices >::iterator i_segment; 00723 int next_color = 0; 00724 for (i_segment = clusters_.begin (); i_segment != clusters_.end (); i_segment++) 00725 { 00726 std::vector<int>::iterator i_point; 00727 for (i_point = i_segment->indices.begin (); i_point != i_segment->indices.end (); i_point++) 00728 { 00729 int index; 00730 index = *i_point; 00731 colored_cloud->points[index].r = colors[3 * next_color]; 00732 colored_cloud->points[index].g = colors[3 * next_color + 1]; 00733 colored_cloud->points[index].b = colors[3 * next_color + 2]; 00734 } 00735 next_color++; 00736 } 00737 } 00738 00739 return (colored_cloud); 00740 } 00741 00742 #define PCL_INSTANTIATE_RegionGrowing(T) template class pcl::RegionGrowing<T, pcl::Normal>; 00743 00744 #endif // PCL_SEGMENTATION_REGION_GROWING_HPP_
Except where otherwise noted, the PointClouds.org web pages are licensed under Creative Commons Attribution 3.0.
Pages generated on Wed Mar 25 00:25:40 2015