Point Cloud Library (PCL)  1.7.0
/tmp/buildd/pcl-1.7-1.7.0/features/include/pcl/features/integral_image2D.h
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  * $Id: feature.h 2784 2011-10-15 22:05:38Z aichim $
00038  */
00039 
00040 #ifndef PCL_INTEGRAL_IMAGE2D_H_
00041 #define PCL_INTEGRAL_IMAGE2D_H_
00042 
00043 #include <vector>
00044 
00045 namespace pcl
00046 {
00047   template <typename DataType>
00048   struct IntegralImageTypeTraits
00049   {
00050     typedef DataType Type;
00051     typedef DataType IntegralType;
00052   };
00053 
00054   template <>
00055   struct IntegralImageTypeTraits<float>
00056   {
00057     typedef float Type;
00058     typedef double IntegralType;
00059   };
00060 
00061   template <>
00062   struct IntegralImageTypeTraits<char>
00063   {
00064     typedef char Type;
00065     typedef int IntegralType;
00066   };
00067 
00068   template <>
00069   struct IntegralImageTypeTraits<short>
00070   {
00071     typedef short Type;
00072     typedef long IntegralType;
00073   };
00074 
00075   template <>
00076   struct IntegralImageTypeTraits<unsigned short>
00077   {
00078     typedef unsigned short Type;
00079     typedef unsigned long IntegralType;
00080   };
00081 
00082   template <>
00083   struct IntegralImageTypeTraits<unsigned char>
00084   {
00085     typedef unsigned char Type;
00086     typedef unsigned int IntegralType;
00087   };
00088 
00089   template <>
00090   struct IntegralImageTypeTraits<int>
00091   {
00092     typedef int Type;
00093     typedef long IntegralType;
00094   };
00095 
00096   template <>
00097   struct IntegralImageTypeTraits<unsigned int>
00098   {
00099     typedef unsigned int Type;
00100     typedef unsigned long IntegralType;
00101   };
00102 
00103   /** \brief Determines an integral image representation for a given organized data array
00104     * \author Suat Gedikli
00105     */
00106   template <class DataType, unsigned Dimension>
00107   class IntegralImage2D
00108   {
00109     public:
00110       static const unsigned second_order_size = (Dimension * (Dimension + 1)) >> 1;
00111       typedef Eigen::Matrix<typename IntegralImageTypeTraits<DataType>::IntegralType, Dimension, 1> ElementType;
00112       typedef Eigen::Matrix<typename IntegralImageTypeTraits<DataType>::IntegralType, second_order_size, 1> SecondOrderType;
00113 
00114       /** \brief Constructor for an Integral Image
00115         * \param[in] compute_second_order_integral_images set to true if we want to compute a second order image
00116         */
00117       IntegralImage2D (bool compute_second_order_integral_images) :
00118         first_order_integral_image_ (),
00119         second_order_integral_image_ (),
00120         finite_values_integral_image_ (),
00121         width_ (1), 
00122         height_ (1), 
00123         compute_second_order_integral_images_ (compute_second_order_integral_images)
00124       {
00125       }
00126 
00127       /** \brief Destructor */
00128       virtual
00129       ~IntegralImage2D () { }
00130 
00131       /** \brief sets the computation for second order integral images on or off.
00132         * \param compute_second_order_integral_images
00133         */
00134       void 
00135       setSecondOrderComputation (bool compute_second_order_integral_images);
00136 
00137       /** \brief Set the input data to compute the integral image for
00138         * \param[in] data the input data
00139         * \param[in] width the width of the data
00140         * \param[in] height the height of the data
00141         * \param[in] element_stride the element stride of the data
00142         * \param[in] row_stride the row stride of the data
00143         */
00144       void
00145       setInput (const DataType * data,
00146                 unsigned width, unsigned height, unsigned element_stride, unsigned row_stride);
00147 
00148       /** \brief Compute the first order sum within a given rectangle
00149         * \param[in] start_x x position of rectangle
00150         * \param[in] start_y y position of rectangle
00151         * \param[in] width width of rectangle
00152         * \param[in] height height of rectangle
00153         */
00154       inline ElementType
00155       getFirstOrderSum (unsigned start_x, unsigned start_y, unsigned width, unsigned height) const;
00156 
00157       /** \brief Compute the first order sum within a given rectangle
00158         * \param[in] start_x x position of the start of the rectangle
00159         * \param[in] start_y x position of the start of the rectangle
00160         * \param[in] end_x x position of the end of the rectangle
00161         * \param[in] end_y x position of the end of the rectangle
00162         */
00163       inline ElementType
00164       getFirstOrderSumSE (unsigned start_x, unsigned start_y, unsigned end_x, unsigned end_y) const;
00165 
00166       /** \brief Compute the second order sum within a given rectangle
00167         * \param[in] start_x x position of rectangle
00168         * \param[in] start_y y position of rectangle
00169         * \param[in] width width of rectangle
00170         * \param[in] height height of rectangle
00171         */
00172       inline SecondOrderType
00173       getSecondOrderSum (unsigned start_x, unsigned start_y, unsigned width, unsigned height) const;
00174 
00175       /** \brief Compute the second order sum within a given rectangle
00176         * \param[in] start_x x position of the start of the rectangle
00177         * \param[in] start_y x position of the start of the rectangle
00178         * \param[in] end_x x position of the end of the rectangle
00179         * \param[in] end_y x position of the end of the rectangle
00180         */
00181       inline SecondOrderType
00182       getSecondOrderSumSE (unsigned start_x, unsigned start_y, unsigned end_x, unsigned end_y) const;
00183 
00184       /** \brief Compute the number of finite elements within a given rectangle
00185         * \param[in] start_x x position of rectangle
00186         * \param[in] start_y y position of rectangle
00187         * \param[in] width width of rectangle
00188         * \param[in] height height of rectangle
00189         */
00190       inline unsigned
00191       getFiniteElementsCount (unsigned start_x, unsigned start_y, unsigned width, unsigned height) const;
00192 
00193       /** \brief Compute the number of finite elements within a given rectangle
00194         * \param[in] start_x x position of the start of the rectangle
00195         * \param[in] start_y x position of the start of the rectangle
00196         * \param[in] end_x x position of the end of the rectangle
00197         * \param[in] end_y x position of the end of the rectangle
00198         */
00199       inline unsigned
00200       getFiniteElementsCountSE (unsigned start_x, unsigned start_y, unsigned end_x, unsigned end_y) const;
00201 
00202     private:
00203       typedef Eigen::Matrix<typename IntegralImageTypeTraits<DataType>::Type, Dimension, 1> InputType;
00204 
00205       /** \brief Compute the actual integral image data
00206         * \param[in] data the input data
00207         * \param[in] element_stride the element stride of the data
00208         * \param[in] row_stride the row stride of the data
00209         */
00210       void
00211       computeIntegralImages (const DataType * data, unsigned row_stride, unsigned element_stride);
00212 
00213       std::vector<ElementType, Eigen::aligned_allocator<ElementType> > first_order_integral_image_;
00214       std::vector<SecondOrderType, Eigen::aligned_allocator<SecondOrderType> > second_order_integral_image_;
00215       std::vector<unsigned> finite_values_integral_image_;
00216 
00217       /** \brief The width of the 2d input data array */
00218       unsigned width_;
00219       /** \brief The height of the 2d input data array */
00220       unsigned height_;
00221 
00222       /** \brief Indicates whether second order integral images are available **/
00223       bool compute_second_order_integral_images_;
00224    };
00225 
00226    /**
00227      * \brief partial template specialization for integral images with just one channel.
00228      */
00229   template <class DataType>
00230   class IntegralImage2D <DataType, 1>
00231   {
00232     public:
00233       static const unsigned second_order_size = 1;
00234       typedef typename IntegralImageTypeTraits<DataType>::IntegralType ElementType;
00235       typedef typename IntegralImageTypeTraits<DataType>::IntegralType SecondOrderType;
00236 
00237       /** \brief Constructor for an Integral Image
00238         * \param[in] compute_second_order_integral_images set to true if we want to compute a second order image
00239         */
00240       IntegralImage2D (bool compute_second_order_integral_images) : 
00241         first_order_integral_image_ (),
00242         second_order_integral_image_ (),
00243         finite_values_integral_image_ (),
00244         width_ (1), height_ (1), 
00245         compute_second_order_integral_images_ (compute_second_order_integral_images)
00246       {
00247       }
00248 
00249       /** \brief Destructor */
00250       virtual
00251       ~IntegralImage2D () { }
00252 
00253       /** \brief Set the input data to compute the integral image for
00254         * \param[in] data the input data
00255         * \param[in] width the width of the data
00256         * \param[in] height the height of the data
00257         * \param[in] element_stride the element stride of the data
00258         * \param[in] row_stride the row stride of the data
00259         */
00260       void
00261       setInput (const DataType * data,
00262                 unsigned width, unsigned height, unsigned element_stride, unsigned row_stride);
00263 
00264       /** \brief Compute the first order sum within a given rectangle
00265         * \param[in] start_x x position of rectangle
00266         * \param[in] start_y y position of rectangle
00267         * \param[in] width width of rectangle
00268         * \param[in] height height of rectangle
00269         */
00270       inline ElementType
00271       getFirstOrderSum (unsigned start_x, unsigned start_y, unsigned width, unsigned height) const;
00272 
00273       /** \brief Compute the first order sum within a given rectangle
00274         * \param[in] start_x x position of the start of the rectangle
00275         * \param[in] start_y x position of the start of the rectangle
00276         * \param[in] end_x x position of the end of the rectangle
00277         * \param[in] end_y x position of the end of the rectangle
00278         */
00279       inline ElementType
00280       getFirstOrderSumSE (unsigned start_x, unsigned start_y, unsigned end_x, unsigned end_y) const;
00281 
00282       /** \brief Compute the second order sum within a given rectangle
00283         * \param[in] start_x x position of rectangle
00284         * \param[in] start_y y position of rectangle
00285         * \param[in] width width of rectangle
00286         * \param[in] height height of rectangle
00287         */
00288       inline SecondOrderType
00289       getSecondOrderSum (unsigned start_x, unsigned start_y, unsigned width, unsigned height) const;
00290 
00291       /** \brief Compute the second order sum within a given rectangle
00292         * \param[in] start_x x position of the start of the rectangle
00293         * \param[in] start_y x position of the start of the rectangle
00294         * \param[in] end_x x position of the end of the rectangle
00295         * \param[in] end_y x position of the end of the rectangle
00296         */
00297       inline SecondOrderType
00298       getSecondOrderSumSE (unsigned start_x, unsigned start_y, unsigned end_x, unsigned end_y) const;
00299 
00300       /** \brief Compute the number of finite elements within a given rectangle
00301         * \param[in] start_x x position of rectangle
00302         * \param[in] start_y y position of rectangle
00303         * \param[in] width width of rectangle
00304         * \param[in] height height of rectangle
00305         */
00306       inline unsigned
00307       getFiniteElementsCount (unsigned start_x, unsigned start_y, unsigned width, unsigned height) const;
00308 
00309       /** \brief Compute the number of finite elements within a given rectangle
00310         * \param[in] start_x x position of the start of the rectangle
00311         * \param[in] start_y x position of the start of the rectangle
00312         * \param[in] end_x x position of the end of the rectangle
00313         * \param[in] end_y x position of the end of the rectangle
00314         */
00315       inline unsigned
00316       getFiniteElementsCountSE (unsigned start_x, unsigned start_y, unsigned end_x, unsigned end_y) const;
00317 
00318   private:
00319     //  typedef typename IntegralImageTypeTraits<DataType>::Type InputType;
00320 
00321       /** \brief Compute the actual integral image data
00322         * \param[in] data the input data
00323         * \param[in] element_stride the element stride of the data
00324         * \param[in] row_stride the row stride of the data
00325         */
00326       void
00327       computeIntegralImages (const DataType * data, unsigned row_stride, unsigned element_stride);
00328 
00329       std::vector<ElementType, Eigen::aligned_allocator<ElementType> > first_order_integral_image_;
00330       std::vector<SecondOrderType, Eigen::aligned_allocator<SecondOrderType> > second_order_integral_image_;
00331       std::vector<unsigned> finite_values_integral_image_;
00332 
00333       /** \brief The width of the 2d input data array */
00334       unsigned width_;
00335       /** \brief The height of the 2d input data array */
00336       unsigned height_;
00337 
00338       /** \brief Indicates whether second order integral images are available **/
00339       bool compute_second_order_integral_images_;
00340    };
00341  }
00342 
00343 #include <pcl/features/impl/integral_image2D.hpp>
00344 
00345 #endif    // PCL_INTEGRAL_IMAGE2D_H_
00346