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