contrib/oxl/mvl/HomgInterestPointSet.cxx
Go to the documentation of this file.
00001 // This is oxl/mvl/HomgInterestPointSet.cxx
00002 #ifdef VCL_NEEDS_PRAGMA_INTERFACE
00003 #pragma implementation
00004 #endif
00005 //:
00006 // \file
00007 
00008 #include "HomgInterestPointSet.h"
00009 
00010 #include <vcl_cassert.h>
00011 #include <vcl_iostream.h>
00012 #include <vcl_fstream.h>
00013 #include <vcl_vector.h>
00014 
00015 #include <vil1/vil1_memory_image_of.h>
00016 
00017 #include <mvl/HomgInterestPoint.h>
00018 #include <mvl/ImageMetric.h>
00019 
00020 class HomgInterestPointSetData : public vcl_vector<HomgInterestPoint>
00021 {
00022  public:
00023   HomgInterestPointSetData() {}
00024   HomgInterestPointSetData(int n):
00025     vcl_vector<HomgInterestPoint>(n, HomgInterestPoint())
00026   {}
00027   ~HomgInterestPointSetData() { }
00028 };
00029 
00030 //: Construct an empty corner set.
00031 HomgInterestPointSet::HomgInterestPointSet()
00032 {
00033   data_ = new HomgInterestPointSetData;
00034 
00035   init_conditioner(0);
00036 }
00037 
00038 //: Construct an empty corner set which will use the given conditioner to convert from image to homogeneous coordinates.
00039 HomgInterestPointSet::HomgInterestPointSet(const HomgMetric& c)
00040 {
00041   data_ = new HomgInterestPointSetData;
00042 
00043   init_conditioner(c);
00044 }
00045 
00046 //: Load corners from ASCII disk file
00047 HomgInterestPointSet::HomgInterestPointSet(const char* filename, const HomgMetric& c)
00048 {
00049   data_ = 0;
00050   read(filename, c);
00051   init_conditioner(c);
00052 }
00053 
00054 //: Construct corner set from container of vgl_homg_point_2d<double>, and set the conditioner.
00055 // The vgl_homg_point_2ds are assumed to already be in conditioned coordinates.
00056 HomgInterestPointSet::HomgInterestPointSet(vcl_vector<vgl_homg_point_2d<double> > const& points, ImageMetric* conditioner)
00057 {
00058   unsigned n = points.size();
00059   if (n > 0)
00060     data_ = new HomgInterestPointSetData(n);
00061   else
00062     data_ = new HomgInterestPointSetData();
00063 
00064   for (unsigned i = 0; i < n; ++i)
00065     (*data_)[i] = HomgInterestPoint(points[i], conditioner, 0.0f);
00066 
00067   conditioner_ = conditioner;
00068 }
00069 
00070 //: Construct corner set from container of HomgPoint2D, and set the conditioner.
00071 // The HomgPoint2Ds are assumed to already be in conditioned coordinates.
00072 HomgInterestPointSet::HomgInterestPointSet(const vcl_vector<HomgPoint2D>& points, ImageMetric* conditioner)
00073 {
00074   unsigned n = points.size();
00075   if (n > 0)
00076     data_ = new HomgInterestPointSetData(n);
00077   else
00078     data_ = new HomgInterestPointSetData();
00079 
00080   for (unsigned i = 0; i < n; ++i)
00081     (*data_)[i] = HomgInterestPoint(points[i], conditioner, 0.0f);
00082 
00083   conditioner_ = conditioner;
00084 }
00085 
00086 // - Untested
00087 HomgInterestPointSet::HomgInterestPointSet(const HomgInterestPointSet& that)
00088 {
00089   unsigned n = that.data_->size();
00090   if (n > 0)
00091     data_ = new HomgInterestPointSetData(n);
00092   else
00093     data_ = new HomgInterestPointSetData();
00094 
00095   vcl_cerr << "HomgInterestPointSet::copy ctor: size " << n << vcl_endl;
00096 
00097   for (unsigned i = 0; i < n; ++i)
00098     (*data_)[i] = (*that.data_)[i];
00099   conditioner_ = that.conditioner_;
00100 }
00101 
00102 // - Untested
00103 HomgInterestPointSet& HomgInterestPointSet::operator=(const HomgInterestPointSet& that)
00104 {
00105   unsigned n = that.data_->size();
00106   delete data_;
00107   if (n > 0)
00108     data_ = new HomgInterestPointSetData(n);
00109   else
00110     data_ = new HomgInterestPointSetData();
00111   for (unsigned i = 0; i < n; ++i) {
00112     (*data_)[i] = (*that.data_)[i];
00113   }
00114   conditioner_ = that.conditioner_;
00115   return *this;
00116 }
00117 
00118 //: Set conditioner
00119 void HomgInterestPointSet::set_conditioner(const HomgMetric& c)
00120 {
00121   delete_conditioner();
00122   init_conditioner(c);
00123 }
00124 
00125 void HomgInterestPointSet::init_conditioner(const HomgMetric& c)
00126 {
00127   conditioner_ = c;
00128 }
00129 
00130 void HomgInterestPointSet::delete_conditioner()
00131 {
00132 }
00133 
00134 //: Clear corner set.
00135 void HomgInterestPointSet::clear()
00136 {
00137   delete data_;
00138   data_ = new HomgInterestPointSetData;
00139   set_conditioner(0);
00140 }
00141 
00142 //: Destructor
00143 HomgInterestPointSet::~HomgInterestPointSet()
00144 {
00145   delete data_;
00146 }
00147 
00148 // Operations----------------------------------------------------------------
00149 //
00150 //: Add a corner to the end of the list
00151 bool HomgInterestPointSet::add(vgl_homg_point_2d<double> const& c)
00152 {
00153   return add(c.x()/c.w(),c.y()/c.w());
00154 }
00155 bool HomgInterestPointSet::add(const HomgPoint2D& c)
00156 {
00157   double x, y;
00158   c.get_nonhomogeneous(x,y);
00159   return add(x,y);
00160 }
00161 bool HomgInterestPointSet::add(const HomgInterestPoint& c)
00162 {
00163   return add(c.homg_);
00164 }
00165 //
00166 //: Add corner (x, y), using ImageMetric to convert to homogeneous.
00167 bool HomgInterestPointSet::add(double x, double y)
00168 {
00169   data_->push_back(HomgInterestPoint(x, y, conditioner_));
00170   return true;
00171 }
00172 
00173 //: Add a corner which has already been preconditioned by this cornerset's imagemetric.
00174 bool HomgInterestPointSet::add_preconditioned(vgl_homg_point_2d<double> const& h)
00175 {
00176   double x, y;
00177   conditioner_.homg_to_image(h, x, y);
00178   return add(x, y);
00179 }
00180 bool HomgInterestPointSet::add_preconditioned(const HomgPoint2D& h)
00181 {
00182   double x, y;
00183   conditioner_.homg_to_image(h, &x, &y);
00184   return add(x, y);
00185 }
00186 
00187 //: Return the number of corners in the set.
00188 unsigned HomgInterestPointSet::size() const
00189 {
00190   return data_->size();
00191 }
00192 
00193 // == ACCESSORS ==
00194 
00195 //: Return a reference to the i'th corner structure
00196 const HomgInterestPoint& HomgInterestPointSet::get(int i) const
00197 {
00198   return (*data_)[i];
00199 }
00200 
00201 HomgInterestPoint& HomgInterestPointSet::get(int i)
00202 {
00203   return (*data_)[i];
00204 }
00205 
00206 //: Return the i'th corner as a 2D point
00207 vnl_double_2 const& HomgInterestPointSet::get_2d(int i) const
00208 {
00209   return (*data_)[i].double2_;
00210 }
00211 
00212 //: Return the i'th corner as a 2D point
00213 vnl_vector_fixed<int,2> const& HomgInterestPointSet::get_int(int i) const
00214 {
00215   return (*data_)[i].int2_;
00216 }
00217 
00218 //: Return the i'th corner as a vgl_homg_point_2d<double>
00219 vgl_homg_point_2d<double> HomgInterestPointSet::homg_point(int i) const
00220 {
00221   assert(i >= 0 && i < int(data_->size()));
00222   HomgPoint2D& p = (*data_)[i].homg_;
00223   return vgl_homg_point_2d<double>(p.x(),p.y(),p.w());
00224 }
00225 
00226 //: Return the i'th corner as a HomgPoint2D
00227 const HomgPoint2D& HomgInterestPointSet::get_homg(int i) const
00228 {
00229   assert(i >= 0 && i < int(data_->size()));
00230   return (*data_)[i].homg_;
00231 }
00232 
00233 //: Return the i'th mean intensity
00234 float HomgInterestPointSet::get_mean_intensity(int i) const
00235 {
00236   assert(i >= 0 && i < int(data_->size()));
00237   float v = (*data_)[i].mean_intensity_;
00238   if (v == 0.0F) {
00239     vcl_cerr << "HomgInterestPointSet: WARNING mean_intensity["<<i<<"] = 0\n";
00240   }
00241   return v;
00242 }
00243 
00244 // Input/Output--------------------------------------------------------------
00245 
00246 // == INPUT/OUTPUT ==
00247 
00248 //: Load a corner set from a simple ASCII file of x y pairs.
00249 // If ImageMetric is supplied, it is used to convert image coordinates to
00250 // homogeneous form.
00251 bool HomgInterestPointSet::read(const char* filename, const HomgMetric& c)
00252 {
00253   vcl_ifstream f(filename);
00254   if (!f.good()) {
00255     vcl_cerr << "HomgInterestPointSet::read() -- Failed to open \"" << filename << "\"\n";
00256     return false;
00257   }
00258 
00259   return read(f, c);
00260 }
00261 
00262 bool HomgInterestPointSet::read(vcl_istream& f, const ImageMetric* c)
00263 {
00264   clear();
00265 
00266   set_conditioner(c);
00267 
00268   while (f.good()) {
00269     double x, y;
00270     f >> x >> y;
00271     if (!f.good())
00272       break;
00273     add(x, y);
00274     f >> vcl_ws;
00275   }
00276   return true;
00277 }
00278 
00279 //: Load a corner set from a simple ASCII file of x y pairs, and use vil1_image src to compute mean_intensities.
00280 // If ImageMetric is supplied, it is used to convert image coordinates to homogeneous form.
00281 // NOT YET IMPLEMENTED
00282 bool HomgInterestPointSet::read(const char* filename, vil1_image const& /*src*/, const HomgMetric& c)
00283 {
00284   if (!read(filename, c))
00285     return false;
00286 
00287 #if 1
00288   vcl_cerr << "HomgInterestPointSet::read() not implemented in any sense of the word\n";
00289 #else
00290   //vcl_cerr << "HomgInterestPointSet: Computing mean intensities\n";
00291   vil1_memory_image_of<unsigned char> imbuf(src);
00292   for (unsigned i=0; i< size(); i++) {
00293     ImageWindowOps winops(imbuf, get_int(i), 3);
00294     (*data_)[i].mean_intensity_ = winops.mean_intensity();
00295     if ((*data_)[i].mean_intensity_ == 0.0F) {
00296       //vcl_cerr << " note " << i << " had mi of 0\n";
00297       (*data_)[i].mean_intensity_ = 1e6;
00298     }
00299   }
00300 #endif
00301 
00302   return true;
00303 }
00304 
00305 //: Save a corner set as a simple ASCII file of x y pairs.
00306 bool HomgInterestPointSet::write(const char* filename) const
00307 {
00308   vcl_ofstream fout(filename);
00309   if (!fout.good()) {
00310     vcl_cerr << "HomgInterestPointSet::write() -- Failed to open \"" << filename << "\"\n";
00311     return false;
00312   }
00313   vcl_cerr << "HomgInterestPointSet: Saving corners to \"" << filename << "\"\n";
00314   return write(fout, get_conditioner());
00315 }
00316 
00317 bool HomgInterestPointSet::write(vcl_ostream& f, const ImageMetric*) const
00318 {
00319   for (unsigned i=0; i < size(); i++) {
00320     const vnl_double_2& p = get_2d(i);
00321     f << p[0] << " " << p[1] << "\n";
00322   }
00323   return true;
00324 }