integral_image_normal.h
Go to the documentation of this file.
00001 /*
00002  * Software License Agreement (BSD License)
00003  *
00004  *  Point Cloud Library (PCL) - www.pointclouds.org
00005  *  Copyright (c) 2010-2011, Willow Garage, Inc.
00006  *  Copyright (c) 2012-, Open Perception, Inc.
00007  *
00008  *  All rights reserved.
00009  *
00010  *  Redistribution and use in source and binary forms, with or without
00011  *  modification, are permitted provided that the following conditions
00012  *  are met:
00013  *
00014  *   * Redistributions of source code must retain the above copyright
00015  *     notice, this list of conditions and the following disclaimer.
00016  *   * Redistributions in binary form must reproduce the above
00017  *     copyright notice, this list of conditions and the following
00018  *     disclaimer in the documentation and/or other materials provided
00019  *     with the distribution.
00020  *   * Neither the name of the copyright holder(s) nor the names of its
00021  *     contributors may be used to endorse or promote products derived
00022  *     from this software without specific prior written permission.
00023  *
00024  *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
00025  *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
00026  *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
00027  *  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
00028  *  COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
00029  *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
00030  *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
00031  *  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
00032  *  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
00033  *  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
00034  *  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
00035  *  POSSIBILITY OF SUCH DAMAGE.
00036  *
00037  */
00038 
00039 #ifndef PCL_INTEGRALIMAGE_BASED_NORMAL_ESTIMATOR_H_
00040 #define PCL_INTEGRALIMAGE_BASED_NORMAL_ESTIMATOR_H_
00041 
00042 #include <pcl/point_cloud.h>
00043 #include <pcl/point_types.h>
00044 #include <pcl/features/feature.h>
00045 #include <pcl/features/integral_image2D.h>
00046 
00047 #if defined BUILD_Maintainer && defined __GNUC__ && __GNUC__ == 4 && __GNUC_MINOR__ > 3
00048 #pragma GCC diagnostic ignored "-Weffc++"
00049 #endif
00050 namespace pcl
00051 {
00055   template <typename PointInT, typename PointOutT>
00056   class IntegralImageNormalEstimation: public Feature<PointInT, PointOutT>
00057   {
00058     using Feature<PointInT, PointOutT>::input_;
00059     using Feature<PointInT, PointOutT>::feature_name_;
00060     using Feature<PointInT, PointOutT>::tree_;
00061     using Feature<PointInT, PointOutT>::k_;
00062 
00063     public:
00064       typedef boost::shared_ptr<IntegralImageNormalEstimation<PointInT, PointOutT> > Ptr;
00065       typedef boost::shared_ptr<const IntegralImageNormalEstimation<PointInT, PointOutT> > ConstPtr;
00066 
00068         enum BorderPolicy
00069         {
00070           BORDER_POLICY_IGNORE,
00071           BORDER_POLICY_MIRROR
00072         };
00073 
00085       enum NormalEstimationMethod
00086       {
00087         COVARIANCE_MATRIX,
00088         AVERAGE_3D_GRADIENT,
00089         AVERAGE_DEPTH_CHANGE,
00090         SIMPLE_3D_GRADIENT
00091       };
00092 
00093       typedef typename Feature<PointInT, PointOutT>::PointCloudIn  PointCloudIn;
00094       typedef typename Feature<PointInT, PointOutT>::PointCloudOut PointCloudOut;
00095 
00097       IntegralImageNormalEstimation ()
00098         : normal_estimation_method_(AVERAGE_3D_GRADIENT)
00099         , border_policy_ (BORDER_POLICY_IGNORE)
00100         , rect_width_ (0), rect_width_2_ (0), rect_width_4_ (0)
00101         , rect_height_ (0), rect_height_2_ (0), rect_height_4_ (0)
00102         , distance_threshold_ (0)
00103         , integral_image_DX_ (false)
00104         , integral_image_DY_ (false)
00105         , integral_image_depth_ (false)
00106         , integral_image_XYZ_ (true)
00107         , diff_x_ (NULL)
00108         , diff_y_ (NULL)
00109         , depth_data_ (NULL)
00110         , distance_map_ (NULL)
00111         , use_depth_dependent_smoothing_ (false)
00112         , max_depth_change_factor_ (20.0f*0.001f)
00113         , normal_smoothing_size_ (10.0f)
00114         , init_covariance_matrix_ (false)
00115         , init_average_3d_gradient_ (false)
00116         , init_simple_3d_gradient_ (false)
00117         , init_depth_change_ (false)
00118         , vpx_ (0.0f)
00119         , vpy_ (0.0f)
00120         , vpz_ (0.0f)
00121         , use_sensor_origin_ (true)
00122       {
00123         feature_name_ = "IntegralImagesNormalEstimation";
00124         tree_.reset ();
00125         k_ = 1;
00126       }
00127 
00129       virtual ~IntegralImageNormalEstimation ();
00130 
00135       void
00136       setRectSize (const int width, const int height);
00137 
00141       void
00142       setBorderPolicy (const BorderPolicy border_policy)
00143       {
00144         border_policy_ = border_policy;
00145       }
00146 
00153       void
00154       computePointNormal (const int pos_x, const int pos_y, const unsigned point_index, PointOutT &normal);
00155 
00162       void
00163       computePointNormalMirror (const int pos_x, const int pos_y, const unsigned point_index, PointOutT &normal);
00164 
00169       void
00170       setMaxDepthChangeFactor (float max_depth_change_factor)
00171       {
00172         max_depth_change_factor_ = max_depth_change_factor;
00173       }
00174 
00179       void
00180       setNormalSmoothingSize (float normal_smoothing_size)
00181       {
00182         if (normal_smoothing_size <= 0)
00183         {
00184           PCL_ERROR ("[pcl::%s::setNormalSmoothingSize] Invalid normal smoothing size given! (%f). Allowed ranges are: 0 < N. Defaulting to %f.\n", 
00185                       feature_name_.c_str (), normal_smoothing_size, normal_smoothing_size_);
00186           return;
00187         }
00188         normal_smoothing_size_ = normal_smoothing_size;
00189       }
00190 
00203       void
00204       setNormalEstimationMethod (NormalEstimationMethod normal_estimation_method)
00205       {
00206         normal_estimation_method_ = normal_estimation_method;
00207       }
00208 
00212       void
00213       setDepthDependentSmoothing (bool use_depth_dependent_smoothing)
00214       {
00215         use_depth_dependent_smoothing_ = use_depth_dependent_smoothing;
00216       }
00217 
00221       virtual inline void
00222       setInputCloud (const typename PointCloudIn::ConstPtr &cloud)
00223       {
00224         input_ = cloud;
00225         if (!cloud->isOrganized ())
00226         {
00227           PCL_ERROR ("[pcl::IntegralImageNormalEstimation::setInputCloud] Input dataset is not organized (height = 1).\n");
00228           return;
00229         }
00230 
00231         init_covariance_matrix_ = init_average_3d_gradient_ = init_depth_change_ = false;
00232         
00233         if (use_sensor_origin_)
00234         {
00235           vpx_ = input_->sensor_origin_.coeff (0);
00236           vpy_ = input_->sensor_origin_.coeff (1);
00237           vpz_ = input_->sensor_origin_.coeff (2);
00238         }
00239 
00240         // Initialize the correct data structure based on the normal estimation method chosen
00241         initData ();
00242       }
00243 
00246       inline float*
00247       getDistanceMap ()
00248       {
00249         return (distance_map_);
00250       }
00251 
00257       inline void
00258       setViewPoint (float vpx, float vpy, float vpz)
00259       {
00260         vpx_ = vpx;
00261         vpy_ = vpy;
00262         vpz_ = vpz;
00263         use_sensor_origin_ = false;
00264       }
00265 
00274       inline void
00275       getViewPoint (float &vpx, float &vpy, float &vpz)
00276       {
00277         vpx = vpx_;
00278         vpy = vpy_;
00279         vpz = vpz_;
00280       }
00281 
00286       inline void
00287       useSensorOriginAsViewPoint ()
00288       {
00289         use_sensor_origin_ = true;
00290         if (input_)
00291         {
00292           vpx_ = input_->sensor_origin_.coeff (0);
00293           vpy_ = input_->sensor_origin_.coeff (1);
00294           vpz_ = input_->sensor_origin_.coeff (2);
00295         }
00296         else
00297         {
00298           vpx_ = 0;
00299           vpy_ = 0;
00300           vpz_ = 0;
00301         }
00302       }
00303       
00304     protected:
00305 
00309       void
00310       computeFeature (PointCloudOut &output);
00311 
00313       void
00314       initData ();
00315 
00316     private:
00317 
00328       inline void
00329       flipNormalTowardsViewpoint (const PointInT &point, 
00330                                   float vp_x, float vp_y, float vp_z,
00331                                   float &nx, float &ny, float &nz)
00332       {
00333         // See if we need to flip any plane normals
00334         vp_x -= point.x;
00335         vp_y -= point.y;
00336         vp_z -= point.z;
00337 
00338         // Dot product between the (viewpoint - point) and the plane normal
00339         float cos_theta = (vp_x * nx + vp_y * ny + vp_z * nz);
00340 
00341         // Flip the plane normal
00342         if (cos_theta < 0)
00343         {
00344           nx *= -1;
00345           ny *= -1;
00346           nz *= -1;
00347         }
00348       }
00349 
00356       NormalEstimationMethod normal_estimation_method_;
00357 
00359       BorderPolicy border_policy_;
00360 
00362       int rect_width_;
00363       int rect_width_2_;
00364       int rect_width_4_;
00366       int rect_height_;
00367       int rect_height_2_;
00368       int rect_height_4_;
00369 
00371       float distance_threshold_;
00372 
00374       IntegralImage2D<float, 3> integral_image_DX_;
00376       IntegralImage2D<float, 3> integral_image_DY_;
00378       IntegralImage2D<float, 1> integral_image_depth_;
00380       IntegralImage2D<float, 3> integral_image_XYZ_;
00381 
00383       float *diff_x_;
00385       float *diff_y_;
00386 
00388       float *depth_data_;
00389 
00391       float *distance_map_;
00392 
00394       bool use_depth_dependent_smoothing_;
00395 
00397       float max_depth_change_factor_;
00398 
00400       float normal_smoothing_size_;
00401 
00403       bool init_covariance_matrix_;
00404 
00406       bool init_average_3d_gradient_;
00407 
00409       bool init_simple_3d_gradient_;
00410 
00412       bool init_depth_change_;
00413 
00416       float vpx_, vpy_, vpz_;
00417 
00419       bool use_sensor_origin_;
00420       
00422       bool
00423       initCompute ();
00424 
00426       void
00427       initCovarianceMatrixMethod ();
00428 
00430       void
00431       initAverage3DGradientMethod ();
00432 
00434       void
00435       initAverageDepthChangeMethod ();
00436 
00438       void
00439       initSimple3DGradientMethod ();
00440 
00441     public:
00442       EIGEN_MAKE_ALIGNED_OPERATOR_NEW
00443   };
00444 }
00445 #if defined BUILD_Maintainer && defined __GNUC__ && __GNUC__ == 4 && __GNUC_MINOR__ > 3
00446 #pragma GCC diagnostic warning "-Weffc++"
00447 #endif
00448 
00449 #ifdef PCL_NO_PRECOMPILE
00450 #include <pcl/features/impl/integral_image_normal.hpp>
00451 #endif
00452 
00453 #endif
00454 


pcl
Author(s): Open Perception
autogenerated on Wed Aug 26 2015 15:25:02