Point Cloud Library (PCL)  1.7.0
/tmp/buildd/pcl-1.7-1.7.0/segmentation/include/pcl/segmentation/region_growing_rgb.h
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_REGION_GROWING_RGB_H_
00041 #define PCL_REGION_GROWING_RGB_H_
00042 
00043 #include <pcl/segmentation/region_growing.h>
00044 
00045 namespace pcl
00046 {
00047   /** \brief
00048     * Implements the well known Region Growing algorithm used for segmentation based on color of points.
00049     * Description can be found in the article
00050     * "Color-based segmentation of point clouds"
00051     * by Qingming Zhan, Yubin Liang, Yinghui Xiao
00052     */
00053   template <typename PointT, typename NormalT = pcl::Normal>
00054   class PCL_EXPORTS RegionGrowingRGB : public RegionGrowing<PointT, NormalT>
00055   {
00056     public:
00057 
00058       using RegionGrowing<PointT, NormalT>::input_;
00059       using RegionGrowing<PointT, NormalT>::indices_;
00060       using RegionGrowing<PointT, NormalT>::initCompute;
00061       using RegionGrowing<PointT, NormalT>::deinitCompute;
00062       using RegionGrowing<PointT, NormalT>::normals_;
00063       using RegionGrowing<PointT, NormalT>::normal_flag_;
00064       using RegionGrowing<PointT, NormalT>::curvature_flag_;
00065       using RegionGrowing<PointT, NormalT>::residual_flag_;
00066       using RegionGrowing<PointT, NormalT>::residual_threshold_;
00067       using RegionGrowing<PointT, NormalT>::neighbour_number_;
00068       using RegionGrowing<PointT, NormalT>::search_;
00069       using RegionGrowing<PointT, NormalT>::min_pts_per_cluster_;
00070       using RegionGrowing<PointT, NormalT>::max_pts_per_cluster_;
00071       using RegionGrowing<PointT, NormalT>::smooth_mode_flag_;
00072       using RegionGrowing<PointT, NormalT>::theta_threshold_;
00073       using RegionGrowing<PointT, NormalT>::curvature_threshold_;
00074       using RegionGrowing<PointT, NormalT>::point_neighbours_;
00075       using RegionGrowing<PointT, NormalT>::point_labels_;
00076       using RegionGrowing<PointT, NormalT>::num_pts_in_segment_;
00077       using RegionGrowing<PointT, NormalT>::clusters_;
00078       using RegionGrowing<PointT, NormalT>::number_of_segments_;
00079       using RegionGrowing<PointT, NormalT>::applySmoothRegionGrowingAlgorithm;
00080       using RegionGrowing<PointT, NormalT>::assembleRegions;
00081 
00082     public:
00083 
00084       /** \brief Constructor that sets default values for member variables. */
00085       RegionGrowingRGB ();
00086 
00087       /** \brief Destructor that frees memory. */
00088       virtual
00089       ~RegionGrowingRGB ();
00090 
00091       /** \brief Returns the color threshold value used for testing if points belong to the same region. */
00092       float
00093       getPointColorThreshold () const;
00094 
00095       /** \brief This method specifies the threshold value for color test between the points.
00096         * This kind of testing is made at the first stage of the algorithm(region growing).
00097         * If the difference between points color is less than threshold value, then they are considered
00098         * to be in the same region.
00099         * \param[in] thresh new threshold value for color test
00100         */
00101       void
00102       setPointColorThreshold (float thresh);
00103 
00104       /** \brief Returns the color threshold value used for testing if regions can be merged. */
00105       float
00106       getRegionColorThreshold () const;
00107 
00108       /** \brief This method specifies the threshold value for color test between the regions.
00109         * This kind of testing is made at the second stage of the algorithm(region merging).
00110         * If the difference between segments color is less than threshold value, then they are merged together.
00111         * \param[in] thresh new threshold value for color test
00112         */
00113       void
00114       setRegionColorThreshold (float thresh);
00115 
00116       /** \brief Returns the distance threshold. If the distance between two points is less or equal to
00117         * distance threshold value, then those points assumed to be neighbouring points.
00118         */
00119       float
00120       getDistanceThreshold () const;
00121 
00122       /** \brief Allows to set distance threshold.
00123         * \param[in] thresh new threshold value for neighbour test
00124         */
00125       void
00126       setDistanceThreshold (float thresh);
00127 
00128       /** \brief Returns the number of nearest neighbours used for searching K nearest segments.
00129         * Note that here it refers to the segments(not the points).
00130         */
00131       unsigned int
00132       getNumberOfRegionNeighbours () const;
00133 
00134       /** \brief This method allows to set the number of neighbours that is used for finding
00135         * neighbouring segments. Neighbouring segments are needed for the merging process.
00136         * \param[in] nghbr_number the number of neighbouring segments to find
00137         */
00138       void
00139       setNumberOfRegionNeighbours (unsigned int nghbr_number);
00140 
00141       /** \brief Returns the flag that signalize if the smoothness test is turned on/off. */
00142       bool
00143       getNormalTestFlag () const;
00144 
00145        /** \brief
00146          * Allows to turn on/off the smoothness test.
00147          * \param[in] value new value for normal/smoothness test. If set to true then the test will be turned on
00148          */
00149       void
00150       setNormalTestFlag (bool value);
00151 
00152       /** \brief Allows to turn on/off the curvature test.
00153         * \param[in] value new value for curvature test. If set to true then the test will be turned on
00154         */
00155       virtual void
00156       setCurvatureTestFlag (bool value);
00157 
00158       /** \brief
00159         * Allows to turn on/off the residual test.
00160         * \param[in] value new value for residual test. If set to true then the test will be turned on
00161         */
00162       virtual void
00163       setResidualTestFlag (bool value);
00164 
00165       /** \brief This method launches the segmentation algorithm and returns the clusters that were
00166         * obtained during the segmentation.
00167         * \param[out] clusters clusters that were obtained. Each cluster is an array of point indices.
00168         */
00169       virtual void
00170       extract (std::vector <pcl::PointIndices>& clusters);
00171 
00172       /** \brief For a given point this function builds a segment to which it belongs and returns this segment.
00173         * \param[in] index index of the initial point which will be the seed for growing a segment.
00174         */
00175       virtual void
00176       getSegmentFromPoint (int index, pcl::PointIndices& cluster);
00177 
00178     protected:
00179 
00180       /** \brief This method simply checks if it is possible to execute the segmentation algorithm with
00181         * the current settings. If it is possible then it returns true.
00182         */
00183       virtual bool
00184       prepareForSegmentation ();
00185 
00186       /** \brief This method finds KNN for each point and saves them to the array
00187         * because the algorithm needs to find KNN a few times.
00188         */
00189       virtual void
00190       findPointNeighbours ();
00191 
00192       /** \brief This method simply calls the findRegionsKNN for each segment and
00193         * saves the results for later use.
00194         */
00195       void
00196       findSegmentNeighbours ();
00197 
00198       /** \brief This method finds K nearest neighbours of the given segment.
00199         * \param[in] index index of the segment for which neighbours will be found
00200         * \param[in] nghbr_number the number of neighbours to find
00201         * \param[out] nghbrs the array of indices of the neighbours that were found
00202         * \param[out] dist the array of distances to the corresponding neighbours
00203         */
00204       void
00205       findRegionsKNN (int index, int nghbr_number, std::vector<int>& nghbrs, std::vector<float>& dist);
00206 
00207       /** \brief This function implements the merging algorithm described in the article
00208         * "Color-based segmentation of point clouds"
00209         * by Qingming Zhan, Yubin Liang, Yinghui Xiao
00210         */
00211       void
00212       applyRegionMergingAlgorithm ();
00213 
00214       /** \brief This method calculates the colorimetrical difference between two points.
00215         * In this case it simply returns the euclidean distance between two colors.
00216         * \param[in] first_color the color of the first point
00217         * \param[in] second_color the color of the second point
00218         */
00219       float
00220       calculateColorimetricalDifference (std::vector<unsigned int>& first_color, std::vector<unsigned int>& second_color) const;
00221 
00222       /** \brief This method assembles the array containing neighbours of each homogeneous region.
00223         * Homogeneous region is the union of some segments. This array is used when the regions
00224         * with a few points need to be merged with the neighbouring region.
00225         * \param[out] neighbours_out vector of lists of neighbours for every homogeneous region
00226         * \param[in] regions_in vector of lists, each list contains indices of segments that belong
00227         * to the corresponding homogeneous region.
00228         */
00229       void
00230       findRegionNeighbours (std::vector< std::vector< std::pair<float, int> > >& neighbours_out, std::vector< std::vector<int> >& regions_in);
00231 
00232       /** \brief This function simply assembles the regions from list of point labels.
00233         * \param[in] num_pts_in_region for each final region it stores the corresponding number of points in it
00234         * \param[in] num_regions number of regions to assemble
00235         */
00236       void
00237       assembleRegions (std::vector<unsigned int>& num_pts_in_region, int num_regions);
00238 
00239       /** \brief This function is checking if the point with index 'nghbr' belongs to the segment.
00240         * If so, then it returns true. It also checks if this point can serve as the seed.
00241         * \param[in] initial_seed index of the initial point that was passed to the growRegion() function
00242         * \param[in] point index of the current seed point
00243         * \param[in] nghbr index of the point that is neighbour of the current seed
00244         * \param[out] is_a_seed this value is set to true if the point with index 'nghbr' can serve as the seed
00245         */
00246       virtual bool
00247       validatePoint (int initial_seed, int point, int nghbr, bool& is_a_seed) const;
00248 
00249     protected:
00250 
00251       /** \brief Thershold used in color test for points. */
00252       float color_p2p_threshold_;
00253 
00254       /** \brief Thershold used in color test for regions. */
00255       float color_r2r_threshold_;
00256 
00257       /** \brief Threshold that tells which points we need to assume neighbouring. */
00258       float distance_threshold_;
00259 
00260       /** \brief Number of neighbouring segments to find. */
00261       unsigned int region_neighbour_number_;
00262 
00263       /** \brief Stores distances for the point neighbours from point_neighbours_ */
00264       std::vector< std::vector<float> > point_distances_;
00265 
00266       /** \brief Stores the neighboures for the corresponding segments. */
00267       std::vector< std::vector<int> > segment_neighbours_;
00268 
00269       /** \brief Stores distances for the segment neighbours from segment_neighbours_ */
00270       std::vector< std::vector<float> > segment_distances_;
00271 
00272       /** \brief Stores new indices for segments that were obtained at the region growing stage. */
00273       std::vector<int> segment_labels_;
00274 
00275     public:
00276       EIGEN_MAKE_ALIGNED_OPERATOR_NEW
00277   };
00278 }
00279 
00280 #ifdef PCL_NO_PRECOMPILE
00281 #include <pcl/segmentation/impl/region_growing_rgb.hpp>
00282 #endif
00283 
00284 #endif