00001 #include "mfpf_mr_point_finder_builder.h"
00002
00003
00004
00005
00006
00007 #include <mfpf/mfpf_mr_point_finder.h>
00008
00009 #include <vimt/vimt_image_pyramid.h>
00010 #include <vnl/vnl_math.h>
00011 #include <vgl/vgl_point_2d.h>
00012 #include <vgl/vgl_vector_2d.h>
00013 #include <vcl_cmath.h>
00014 #include <vcl_algorithm.h>
00015 #include <vcl_cassert.h>
00016 #include <vcl_cstdlib.h>
00017
00018 #include <vsl/vsl_indent.h>
00019 #include <vsl/vsl_binary_loader.h>
00020 #include <vsl/vsl_vector_io.h>
00021
00022
00023
00024
00025
00026 mfpf_mr_point_finder_builder::mfpf_mr_point_finder_builder()
00027 {
00028 }
00029
00030
00031 mfpf_mr_point_finder_builder::mfpf_mr_point_finder_builder(const mfpf_mr_point_finder_builder& b)
00032 {
00033 *this=b;
00034 }
00035
00036
00037 mfpf_mr_point_finder_builder& mfpf_mr_point_finder_builder::operator=(const mfpf_mr_point_finder_builder& b)
00038 {
00039 if (&b==this) return *this;
00040
00041 delete_all();
00042
00043
00044 unsigned n=b.size();
00045 builders_.resize(n);
00046 for (unsigned i=0;i<n;++i) builders_[i]=b.builders_[i]->clone();
00047
00048 return *this;
00049 }
00050
00051
00052
00053
00054
00055
00056 mfpf_mr_point_finder_builder::~mfpf_mr_point_finder_builder()
00057 {
00058 delete_all();
00059 }
00060
00061
00062 void mfpf_mr_point_finder_builder::delete_all()
00063 {
00064 for (unsigned i=0;i<builders_.size();++i)
00065 delete builders_[i];
00066 builders_.resize(0);
00067 }
00068
00069
00070
00071 void mfpf_mr_point_finder_builder::set(
00072 const vcl_vector<mfpf_point_finder_builder*>& builders)
00073 {
00074 delete_all();
00075 builders_.resize(builders.size());
00076 for (unsigned i=0;i<builders.size();++i)
00077 builders_[i]=builders[i]->clone();
00078 }
00079
00080
00081 void mfpf_mr_point_finder_builder::set_n_levels(unsigned n)
00082 {
00083 unsigned imax=builders_.size();
00084 builders_.resize(n);
00085 for (unsigned i=imax;i<n;i++)
00086 builders_[i]=builders_[imax]->clone();
00087 }
00088
00089
00090
00091
00092
00093
00094 void mfpf_mr_point_finder_builder::set(
00095 const mfpf_point_finder_builder& builder0,
00096 unsigned n, double step0, double scale_step)
00097 {
00098 delete_all();
00099 builders_.resize(n);
00100 for (unsigned i=0;i<n;++i)
00101 {
00102 builders_[i]=builder0.clone();
00103 builder(i).set_step_size(step0*vcl_pow(scale_step,int(i)));
00104 }
00105
00106 int dx = vcl_max(1,int(0.99+1.0/scale_step));
00107 double dA = builder0.search_dA();
00108 double ds = builder0.search_ds();
00109
00110 for (int i=n-2;i>=0;--i)
00111 {
00112
00113 dA*=0.7;
00114 ds = 1.0+0.7*(ds-1.0);
00115 builder(i).set_search_area(dx,dx);
00116 if (builder0.search_ns()>0)
00117 builder(i).set_search_scale_range(1,ds);
00118 if (builder0.search_nA()>0)
00119 builder(i).set_search_angle_range(1,dA);
00120 }
00121 }
00122
00123
00124
00125
00126 void mfpf_mr_point_finder_builder::set_region_size(double wi, double wj)
00127 {
00128 for (unsigned i=0;i<size();++i)
00129 {
00130 builder(i).set_region_size(wi,wj);
00131 }
00132 }
00133
00134 void mfpf_mr_point_finder_builder::set_size_and_levels(
00135 const mfpf_point_finder_builder& builder0,
00136 double wi, double wj,
00137 double scale_step,
00138 int min_n_samples,
00139 int max_n_samples,
00140 double base_pixel_width)
00141 {
00142
00143 double max_w = vcl_max(wi/base_pixel_width,wj/base_pixel_width);
00144
00145 double log_s = vcl_log(scale_step);
00146
00147
00148 int max_L = int(vcl_log(max_w/min_n_samples)/log_s);
00149
00150 int min_L = vnl_math_rnd(0.5+vcl_log(max_w/max_n_samples)/log_s);
00151 if (min_L>max_L) max_L=min_L;
00152
00153 double step0 = base_pixel_width*vcl_pow(scale_step,min_L);
00154 int n_levels = 1+max_L-min_L;
00155
00156 set(builder0,n_levels,step0,scale_step);
00157 set_region_size(wi,wj);
00158 }
00159
00160
00161
00162
00163
00164 unsigned mfpf_mr_point_finder_builder::image_level(
00165 unsigned i,
00166 const vgl_vector_2d<double>& u,
00167 const vimt_image_pyramid& im_pyr) const
00168 {
00169 double model_pixel_size = builder(i).step_size()*u.length();
00170 double rel_size0 = model_pixel_size/im_pyr.base_pixel_width();
00171
00172 double log_step = vcl_log(im_pyr.scale_step());
00173 int level = vnl_math_rnd(vcl_log(rel_size0)/log_step);
00174 if (level<im_pyr.lo()) return im_pyr.lo();
00175 if (level>im_pyr.hi()) return im_pyr.hi();
00176 return level;
00177 }
00178
00179
00180 static unsigned nearest_valid_level(const vimt_image_pyramid& im_pyr,
00181 unsigned level)
00182 {
00183 int L0=int(level);
00184 int bestL=0;
00185 int min_d2=999;
00186 for (int L=0;L<=im_pyr.hi();++L)
00187 {
00188 if (im_pyr(L).image_size()[0]>0)
00189 {
00190 int d2 = (L-L0)*(L-L0);
00191 if (d2<min_d2) { min_d2=d2; bestL=L; }
00192 }
00193 }
00194 return unsigned(bestL);
00195 }
00196
00197
00198
00199 void mfpf_mr_point_finder_builder::clear(unsigned n_egs)
00200 {
00201 for (unsigned i=0;i<size();++i) builder(i).clear(n_egs);
00202 }
00203
00204
00205 void mfpf_mr_point_finder_builder::get_sample_vector(
00206 const vimt_image_pyramid& image_pyr,
00207 const vgl_point_2d<double>& p,
00208 const vgl_vector_2d<double>& u,
00209 unsigned L,
00210 vcl_vector<double>& v)
00211 {
00212 assert( L<size() );
00213
00214 unsigned im_L = image_level(L,u,image_pyr);
00215
00216 if (image_pyr(im_L).image_size()[0]==0)
00217 {
00218 vcl_cerr<<"Image at level "<<im_L<<" in pyramid has not been set up.\n"
00219 <<"This is required for level "<<L<<" of the mfpf model.\n"
00220 <<"Check range for which pyramid is defined.\n";
00221
00222 im_L=nearest_valid_level(image_pyr,im_L);
00223 if (image_pyr(im_L).image_size()[0]==0)
00224 {
00225 vcl_cerr << "No image pyramid levels set up.\n";
00226 vcl_abort();
00227 }
00228 }
00229
00230 assert(image_pyr(im_L).is_a()=="vimt_image_2d_of<float>");
00231 const vimt_image_2d_of<float>& image
00232 = static_cast<const vimt_image_2d_of<float>&>(image_pyr(im_L));
00233
00234 builder(L).get_sample_vector(image,p,u,v);
00235 }
00236
00237
00238 void mfpf_mr_point_finder_builder::add_example(
00239 const vimt_image_pyramid& image_pyr,
00240 const vgl_point_2d<double>& p,
00241 const vgl_vector_2d<double>& u)
00242 {
00243 for (unsigned L=0;L<size();++L)
00244 {
00245 unsigned im_L = image_level(L,u,image_pyr);
00246
00247 if (image_pyr(im_L).image_size()[0]==0)
00248 {
00249 vcl_cerr << "Image at level "<<im_L<<" in pyramid has not been set up.\n"
00250 << "This is required for level "<<L<<" of the mfpf model.\n"
00251 << "Check range for which pyramid is defined.\n";
00252
00253 im_L=nearest_valid_level(image_pyr,im_L);
00254 if (image_pyr(im_L).image_size()[0]==0)
00255 {
00256 vcl_cerr << "No image pyramid levels set up.\n";
00257 vcl_abort();
00258 }
00259 }
00260
00261 assert(image_pyr(im_L).is_a()=="vimt_image_2d_of<float>");
00262 const vimt_image_2d_of<float>& image
00263 = static_cast<const vimt_image_2d_of<float>&>(image_pyr(im_L));
00264
00265 builder(L).add_example(image,p,u);
00266 }
00267 }
00268
00269
00270 void mfpf_mr_point_finder_builder::build(mfpf_mr_point_finder& mr_pf)
00271 {
00272 vcl_vector<mfpf_point_finder*> finders(size());
00273 for (unsigned i=0;i<size();++i)
00274 {
00275 finders[i] = builder(i).new_finder();
00276 builder(i).build(*finders[i]);
00277 }
00278
00279 mr_pf.set(finders);
00280
00281
00282 for (unsigned i=0;i<size();++i) delete finders[i];
00283 }
00284
00285
00286
00287
00288
00289 short mfpf_mr_point_finder_builder::version_no() const
00290 {
00291 return 1;
00292 }
00293
00294
00295
00296
00297
00298
00299 vcl_string mfpf_mr_point_finder_builder::is_a() const
00300 {
00301 return vcl_string("mfpf_mr_point_finder_builder");
00302 }
00303
00304
00305 void mfpf_mr_point_finder_builder::print_summary(vcl_ostream& os) const
00306 {
00307 os<<'\n';
00308 unsigned n=builders_.size();
00309 os<<vsl_indent()<<"n_builders: "<<n<<'\n';
00310 vsl_indent_inc(os);
00311 for (unsigned i=0;i<n;i++)
00312 {
00313 os<<vsl_indent()<<i<<") ";
00314 vsl_indent_inc(os);
00315 os<<builders_[i]<<'\n';
00316 vsl_indent_dec(os);
00317 }
00318 vsl_indent_dec(os);
00319 }
00320
00321
00322
00323
00324
00325 void mfpf_mr_point_finder_builder::b_write(vsl_b_ostream& bfs) const
00326 {
00327 vsl_b_write(bfs,version_no());
00328 vsl_b_write(bfs,builders_.size());
00329 for (unsigned i=0;i<builders_.size();++i)
00330 vsl_b_write(bfs,builders_[i]);
00331 }
00332
00333
00334
00335
00336
00337 void mfpf_mr_point_finder_builder::b_read(vsl_b_istream& bfs)
00338 {
00339 if (!bfs) return;
00340
00341 delete_all();
00342
00343 short version;
00344 vsl_b_read(bfs,version);
00345 unsigned n;
00346 switch (version)
00347 {
00348 case (1):
00349 vsl_b_read(bfs,n);
00350 builders_.resize(n);
00351 for (unsigned i=0;i<n;++i)
00352 {
00353 builders_[i]=0;
00354 vsl_b_read(bfs,builders_[i]);
00355 }
00356 break;
00357 default:
00358 vcl_cerr << "I/O ERROR: vsl_b_read(vsl_b_istream&)\n"
00359 << " Unknown version number "<< version << vcl_endl;
00360 bfs.is().clear(vcl_ios::badbit);
00361 return;
00362 }
00363 }
00364
00365
00366
00367
00368
00369 vcl_ostream& operator<<(vcl_ostream& os,const mfpf_mr_point_finder_builder& b)
00370 {
00371 os << b.is_a() << ": ";
00372 vsl_indent_inc(os);
00373 b.print_summary(os);
00374 vsl_indent_dec(os);
00375 return os;
00376 }
00377
00378
00379 void vsl_b_write(vsl_b_ostream& bfs, const mfpf_mr_point_finder_builder& b)
00380 {
00381 b.b_write(bfs);
00382 }
00383
00384
00385 void vsl_b_read(vsl_b_istream& bfs, mfpf_mr_point_finder_builder& b)
00386 {
00387 b.b_read(bfs);
00388 }
00389
00390