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 #ifndef PCL_KEYPOINTS_AGAST_KEYPOINT_2D_H_
00040 #define PCL_KEYPOINTS_AGAST_KEYPOINT_2D_H_
00041 
00042 #include <pcl/point_cloud.h>
00043 #include <pcl/point_types.h>
00044 #include <pcl/keypoints/keypoint.h>
00045 #include <pcl/common/intensity.h>
00046 
00047 namespace pcl
00048 {
00049   namespace keypoints
00050   {
00051     namespace agast
00052     {
00053 
00062       class PCL_EXPORTS AbstractAgastDetector
00063       {
00064         public:
00065           typedef boost::shared_ptr<AbstractAgastDetector> Ptr;
00066           typedef boost::shared_ptr<const AbstractAgastDetector> ConstPtr;
00067 
00074           AbstractAgastDetector (const size_t width, 
00075                                  const size_t height, 
00076                                  const double threshold,
00077                                  const double bmax) 
00078             : width_ (width)
00079             , height_ (height)
00080             , threshold_ (threshold)
00081             , nr_max_keypoints_ (std::numeric_limits<unsigned int>::max ())
00082             , bmax_ (bmax)
00083           {}
00084 
00086           virtual ~AbstractAgastDetector () {}
00087 
00092           void 
00093           detectKeypoints (const std::vector<unsigned char> &intensity_data, 
00094                            pcl::PointCloud<pcl::PointUV> &output);
00095 
00100           void 
00101           detectKeypoints (const std::vector<float> &intensity_data, 
00102                            pcl::PointCloud<pcl::PointUV> &output);
00103 
00109           void
00110           applyNonMaxSuppression (const std::vector<unsigned char>& intensity_data, 
00111                                   const pcl::PointCloud<pcl::PointUV> &input, 
00112                                   pcl::PointCloud<pcl::PointUV> &output);
00113 
00119           void
00120           applyNonMaxSuppression (const std::vector<float>& intensity_data, 
00121                                   const pcl::PointCloud<pcl::PointUV> &input, 
00122                                   pcl::PointCloud<pcl::PointUV> &output);
00123 
00127           virtual int 
00128           computeCornerScore (const unsigned char* im) const = 0;
00129 
00134           virtual int 
00135           computeCornerScore (const float* im) const = 0;
00136 
00140           inline void
00141           setThreshold (const double threshold)
00142           {
00143             threshold_ = threshold;
00144           }
00145 
00147           inline double
00148           getThreshold ()
00149           {
00150             return (threshold_);
00151           }
00152 
00157           inline void
00158           setMaxKeypoints (const unsigned int nr_max_keypoints)
00159           {
00160             nr_max_keypoints_ = nr_max_keypoints;
00161           }
00162 
00164           inline unsigned int 
00165           getMaxKeypoints ()
00166           {
00167             return (nr_max_keypoints_);
00168           }
00169 
00174           virtual void 
00175           detect (const unsigned char* im, 
00176                   std::vector<pcl::PointUV, Eigen::aligned_allocator<pcl::PointUV> > &corners_all) const = 0;
00177 
00182           virtual void 
00183           detect (const float* im, 
00184                   std::vector<pcl::PointUV, Eigen::aligned_allocator<pcl::PointUV> > &) const = 0;
00185 
00186         protected:
00187 
00189           struct ScoreIndex
00190           {
00191             int idx;
00192             int score;
00193           };
00194 
00196           struct CompareScoreIndex
00197           {
00202             inline bool
00203             operator() (const ScoreIndex &i1, const ScoreIndex &i2)
00204             {
00205               return (i1.score > i2.score);
00206             }
00207           };
00208 
00210           virtual void
00211           initPattern () = 0;
00212 
00218           void
00219           applyNonMaxSuppression (const pcl::PointCloud<pcl::PointUV> &input, 
00220                                   const std::vector<ScoreIndex>& scores, 
00221                                   pcl::PointCloud<pcl::PointUV> &output);
00222 
00228           void 
00229           computeCornerScores (const unsigned char* im, 
00230                                const std::vector<pcl::PointUV, Eigen::aligned_allocator<pcl::PointUV> > & corners_all, 
00231                                std::vector<ScoreIndex> & scores);
00232 
00238           void 
00239           computeCornerScores (const float* im, 
00240                                const std::vector<pcl::PointUV, Eigen::aligned_allocator<pcl::PointUV> > & corners_all, 
00241                                std::vector<ScoreIndex> & scores);
00242 
00244           size_t width_;
00246           size_t height_;
00247 
00249           double threshold_;
00250 
00252           unsigned int nr_max_keypoints_;
00253 
00255           double bmax_;
00256       };
00257 
00266       class PCL_EXPORTS AgastDetector7_12s : public AbstractAgastDetector
00267       {
00268         public:
00269           typedef boost::shared_ptr<AgastDetector7_12s> Ptr;
00270           typedef boost::shared_ptr<const AgastDetector7_12s> ConstPtr;
00271 
00278           AgastDetector7_12s (const size_t width, 
00279                               const size_t height, 
00280                               const double threshold,
00281                               const double bmax = 255) 
00282             : AbstractAgastDetector (width, height, threshold, bmax)
00283           {
00284             initPattern ();
00285           }
00286 
00288           ~AgastDetector7_12s () {}
00289 
00293           int 
00294           computeCornerScore (const unsigned char* im) const;
00295 
00299           int 
00300           computeCornerScore (const float* im) const;
00301 
00306           void 
00307           detect (const unsigned char* im, std::vector<pcl::PointUV, Eigen::aligned_allocator<pcl::PointUV> > &corners_all) const;
00308 
00313           void 
00314           detect (const float* im, std::vector<pcl::PointUV, Eigen::aligned_allocator<pcl::PointUV> > &corners_all) const;
00315 
00316         protected:
00318           void 
00319           initPattern ();
00320 
00321         private:
00323           static const int border_width_ = 2;
00324 
00325           
00326           int_fast16_t s_offset0_;
00327           int_fast16_t s_offset1_;
00328           int_fast16_t s_offset2_;
00329           int_fast16_t s_offset3_;
00330           int_fast16_t s_offset4_;
00331           int_fast16_t s_offset5_;
00332           int_fast16_t s_offset6_;
00333           int_fast16_t s_offset7_;
00334           int_fast16_t s_offset8_;
00335           int_fast16_t s_offset9_;
00336           int_fast16_t s_offset10_;
00337           int_fast16_t s_offset11_;
00338       };
00339 
00348       class PCL_EXPORTS AgastDetector5_8 : public AbstractAgastDetector
00349       {
00350         public:
00351           typedef boost::shared_ptr<AgastDetector5_8> Ptr;
00352           typedef boost::shared_ptr<const AgastDetector5_8> ConstPtr;
00353 
00360           AgastDetector5_8 (const size_t width, 
00361                             const size_t height, 
00362                             const double threshold,
00363                             const double bmax = 255) 
00364             : AbstractAgastDetector (width, height, threshold, bmax)
00365           {
00366             initPattern ();
00367           }
00368 
00370           ~AgastDetector5_8 () {}
00371 
00375           int 
00376           computeCornerScore (const unsigned char* im) const;
00377 
00381           int 
00382           computeCornerScore (const float* im) const;
00383 
00388           void 
00389           detect (const unsigned char* im, std::vector<pcl::PointUV, Eigen::aligned_allocator<pcl::PointUV> > &corners_all) const;
00390 
00395           void 
00396           detect (const float* im, std::vector<pcl::PointUV, Eigen::aligned_allocator<pcl::PointUV> > &corners_all) const;
00397 
00398         protected:
00400           void 
00401           initPattern ();
00402 
00403         private:
00405           static const int border_width_ = 1;
00406 
00407           
00408           int_fast16_t s_offset0_;
00409           int_fast16_t s_offset1_;
00410           int_fast16_t s_offset2_;
00411           int_fast16_t s_offset3_;
00412           int_fast16_t s_offset4_;
00413           int_fast16_t s_offset5_;
00414           int_fast16_t s_offset6_;
00415           int_fast16_t s_offset7_;
00416       };
00417 
00426       class PCL_EXPORTS OastDetector9_16 : public AbstractAgastDetector
00427       {
00428         public:
00429           typedef boost::shared_ptr<OastDetector9_16> Ptr;
00430           typedef boost::shared_ptr<const OastDetector9_16> ConstPtr;
00431 
00438           OastDetector9_16 (const size_t width, 
00439                             const size_t height, 
00440                             const double threshold,
00441                             const double bmax = 255) 
00442             : AbstractAgastDetector (width, height, threshold, bmax)
00443           {
00444             initPattern ();
00445           }
00446 
00448           ~OastDetector9_16 () {}
00449 
00453           int 
00454           computeCornerScore (const unsigned char* im) const;
00455 
00459           int 
00460           computeCornerScore (const float* im) const;
00461 
00466           void 
00467           detect (const unsigned char* im, std::vector<pcl::PointUV, Eigen::aligned_allocator<pcl::PointUV> > &corners_all) const;
00468 
00473           void 
00474           detect (const float* im, std::vector<pcl::PointUV, Eigen::aligned_allocator<pcl::PointUV> > &corners_all) const;
00475 
00476         protected:
00478           void 
00479           initPattern ();
00480 
00481         private:
00483           static const int border_width_ = 3;
00484 
00485           
00486           int_fast16_t s_offset0_;
00487           int_fast16_t s_offset1_;
00488           int_fast16_t s_offset2_;
00489           int_fast16_t s_offset3_;
00490           int_fast16_t s_offset4_;
00491           int_fast16_t s_offset5_;
00492           int_fast16_t s_offset6_;
00493           int_fast16_t s_offset7_;
00494           int_fast16_t s_offset8_;
00495           int_fast16_t s_offset9_;
00496           int_fast16_t s_offset10_;
00497           int_fast16_t s_offset11_;
00498           int_fast16_t s_offset12_;
00499           int_fast16_t s_offset13_;
00500           int_fast16_t s_offset14_;
00501           int_fast16_t s_offset15_;
00502       };
00503     } 
00504   } 
00505 
00509   namespace keypoints
00510   {
00511     namespace internal
00512     {
00514       template <typename Out> 
00515       struct AgastApplyNonMaxSuppresion
00516       {
00517         AgastApplyNonMaxSuppresion (
00518             const std::vector<unsigned char> &image_data, 
00519             const pcl::PointCloud<pcl::PointUV> &tmp_cloud,
00520             const pcl::keypoints::agast::AbstractAgastDetector::Ptr &detector,
00521             pcl::PointCloud<Out> &output)
00522         {
00523           pcl::PointCloud<pcl::PointUV> output_temp;
00524           detector->applyNonMaxSuppression (image_data, tmp_cloud, output_temp);
00525           pcl::copyPointCloud<pcl::PointUV, Out> (output_temp, output);
00526         }
00527       };
00528 
00530       template <>
00531       struct AgastApplyNonMaxSuppresion<pcl::PointUV>
00532       {
00533         AgastApplyNonMaxSuppresion (
00534             const std::vector<unsigned char> &image_data, 
00535             const pcl::PointCloud<pcl::PointUV> &tmp_cloud,
00536             const pcl::keypoints::agast::AbstractAgastDetector::Ptr &detector,
00537             pcl::PointCloud<pcl::PointUV> &output)
00538         {
00539           detector->applyNonMaxSuppression (image_data, tmp_cloud, output);
00540         }
00541       };
00543       template <typename Out> 
00544       struct AgastDetector
00545       {
00546         AgastDetector (
00547             const std::vector<unsigned char> &image_data, 
00548             const pcl::keypoints::agast::AbstractAgastDetector::Ptr &detector,
00549             pcl::PointCloud<Out> &output)
00550         {
00551           pcl::PointCloud<pcl::PointUV> output_temp;
00552           detector->detectKeypoints (image_data, output_temp);
00553           pcl::copyPointCloud<pcl::PointUV, Out> (output_temp, output);
00554         }
00555       };
00556 
00558       template <>
00559       struct AgastDetector<pcl::PointUV>
00560       {
00561         AgastDetector (
00562             const std::vector<unsigned char> &image_data, 
00563             const pcl::keypoints::agast::AbstractAgastDetector::Ptr &detector,
00564             pcl::PointCloud<pcl::PointUV> &output)
00565         {
00566           detector->detectKeypoints (image_data, output);
00567         }
00568       };
00569     } 
00570   } 
00571 
00575 
00588   template <typename PointInT, typename PointOutT, typename IntensityT = pcl::common::IntensityFieldAccessor<PointInT> >
00589   class AgastKeypoint2DBase : public Keypoint<PointInT, PointOutT>
00590   {
00591     public:
00592       typedef typename Keypoint<PointInT, PointOutT>::PointCloudIn PointCloudIn;
00593       typedef typename Keypoint<PointInT, PointOutT>::PointCloudOut PointCloudOut;
00594       typedef typename Keypoint<PointInT, PointOutT>::KdTree KdTree;
00595       typedef typename PointCloudIn::ConstPtr PointCloudInConstPtr;
00596 
00597       typedef pcl::keypoints::agast::AbstractAgastDetector::Ptr AgastDetectorPtr;
00598      
00599       using Keypoint<PointInT, PointOutT>::name_;
00600       using Keypoint<PointInT, PointOutT>::input_;
00601       using Keypoint<PointInT, PointOutT>::indices_;
00602       using Keypoint<PointInT, PointOutT>::k_;
00603 
00605       AgastKeypoint2DBase ()
00606         : threshold_ (10)
00607         , apply_non_max_suppression_ (true)
00608         , bmax_ (255)
00609         , detector_ ()
00610         , nr_max_keypoints_ (std::numeric_limits<unsigned int>::max ())
00611       {
00612         k_ = 1;
00613       }
00614 
00616       virtual ~AgastKeypoint2DBase ()
00617       {
00618       }
00619 
00623       inline void
00624       setThreshold (const double threshold)
00625       {
00626         threshold_ = threshold;
00627       }
00628 
00630       inline double
00631       getThreshold ()
00632       {
00633         return (threshold_);
00634       }
00635 
00640       inline void
00641       setMaxKeypoints (const unsigned int nr_max_keypoints)
00642       {
00643         nr_max_keypoints_ = nr_max_keypoints;
00644       }
00645 
00647       inline unsigned int 
00648       getMaxKeypoints ()
00649       {
00650         return (nr_max_keypoints_);
00651       }
00652 
00656       inline void
00657       setMaxDataValue (const double bmax)
00658       {
00659         bmax_ = bmax;
00660       }
00661 
00663       inline double
00664       getMaxDataValue ()
00665       {
00666         return (bmax_);
00667       }
00668 
00672       inline void
00673       setNonMaxSuppression (const bool enabled)
00674       {
00675         apply_non_max_suppression_ = enabled;
00676       }
00677 
00679       inline bool
00680       getNonMaxSuppression ()
00681       {
00682         return (apply_non_max_suppression_);
00683       }
00684 
00685       inline void
00686       setAgastDetector (const AgastDetectorPtr &detector)
00687       {
00688         detector_ = detector;
00689       }
00690 
00691       inline AgastDetectorPtr
00692       getAgastDetector ()
00693       {
00694         return (detector_);
00695       }
00696     protected:
00697 
00699       bool 
00700       initCompute ();
00701       
00705       virtual void 
00706       detectKeypoints (PointCloudOut &output) = 0;
00707 
00709       IntensityT intensity_;
00710       
00712       double threshold_;
00713 
00715       bool apply_non_max_suppression_;
00716 
00718       double bmax_;
00719 
00721       AgastDetectorPtr detector_;
00722 
00724       unsigned int nr_max_keypoints_;
00725   };
00726 
00752   template <typename PointInT, typename PointOutT = pcl::PointUV>
00753   class AgastKeypoint2D : public AgastKeypoint2DBase<PointInT, PointOutT, pcl::common::IntensityFieldAccessor<PointInT> >
00754   {
00755     public:
00756       typedef typename Keypoint<PointInT, PointOutT>::PointCloudOut PointCloudOut;
00757 
00758       using Keypoint<PointInT, PointOutT>::name_;
00759       using Keypoint<PointInT, PointOutT>::input_;
00760       using Keypoint<PointInT, PointOutT>::indices_;
00761       using Keypoint<PointInT, PointOutT>::k_;
00762       using AgastKeypoint2DBase<PointInT, PointOutT, pcl::common::IntensityFieldAccessor<PointInT> >::intensity_;
00763       using AgastKeypoint2DBase<PointInT, PointOutT, pcl::common::IntensityFieldAccessor<PointInT> >::threshold_;
00764       using AgastKeypoint2DBase<PointInT, PointOutT, pcl::common::IntensityFieldAccessor<PointInT> >::bmax_;
00765       using AgastKeypoint2DBase<PointInT, PointOutT, pcl::common::IntensityFieldAccessor<PointInT> >::apply_non_max_suppression_;
00766       using AgastKeypoint2DBase<PointInT, PointOutT, pcl::common::IntensityFieldAccessor<PointInT> >::detector_;
00767       using AgastKeypoint2DBase<PointInT, PointOutT, pcl::common::IntensityFieldAccessor<PointInT> >::nr_max_keypoints_;
00768 
00770       AgastKeypoint2D ()
00771       {
00772         name_ = "AgastKeypoint2D";
00773       }
00774 
00776       virtual ~AgastKeypoint2D ()
00777       {
00778       }
00779 
00780     protected:
00784       virtual void 
00785       detectKeypoints (PointCloudOut &output);
00786   };
00787 
00814   template <>
00815   class AgastKeypoint2D<pcl::PointXYZ, pcl::PointUV>
00816     : public AgastKeypoint2DBase<pcl::PointXYZ, pcl::PointUV, pcl::common::IntensityFieldAccessor<pcl::PointXYZ> > 
00817   {
00818     public:
00820       AgastKeypoint2D ()
00821       {
00822         name_ = "AgastKeypoint2D";
00823         bmax_ = 4;    
00824       }
00825 
00827       virtual ~AgastKeypoint2D ()
00828       {
00829       }
00830 
00831     protected:
00835       virtual void 
00836       detectKeypoints (pcl::PointCloud<pcl::PointUV> &output);
00837   };
00838 
00839 }
00840 
00841 #include <pcl/keypoints/impl/agast_2d.hpp>
00842 
00843 #endif
00844