00001 #include "mfpf_region_pdf_builder.h"
00002
00003
00004
00005
00006
00007 #include <mfpf/mfpf_region_pdf.h>
00008 #include <vsl/vsl_binary_loader.h>
00009 #include <vul/vul_string.h>
00010 #include <vcl_cmath.h>
00011 #include <vcl_sstream.h>
00012 #include <vcl_cassert.h>
00013
00014 #include <mbl/mbl_parse_block.h>
00015 #include <mbl/mbl_read_props.h>
00016 #include <mbl/mbl_exception.h>
00017
00018 #include <vil/vil_resample_bilin.h>
00019 #include <vsl/vsl_vector_io.h>
00020 #include <vsl/vsl_indent.h>
00021
00022 #include <vgl/vgl_point_2d.h>
00023 #include <vgl/vgl_vector_2d.h>
00024 #include <mfpf/mfpf_sample_region.h>
00025 #include <mfpf/mfpf_norm_vec.h>
00026 #include <mbl/mbl_data_array_wrapper.h>
00027
00028
00029
00030
00031
00032 mfpf_region_pdf_builder::mfpf_region_pdf_builder()
00033 {
00034 set_defaults();
00035 }
00036
00037
00038 void mfpf_region_pdf_builder::set_defaults()
00039 {
00040 step_size_=1.0;
00041 search_ni_=5;
00042 search_nj_=5;
00043 n_pixels_=0;
00044 roi_.resize(0);
00045 roi_ni_=0;
00046 roi_nj_=0;
00047 ref_x_=0;
00048 ref_y_=0;
00049 nA_=0;
00050 dA_=0.0;
00051 norm_method_=1;
00052 overlap_f_=1.0;
00053 }
00054
00055
00056
00057
00058
00059 mfpf_region_pdf_builder::~mfpf_region_pdf_builder()
00060 {
00061 }
00062
00063
00064 mfpf_point_finder* mfpf_region_pdf_builder::new_finder() const
00065 {
00066 return new mfpf_region_pdf();
00067 }
00068
00069
00070
00071
00072
00073 void mfpf_region_pdf_builder::set_region(const mfpf_region_form& form)
00074 {
00075 step_size_ = form.pose().scale();
00076
00077 if (form.form()=="box")
00078 {
00079 int ni = vcl_max(1,int(0.99+form.wi()));
00080 int nj = vcl_max(1,int(0.99+form.wj()));
00081 set_as_box(unsigned(ni),unsigned(nj),0.5*ni,0.5*nj);
00082 }
00083 else
00084 if (form.form()=="ellipse")
00085 {
00086 double ri = vcl_max(1.0,form.wi());
00087 double rj = vcl_max(1.0,form.wj());
00088 set_as_ellipse(ri,rj);
00089 }
00090 else
00091 {
00092 vcl_cerr<<"mfpf_region_pdf_builder::set_region : Unknown form: "<<form<<vcl_endl;
00093 vcl_abort();
00094 }
00095 }
00096
00097
00098
00099
00100 void mfpf_region_pdf_builder::set_region_size(double wi, double wj)
00101 {
00102 wi/=step_size();
00103 wj/=step_size();
00104 int ni = vcl_max(1,int(0.99+wi));
00105 int nj = vcl_max(1,int(0.99+wj));
00106 set_as_box(unsigned(ni),unsigned(nj),0.5*(ni-1),0.5*(nj-1));
00107 }
00108
00109
00110
00111 void mfpf_region_pdf_builder::set_as_box(unsigned ni, unsigned nj,
00112 double ref_x, double ref_y,
00113 const vpdfl_builder_base& builder)
00114 {
00115 set_as_box(ni,nj,ref_x,ref_y);
00116 pdf_builder_ = builder.clone();
00117 }
00118
00119
00120 void mfpf_region_pdf_builder::set_as_box(unsigned ni, unsigned nj,
00121 double ref_x, double ref_y)
00122 {
00123 roi_ni_=ni; roi_nj_=nj;
00124 n_pixels_ = ni*nj;
00125
00126
00127 roi_.resize(nj);
00128 for (unsigned j=0;j<nj;++j) roi_[j]=mbl_chord(0,ni-1,j);
00129
00130 ref_x_=ref_x;
00131 ref_y_=ref_y;
00132 }
00133
00134
00135
00136 void mfpf_region_pdf_builder::set_as_box(unsigned ni, unsigned nj,
00137 const vpdfl_builder_base& builder)
00138 {
00139 set_as_box(ni,nj, 0.5*(ni-1),0.5*(nj-1), builder);
00140 }
00141
00142
00143
00144 void mfpf_region_pdf_builder::set_as_ellipse(double ri, double rj,
00145 const vpdfl_builder_base& builder)
00146 {
00147 set_as_ellipse(ri,rj);
00148 pdf_builder_ = builder.clone();
00149 }
00150
00151
00152
00153 void mfpf_region_pdf_builder::set_as_ellipse(double ri, double rj)
00154 {
00155 ri+=1e-6; rj+=1e-6;
00156 int ni=int(ri);
00157 int nj=int(rj);
00158 roi_.resize(0);
00159 n_pixels_=0;
00160 for (int j = -nj;j<=nj;++j)
00161 {
00162
00163 int x = int(ri*vcl_sqrt(1.0-j*j/(rj*rj)));
00164 roi_.push_back(mbl_chord(ni-x,ni+x,nj+j));
00165 n_pixels_+=2*x+1;
00166 }
00167
00168 ref_x_=ni;
00169 ref_y_=nj;
00170 roi_ni_=2*ni+1;
00171 roi_nj_=2*nj+1;
00172 }
00173
00174
00175
00176 void mfpf_region_pdf_builder::clear(unsigned n_egs)
00177 {
00178 data_.resize(0);
00179 }
00180
00181
00182 void mfpf_region_pdf_builder::add_one_example(
00183 const vimt_image_2d_of<float>& image,
00184 const vgl_point_2d<double>& p,
00185 const vgl_vector_2d<double>& u)
00186 {
00187 vgl_vector_2d<double> u1=step_size_*u;
00188 vgl_vector_2d<double> v1(-u1.y(),u1.x());
00189
00190 unsigned np=image.image().nplanes();
00191
00192 vil_image_view<float> sample(roi_ni_,roi_nj_,1,np);
00193
00194 const vgl_point_2d<double> p0 = p-ref_x_*u1-ref_y_*v1;
00195
00196 const vimt_transform_2d& s_w2i = image.world2im();
00197 vgl_point_2d<double> im_p0 = s_w2i(p0);
00198 vgl_vector_2d<double> im_u = s_w2i.delta(p0, u1);
00199 vgl_vector_2d<double> im_v = s_w2i.delta(p0, v1);
00200
00201 vil_resample_bilin(image.image(),sample,
00202 im_p0.x(),im_p0.y(), im_u.x(),im_u.y(),
00203 im_v.x(),im_v.y(),roi_ni_,roi_nj_);
00204
00205 vnl_vector<double> v(n_pixels_*sample.nplanes());
00206 mfpf_sample_region(sample.top_left_ptr(),sample.jstep(),
00207 np,roi_,v);
00208
00209 if (norm_method_==1) mfpf_norm_vec(v);
00210 data_.push_back(v);
00211 }
00212
00213
00214 void mfpf_region_pdf_builder::add_example(const vimt_image_2d_of<float>& image,
00215 const vgl_point_2d<double>& p,
00216 const vgl_vector_2d<double>& u)
00217 {
00218 if (nA_==0)
00219 {
00220 add_one_example(image,p,u);
00221 return;
00222 }
00223
00224 vgl_vector_2d<double> v(-u.y(),u.x());
00225 for (int iA=-int(nA_);iA<=(int)nA_;++iA)
00226 {
00227 double A = iA*dA_;
00228 vgl_vector_2d<double> uA = u*vcl_cos(A)+v*vcl_sin(A);
00229 add_one_example(image,p,uA);
00230 }
00231 }
00232
00233
00234 void mfpf_region_pdf_builder::build(mfpf_point_finder& pf)
00235 {
00236 assert(pf.is_a()=="mfpf_region_pdf");
00237 mfpf_region_pdf& rp = static_cast<mfpf_region_pdf&>(pf);
00238
00239 vpdfl_pdf_base *pdf = pdf_builder().new_model();
00240
00241 if (data_.size()==1)
00242 pdf_builder().build(*pdf,data_[0]);
00243 else
00244 {
00245 mbl_data_array_wrapper<vnl_vector<double> > data(&data_[0],
00246 data_.size());
00247 pdf_builder().build(*pdf,data);
00248 }
00249
00250 rp.set(roi_,ref_x_,ref_y_,*pdf,norm_method_);
00251 set_base_parameters(rp);
00252 rp.set_overlap_f(overlap_f_);
00253
00254
00255 delete pdf;
00256 data_.resize(0);
00257 }
00258
00259
00260
00261 void mfpf_region_pdf_builder::config_as_box(vcl_istream &is)
00262 {
00263
00264 vcl_string s = mbl_parse_block(is);
00265 vcl_istringstream ss(s);
00266 mbl_read_props_type props = mbl_read_props_ws(ss);
00267
00268 unsigned ni=5,nj=5;
00269
00270 if (props.find("ni")!=props.end())
00271 {
00272 ni=vul_string_atoi(props["ni"]);
00273 props.erase("ni");
00274 }
00275 if (props.find("nj")!=props.end())
00276 {
00277 nj=vul_string_atoi(props["nj"]);
00278 props.erase("nj");
00279 }
00280
00281 if (props.find("ref_x")!=props.end())
00282 {
00283 ref_x_=vul_string_atof(props["ref_x"]);
00284 props.erase("ref_x");
00285 }
00286 else ref_x_=0.5*(ni-1.0);
00287
00288 if (props.find("ref_y")!=props.end())
00289 {
00290 ref_y_=vul_string_atof(props["ref_y"]);
00291 props.erase("ref_y");
00292 }
00293 else ref_y_=0.5*(nj-1.0);
00294
00295
00296 mbl_read_props_look_for_unused_props(
00297 "mfpf_region_pdf_builder::config_as_box",
00298 props, mbl_read_props_type());
00299
00300 set_as_box(ni,nj,ref_x_,ref_y_);
00301 }
00302
00303
00304
00305 void mfpf_region_pdf_builder::config_as_ellipse(vcl_istream &is)
00306 {
00307
00308 vcl_string s = mbl_parse_block(is);
00309 vcl_istringstream ss(s);
00310 mbl_read_props_type props = mbl_read_props_ws(ss);
00311
00312 double ri=3.1,rj=3.1;
00313 if (props.find("ri")!=props.end())
00314 {
00315 ri=vul_string_atof(props["ri"]);
00316 props.erase("ri");
00317 }
00318
00319 if (props.find("rj")!=props.end())
00320 {
00321 rj=vul_string_atof(props["rj"]);
00322 props.erase("rj");
00323 }
00324
00325
00326 mbl_read_props_look_for_unused_props(
00327 "mfpf_region_pdf_builder::config_as_ellipse",
00328 props, mbl_read_props_type());
00329
00330 set_as_ellipse(ri,rj);
00331 }
00332
00333
00334
00335
00336
00337
00338 bool mfpf_region_pdf_builder::set_from_stream(vcl_istream &is)
00339 {
00340
00341 vcl_string s = mbl_parse_block(is);
00342 vcl_istringstream ss(s);
00343 mbl_read_props_type props = mbl_read_props_ws(ss);
00344
00345 set_defaults();
00346
00347
00348 parse_base_props(props);
00349
00350 if (props.find("shape")!=props.end())
00351 {
00352 vcl_istringstream shape_s(props["shape"]);
00353 shape_s>>shape_;
00354 if (shape_=="box")
00355 {
00356
00357 config_as_box(shape_s);
00358 }
00359 else
00360 if (shape_=="ellipse")
00361 {
00362
00363 config_as_ellipse(shape_s);
00364 }
00365 else throw mbl_exception_parse_error("Unknown shape: "+shape_);
00366
00367 props.erase("shape");
00368 }
00369
00370 if (props.find("norm")!=props.end())
00371 {
00372 if (props["norm"]=="none") norm_method_=0;
00373 else
00374 if (props["norm"]=="linear") norm_method_=1;
00375 else throw mbl_exception_parse_error("Unknown norm: "+props["norm"]);
00376
00377 props.erase("norm");
00378 }
00379
00380 if (props.find("nA")!=props.end())
00381 {
00382 nA_=vul_string_atoi(props["nA"]);
00383 props.erase("nA");
00384 }
00385
00386 if (props.find("dA")!=props.end())
00387 {
00388 dA_=vul_string_atof(props["dA"]);
00389 props.erase("dA");
00390 }
00391
00392 overlap_f_=vul_string_atof(props.get_optional_property("overlap_f",
00393 "1.0"));
00394
00395 if (props.find("pdf_builder")!=props.end())
00396 {
00397 vcl_istringstream b_ss(props["pdf_builder"]);
00398 vcl_auto_ptr<vpdfl_builder_base> bb =
00399 vpdfl_builder_base::new_pdf_builder_from_stream(b_ss);
00400 pdf_builder_ = bb->clone();
00401 props.erase("pdf_builder");
00402 }
00403
00404
00405 mbl_read_props_look_for_unused_props(
00406 "mfpf_region_pdf_builder::set_from_stream", props, mbl_read_props_type());
00407 return true;
00408 }
00409
00410
00411
00412
00413
00414 vcl_string mfpf_region_pdf_builder::is_a() const
00415 {
00416 return vcl_string("mfpf_region_pdf_builder");
00417 }
00418
00419
00420 mfpf_point_finder_builder* mfpf_region_pdf_builder::clone() const
00421 {
00422 return new mfpf_region_pdf_builder(*this);
00423 }
00424
00425
00426
00427
00428
00429 void mfpf_region_pdf_builder::print_summary(vcl_ostream& os) const
00430 {
00431 os << "{ size: " << roi_ni_ << 'x' << roi_nj_
00432 << " n_pixels: " << n_pixels_
00433 << " ref_pt: (" << ref_x_ << ',' << ref_y_ << ')' <<'\n';
00434 vsl_indent_inc(os);
00435 if (norm_method_==0) os<<vsl_indent()<<"norm: none"<<'\n';
00436 else os<<vsl_indent()<<"norm: linear"<<'\n';
00437 os <<vsl_indent()<< "pdf_builder: ";
00438 if (pdf_builder_.ptr()==0) os << '-'<<'\n';
00439 else os << pdf_builder_<<'\n';
00440 os <<vsl_indent()<< "nA: " << nA_ << " dA: " << dA_ << ' '<<'\n'
00441 <<vsl_indent();
00442 mfpf_point_finder_builder::print_summary(os);
00443 os <<'\n' <<vsl_indent()<<"overlap_f: "<<overlap_f_<<'\n';
00444 vsl_indent_dec(os);
00445 os <<vsl_indent()<< '}';
00446 }
00447
00448 void mfpf_region_pdf_builder::print_shape(vcl_ostream& os) const
00449 {
00450 vil_image_view<vxl_byte> im(roi_ni_,roi_nj_);
00451 im.fill(0);
00452 for (unsigned k=0;k<roi_.size();++k)
00453 for (int i=roi_[k].start_x();i<=roi_[k].end_x();++i)
00454 im(i,roi_[k].y())=1;
00455 for (unsigned j=0;j<im.nj();++j)
00456 {
00457 for (unsigned i=0;i<im.ni();++i)
00458 if (im(i,j)==0) os<<' ';
00459 else os<<'X';
00460 os<<'\n';
00461 }
00462 }
00463
00464
00465 short mfpf_region_pdf_builder::version_no() const
00466 {
00467 return 1;
00468 }
00469
00470 void mfpf_region_pdf_builder::b_write(vsl_b_ostream& bfs) const
00471 {
00472 vsl_b_write(bfs,version_no());
00473 mfpf_point_finder_builder::b_write(bfs);
00474 vsl_b_write(bfs,roi_);
00475 vsl_b_write(bfs,roi_ni_);
00476 vsl_b_write(bfs,roi_nj_);
00477 vsl_b_write(bfs,n_pixels_);
00478 vsl_b_write(bfs,ref_x_);
00479 vsl_b_write(bfs,ref_y_);
00480 vsl_b_write(bfs,nA_);
00481 vsl_b_write(bfs,dA_);
00482 vsl_b_write(bfs,pdf_builder_);
00483 vsl_b_write(bfs,norm_method_);
00484 vsl_b_write(bfs,data_);
00485 vsl_b_write(bfs,overlap_f_);
00486 }
00487
00488
00489
00490
00491
00492 void mfpf_region_pdf_builder::b_read(vsl_b_istream& bfs)
00493 {
00494 if (!bfs) return;
00495 short version;
00496 vsl_b_read(bfs,version);
00497 switch (version)
00498 {
00499 case (1):
00500 case (2):
00501 mfpf_point_finder_builder::b_read(bfs);
00502 vsl_b_read(bfs,roi_);
00503 vsl_b_read(bfs,roi_ni_);
00504 vsl_b_read(bfs,roi_nj_);
00505 vsl_b_read(bfs,n_pixels_);
00506 vsl_b_read(bfs,ref_x_);
00507 vsl_b_read(bfs,ref_y_);
00508 vsl_b_read(bfs,nA_);
00509 vsl_b_read(bfs,dA_);
00510 vsl_b_read(bfs,pdf_builder_);
00511 vsl_b_read(bfs,norm_method_);
00512 vsl_b_read(bfs,data_);
00513 if (version==1) overlap_f_=1.0;
00514 else vsl_b_read(bfs,overlap_f_);
00515 break;
00516 default:
00517 vcl_cerr << "I/O ERROR: vsl_b_read(vsl_b_istream&)\n"
00518 << " Unknown version number "<< version << vcl_endl;
00519 bfs.is().clear(vcl_ios::badbit);
00520 return;
00521 }
00522 }