contrib/brl/bseg/sdet/sdet_nms.h
Go to the documentation of this file.
00001 // This is brl/bseg/sdet/sdet_nms.h
00002 #ifndef sdet_nms_h
00003 #define sdet_nms_h
00004 //:
00005 //\file
00006 //\brief A NMS class that can work with the sdet_edge_map class.
00007 //
00008 // For every pixel in an image, a parabola fit is applied along the
00009 // gradient direction, and the maximum point on this parabola is used
00010 // to get the sub-pixel location of the edge. The pixel point must qualify
00011 // for being a maximum, i.e. it should have higher values than the
00012 // interpolated sub-pixels along the positive and negative gradient
00013 // direction.
00014 //
00015 // Below drawing shows the face numbers at a pixel and
00016 // is for author's own reference.
00017 //\verbatim
00018 //       .---->x
00019 //       |
00020 //       |
00021 //       v y
00022 //
00023 //          6    7
00024 //        -----------
00025 //      5 |    |    | 8
00026 //        |    |    |
00027 //        -----------
00028 //      4 |    |    | 1
00029 //        |    |    |
00030 //        -----------
00031 //          3     2
00032 //\endverbatim
00033 //
00034 //\author Amir Tamrakar (adapted from Can's sdet_nms class)
00035 //\date 9 Sept 2006
00036 //
00037 //\verbatim
00038 // Modifications
00039 //  Moved to sdet -- should be refitted to Can Aras' non_max suppression class
00040 //\endverbatim
00041 //
00042 //-------------------------------------------------------------------------
00043 #include <vcl_vector.h>
00044 #include <vbl/vbl_array_2d.h>
00045 #include <vil/vil_image_view.h>
00046 #include <vgl/vgl_point_2d.h>
00047 #include <vgl/vgl_vector_2d.h>
00048 
00049 //: parameters for NMS
00050 class sdet_nms_params
00051 {
00052  public:
00053   // enumeration for the parabola fit type
00054   enum PFIT_TYPE {PFIT_3_POINTS=0, PFIT_9_POINTS=1};
00055 
00056   double thresh_;
00057   PFIT_TYPE pfit_type_;
00058   unsigned margin_;
00059   double rel_thresh_;                       // = 1.3*noise_sigma./sigma^3;
00060   bool use_adaptive_thresh_;
00061 
00062   sdet_nms_params(double thresh=1.0, PFIT_TYPE pfit_type=PFIT_3_POINTS, unsigned margin=1, double rel_thresh=2.5, bool adaptive_thresh=false):
00063     thresh_(thresh), pfit_type_(pfit_type), margin_(margin), rel_thresh_(rel_thresh), use_adaptive_thresh_(adaptive_thresh) {}
00064   ~sdet_nms_params() {}
00065 };
00066 
00067 class sdet_nms
00068 {
00069  protected:
00070   double thresh_;                                  ///< threshold
00071   sdet_nms_params::PFIT_TYPE parabola_fit_type_;  ///< flag for parabola fit method
00072   unsigned margin_;                                ///< margin size
00073   double rel_thresh_;                              ///< reliable threshold (depends on sensor noise and sigma)
00074   bool use_adaptive_thresh_;                       ///< use reliable threshold or not
00075 
00076   //references to the data passed to this algo
00077   const vil_image_view<double>& dir_x_;
00078   const vil_image_view<double>& dir_y_;
00079   const vil_image_view<double>& grad_mag_;
00080 
00081   // various 2d arrays holding the NMS pixel information to allow for post processing before
00082   // edgel tokens are returned
00083 
00084   vbl_array_2d<double> x_;   ///< to store the x coordinate of the subpixel token
00085   vbl_array_2d<double> y_;   ///< to store the y coordinate of the subpixel token
00086   vbl_array_2d<double> dir_; ///< to store the orientation of the subpixel token (this might be redundant)
00087   vbl_array_2d<double> mag_; ///< to store the magnitude of the maxima points (also doubles as a marker of edge pixels)
00088   vbl_array_2d<double> deriv_; ///< to store the second derivative of the maxima points
00089 
00090  protected:
00091   //: default constructor is not to be used
00092   sdet_nms();
00093 
00094  public:
00095   //: Constructor from a parameter block, gradient magnitudes given as an image and gradients given as component images
00096   sdet_nms(const sdet_nms_params& nsp,
00097            const vil_image_view<double>& dir_x,
00098            const vil_image_view<double>& dir_y,
00099            const vil_image_view<double>& grad_mag);
00100 
00101   //: Destructor
00102   ~sdet_nms() {}
00103 
00104   //Accessors
00105   unsigned width() const { return mag_.cols(); }
00106   unsigned height() const { return mag_.rows(); }
00107 
00108   //: return the array containing the suppressed non maxima (i.e., only maxima remain)
00109   vbl_array_2d<double>& mag() { return mag_; }
00110 
00111   //: return the array containing the second deriv map
00112   vbl_array_2d<double>& deriv() { return deriv_; }
00113 
00114   //: apply NMS to the given data (do not collect any edgel tokens)
00115   void apply() {} //FIX ME
00116 
00117   //: apply NMS to the given data (also collect edgel tokens)
00118   void apply( bool collect_tokens,
00119               vcl_vector<vgl_point_2d<double> >& loc,
00120               vcl_vector<double>& orientation,
00121               vcl_vector<double>& mag);
00122 
00123   void apply( bool collect_tokens,
00124               vcl_vector<vgl_point_2d<double> >& loc,
00125               vcl_vector<double>& orientation,
00126               vcl_vector<double>& mag,
00127               vcl_vector<double>& d2f);
00128 
00129   void apply( bool collect_tokens,
00130               vcl_vector<vgl_point_2d<double> >& loc,
00131               vcl_vector<double>& orientation,
00132               vcl_vector<double>& mag,
00133               vcl_vector<double>& d2f,
00134               vcl_vector<vgl_point_2d<int> >& pix_loc);
00135 
00136   void clear();
00137 
00138   // ======== intermediate functions =========
00139 
00140   int intersected_face_number(const vgl_vector_2d<double>& direction);
00141   double intersection_parameter(const vgl_vector_2d<double>& direction, int face_num);
00142   void f_values(int x, int y, const vgl_vector_2d<double>& direction, double s, int face_num, double *f);
00143   // get the corners related to the given face
00144   void get_relative_corner_coordinates(int face_num, int *corners);
00145   // used for 3 points parabola fit
00146   double subpixel_s(double *s, double *f, double & max_f, double &max_d);
00147   // used for 9 points parabola fit
00148   double subpixel_s(int x, int y, const vgl_vector_2d<double>& direction, double &max_f);
00149   void find_distance_s_and_f_for_point(int x, int y, vgl_homg_line_2d<double> line,
00150                                        double &d, double &s, const vgl_vector_2d<double>& direction);
00151 };
00152 
00153 
00154 #endif // sdet_nms_h