contrib/brl/bseg/sdet/sdet_harris_detector.cxx
Go to the documentation of this file.
00001 // This is brl/bseg/sdet/sdet_harris_detector.cxx
00002 #include "sdet_harris_detector.h"
00003 //:
00004 // \file
00005 #include <vcl_cstdlib.h>   // for vcl_abs(int) and vcl_qsort()
00006 #include <vil1/vil1_memory_image_of.h>
00007 #include <vil/vil_image_view.h>
00008 #include <vil/vil_convert.h>
00009 #include <vil/algo/vil_corners.h>
00010 #include <brip/brip_vil1_float_ops.h>
00011 #include <brip/brip_vil_float_ops.h>
00012 #include <vsol/vsol_point_2d.h>
00013 
00014 //: A container to support sorting of corners
00015 //  Will result in descending order according to strength
00016 struct sdet_harris_point
00017 {
00018   sdet_harris_point () {}
00019 
00020   void set_point(vsol_point_2d_sptr const& p) {p_ = p;}
00021   void set_strength(const float s) {strength_ = s;}
00022   vsol_point_2d_sptr point() {return p_;}
00023   double strength() {return strength_;}
00024 
00025  private:
00026   float strength_;
00027   vsol_point_2d_sptr p_;
00028 };
00029 
00030 //The sort compare function
00031 static int compare(sdet_harris_point*  pa,
00032                    sdet_harris_point*  pb)
00033 {
00034   if (pa->strength() < pb->strength())
00035     return +1;
00036   return -1;
00037 }
00038 
00039 //---------------------------------------------------------------
00040 // Constructors
00041 //
00042 //----------------------------------------------------------------
00043 
00044 //: constructor from a parameter block (the only way)
00045 //
00046 sdet_harris_detector::sdet_harris_detector(sdet_harris_detector_params& rpp)
00047   : sdet_harris_detector_params(rpp)
00048 {
00049   image_ = 0;
00050   vimage_ = 0;
00051   //don't really know but have to pick one
00052   use_vil_image_ = true;
00053 }
00054 
00055 //:Default Destructor
00056 sdet_harris_detector::~sdet_harris_detector()
00057 {
00058 }
00059 
00060 //-------------------------------------------------------------------------
00061 //: Set the image to be processed
00062 //
00063 void sdet_harris_detector::set_image(vil1_image const& image)
00064 {
00065   if (!image)
00066   {
00067     vcl_cout <<"In sdet_harris_detector::set_image(.) - null input\n";
00068     return;
00069   }
00070   points_valid_ = false;
00071   image_ = image;
00072   use_vil_image_ = false;
00073 }
00074 
00075 //-------------------------------------------------------------------------
00076 //: Set the image resource to be processed
00077 //
00078 void sdet_harris_detector::set_image_resource(vil_image_resource_sptr const& image)
00079 {
00080   if (!image)
00081   {
00082     vcl_cout <<"In sdet_harris_detector::set_image(.) - null input\n";
00083     return;
00084   }
00085   points_valid_ = false;
00086   vimage_ = image;
00087 }
00088 
00089 //------------------------------------------------------------------------
00090 // : extract corners using vil1 code
00091 //
00092 bool sdet_harris_detector::extract_corners_vil1(vcl_vector<float>& x_pos,
00093                                                 vcl_vector<float>& y_pos,
00094                                                 vcl_vector<float>& val)
00095 {
00096 // Check the image
00097   if (!image_)
00098   {
00099     vcl_cout << "In sdet_harris_detector::extract_corners() - no image\n";
00100     return false;
00101   }
00102   int w = image_.width(), h = image_.height();
00103   vcl_cout << "sdet_harris_detector::extract_corners(): width = "
00104            << w << " height = " << h << vcl_endl;
00105 
00106   vil1_memory_image_of<float> inputf = brip_vil1_float_ops::convert_to_float(image_);
00107   vil1_memory_image_of<float> smooth = brip_vil1_float_ops::gaussian(inputf, sigma_);
00108   vil1_memory_image_of<float> IxIx, IxIy, IyIy, c;
00109   IxIx.resize(w,h);  IxIy.resize(w,h);   IyIy.resize(w,h);
00110   brip_vil1_float_ops::grad_matrix_NxN(smooth, n_, IxIx, IxIy, IyIy);
00111   c = brip_vil1_float_ops::harris(IxIx, IxIy, IyIy, scale_factor_);
00112   brip_vil1_float_ops::non_maximum_suppression(c, n_, thresh_, x_pos, y_pos, val);
00113   return true;
00114 }
00115 
00116 //------------------------------------------------------------------------
00117 // : extract corners using vil code
00118 //
00119 bool sdet_harris_detector::extract_corners_vil(vcl_vector<float>& x_pos,
00120                                                vcl_vector<float>& y_pos,
00121                                                vcl_vector<float>& val)
00122 {
00123 // Check the image
00124   if (!vimage_||vimage_->nplanes()!=1)
00125   {
00126     vcl_cout << "In sdet_harris_detector::extract_corners() - "
00127              << "no image or not exactly one component\n";
00128     return false;
00129   }
00130 
00131   int w = vimage_->ni(), h = vimage_->nj();
00132   vcl_cout << "sdet_harris_detector::extract_corners(): width = "
00133            << w << " height = " << h << vcl_endl;
00134 
00135   vil_image_view<float> base_view = vimage_->get_view();
00136 
00137   vil_image_view<float> inputf;
00138   vil_convert_cast(base_view, inputf);
00139   vil_image_view<float> smooth = brip_vil_float_ops::gaussian(inputf, sigma_);
00140   vil_image_view<float> c(w,h);
00141   if (use_vil_harris_)
00142     vil_corners(smooth,c,scale_factor_);
00143   else
00144   {
00145     vil_image_view<float> IxIx(w,h), IxIy(w,h), IyIy(w,h);
00146     brip_vil_float_ops::grad_matrix_NxN(smooth, n_, IxIx, IxIy, IyIy);
00147     c = brip_vil_float_ops::harris(IxIx, IxIy, IyIy, scale_factor_);
00148   }
00149   brip_vil_float_ops::non_maximum_suppression(c, n_, thresh_, x_pos, y_pos, val);
00150   return true;
00151 }
00152 
00153 //--------------------------------------------------------------------------
00154 //: extract a set of vsol_point_2d(s)
00155 void sdet_harris_detector::extract_corners()
00156 {
00157   if (points_valid_)
00158     return;
00159 
00160   //Process the image to extract the Harris corners
00161   points_.clear();
00162   vcl_vector<float> x_pos, y_pos, val;
00163   if (!use_vil_image_)
00164   { if (!extract_corners_vil1(x_pos, y_pos, val)) return; }
00165   else
00166   { if (!extract_corners_vil(x_pos, y_pos, val)) return; }
00167   int n_corners = x_pos.size();
00168   vcl_cout << "Found " << n_corners << " above the threshold\n";
00169   if (!n_corners)
00170   {
00171     vcl_cout << "sdet_harris_detector::extract_corners() - "
00172              << "no corners found\n";
00173     return;
00174   }
00175   //Sort the corners according to strength
00176   sdet_harris_point* point_array = new sdet_harris_point[n_corners];
00177   for (int i = 0; i<n_corners; i++)
00178   {
00179     vsol_point_2d_sptr p = new vsol_point_2d(x_pos[i], y_pos[i]);
00180     point_array[i].set_point(p);
00181     point_array[i].set_strength(val[i]);
00182   }
00183   vcl_qsort(point_array, n_corners, sizeof(sdet_harris_point),
00184             (int (*)(const void *, const void *))&compare);
00185   //output the corners (limit by maximum number of corners)
00186   int num = (int)(percent_corners_/100.0*n_corners);
00187   if (num>n_corners)
00188     num = n_corners;
00189   for (int i=0; i<num; i++)
00190   {
00191     points_.push_back(point_array[i].point());
00192     // vcl_cout <<"s[" << i << "]=" << point_array[i].strength() << '\n';
00193   }
00194   delete [] point_array;
00195   points_valid_ = true;
00196 }
00197 
00198 //----------------------------------------------------------
00199 //: Clear internal storage
00200 //
00201 void sdet_harris_detector::clear()
00202 {
00203   points_.clear();
00204   points_valid_ = false;
00205 }
00206