00001 #include "mfpf_region_pdf.h"
00002
00003
00004
00005
00006
00007 #include <vsl/vsl_binary_loader.h>
00008 #include <vcl_cmath.h>
00009 #include <vcl_cassert.h>
00010
00011 #include <vil/vil_resample_bilin.h>
00012 #include <vil/io/vil_io_image_view.h>
00013 #include <vsl/vsl_vector_io.h>
00014 #include <vsl/vsl_indent.h>
00015 #include <vnl/vnl_vector_ref.h>
00016
00017 #include <vgl/vgl_point_2d.h>
00018 #include <vgl/vgl_vector_2d.h>
00019 #include <mfpf/mfpf_sample_region.h>
00020 #include <mfpf/mfpf_norm_vec.h>
00021
00022
00023
00024
00025
00026 mfpf_region_pdf::mfpf_region_pdf()
00027 {
00028 set_defaults();
00029 }
00030
00031
00032 void mfpf_region_pdf::set_defaults()
00033 {
00034 step_size_=1.0;
00035 search_ni_=5;
00036 search_nj_=5;
00037 nA_=0; dA_=0.0;
00038 ns_=0; ds_=1.0;
00039 n_pixels_=0;
00040 roi_.resize(0);
00041 roi_ni_=0;
00042 roi_nj_=0;
00043 ref_x_=0;
00044 ref_y_=0;
00045 norm_method_=1;
00046 overlap_f_=1.0;
00047 }
00048
00049
00050
00051
00052
00053 mfpf_region_pdf::~mfpf_region_pdf()
00054 {
00055 }
00056
00057
00058 void mfpf_region_pdf::set(const vcl_vector<mbl_chord>& roi,
00059 double ref_x, double ref_y,
00060 const vpdfl_pdf_base& pdf,
00061 short norm_method)
00062 {
00063 pdf_ = pdf.clone();
00064 ref_x_ = ref_x;
00065 ref_y_ = ref_y;
00066
00067
00068 if (roi.size()==0) { roi_ni_=0; roi_nj_=0; return; }
00069 int ilo=roi[0].start_x(), ihi=roi[0].end_x();
00070 int jlo=roi[0].y(), jhi=roi[0].y();
00071
00072 for (unsigned k=1;k<roi.size();++k)
00073 {
00074 if (roi[k].start_x()<ilo) ilo=roi[k].start_x();
00075 if (roi[k].end_x()>ihi) ihi=roi[k].end_x();
00076 if (roi[k].y()<jlo) jlo=roi[k].y();
00077 if (roi[k].y()>jhi) jhi=roi[k].y();
00078 }
00079 roi_ni_=1+ihi-ilo;
00080 roi_nj_=1+jhi-jlo;
00081
00082
00083 ref_x_-=ilo; ref_y_-=jlo;
00084 roi_.resize(roi.size());
00085 n_pixels_=0;
00086 for (unsigned k=0;k<roi.size();++k)
00087 {
00088 roi_[k]= mbl_chord(roi[k].start_x()-ilo,
00089 roi[k].end_x()-ilo, roi[k].y()-jlo);
00090 n_pixels_+=1+roi[k].end_x()-roi[k].start_x();
00091 }
00092
00093 assert(norm_method>=0 && norm_method<=1);
00094 norm_method_ = norm_method;
00095 }
00096
00097
00098
00099 void mfpf_region_pdf::set_overlap_f(double f)
00100 {
00101 overlap_f_=f;
00102 }
00103
00104
00105
00106 double mfpf_region_pdf::radius() const
00107 {
00108
00109 double wx = roi_ni_-1;
00110 double x2 = vcl_max(ref_x_*ref_x_,(ref_x_-wx)*(ref_x_-wx));
00111 double wy = roi_nj_-1;
00112 double y2 = vcl_max(ref_y_*ref_y_,(ref_y_-wy)*(ref_y_-wy));
00113 double r2 = x2+y2;
00114 if (r2<=1) return 1.0;
00115 return vcl_sqrt(r2);
00116 }
00117
00118
00119
00120
00121 double mfpf_region_pdf::evaluate(const vimt_image_2d_of<float>& image,
00122 const vgl_point_2d<double>& p,
00123 const vgl_vector_2d<double>& u)
00124 {
00125 vgl_vector_2d<double> u1=step_size_*u;
00126 vgl_vector_2d<double> v1(-u1.y(),u1.x());
00127
00128 unsigned np=image.image().nplanes();
00129
00130 vil_image_view<float> sample(roi_ni_,roi_nj_,1,np);
00131
00132 const vgl_point_2d<double> p0 = p-ref_x_*u1-ref_y_*v1;
00133
00134 const vimt_transform_2d& s_w2i = image.world2im();
00135 vgl_point_2d<double> im_p0 = s_w2i(p0);
00136 vgl_vector_2d<double> im_u = s_w2i.delta(p0, u1);
00137 vgl_vector_2d<double> im_v = s_w2i.delta(p0, v1);
00138
00139 vil_resample_bilin(image.image(),sample,
00140 im_p0.x(),im_p0.y(), im_u.x(),im_u.y(),
00141 im_v.x(),im_v.y(),
00142 roi_ni_,roi_nj_);
00143
00144 vnl_vector<double> v(n_pixels_*sample.nplanes());
00145 mfpf_sample_region(sample.top_left_ptr(),sample.jstep(),
00146 np,roi_,v);
00147
00148 if (norm_method_==1) mfpf_norm_vec(v);
00149 return -1*pdf().log_p(v);
00150 }
00151
00152
00153
00154
00155
00156
00157
00158
00159 void mfpf_region_pdf::evaluate_region(
00160 const vimt_image_2d_of<float>& image,
00161 const vgl_point_2d<double>& p,
00162 const vgl_vector_2d<double>& u,
00163 vimt_image_2d_of<double>& response)
00164 {
00165 int ni=1+2*search_ni_;
00166 int nj=1+2*search_nj_;
00167 int nsi = 2*search_ni_ + roi_ni_;
00168 int nsj = 2*search_nj_ + roi_nj_;
00169
00170 unsigned np=image.image().nplanes();
00171
00172 vil_image_view<float> sample(nsi,nsj,1,np);
00173 vgl_vector_2d<double> u1=step_size_*u;
00174 vgl_vector_2d<double> v1(-u1.y(),u1.x());
00175 const vgl_point_2d<double> p0 = p-(search_ni_+ref_x_)*u1
00176 -(search_nj_+ref_y_)*v1;
00177
00178 const vimt_transform_2d& s_w2i = image.world2im();
00179 vgl_point_2d<double> im_p0 = s_w2i(p0);
00180 vgl_vector_2d<double> im_u = s_w2i.delta(p0, u1);
00181 vgl_vector_2d<double> im_v = s_w2i.delta(p0, v1);
00182
00183 vil_resample_bilin(image.image(),sample,
00184 im_p0.x(),im_p0.y(), im_u.x(),im_u.y(),
00185 im_v.x(),im_v.y(),
00186 nsi,nsj);
00187
00188 vnl_vector<double> v(n_pixels_*np);
00189
00190 response.image().set_size(ni,nj);
00191 double* r = response.image().top_left_ptr();
00192 const float* s = sample.top_left_ptr();
00193 vcl_ptrdiff_t r_jstep = response.image().jstep();
00194 vcl_ptrdiff_t s_jstep = sample.jstep();
00195
00196 for (unsigned j=0;j<(unsigned)nj;++j,r+=r_jstep,s+=s_jstep)
00197 {
00198 for (int i=0;i<ni;++i)
00199 {
00200 mfpf_sample_region(s+i*np,s_jstep,np,roi_,v);
00201 if (norm_method_==1) mfpf_norm_vec(v);
00202 r[i] = -1*pdf().log_p(v);
00203 }
00204 }
00205
00206
00207
00208
00209
00210 const vgl_point_2d<double> p1 = p-search_ni_*u1-search_nj_*v1;
00211
00212 vimt_transform_2d i2w;
00213 i2w.set_similarity(vgl_point_2d<double>(u1.x(),u1.y()),p1);
00214 response.set_world2im(i2w.inverse());
00215 }
00216
00217
00218
00219
00220
00221 double mfpf_region_pdf::search_one_pose(const vimt_image_2d_of<float>& image,
00222 const vgl_point_2d<double>& p,
00223 const vgl_vector_2d<double>& u,
00224 vgl_point_2d<double>& new_p)
00225 {
00226 int ni=1+2*search_ni_;
00227 int nj=1+2*search_nj_;
00228 int nsi = 2*search_ni_ + roi_ni_;
00229 int nsj = 2*search_nj_ + roi_nj_;
00230
00231 unsigned np=image.image().nplanes();
00232
00233 vil_image_view<float> sample(nsi,nsj,1,np);
00234 vgl_vector_2d<double> u1=step_size_*u;
00235 vgl_vector_2d<double> v1(-u1.y(),u1.x());
00236 const vgl_point_2d<double> p0 = p-(search_ni_+ref_x_)*u1
00237 -(search_nj_+ref_y_)*v1;
00238
00239 const vimt_transform_2d& s_w2i = image.world2im();
00240 vgl_point_2d<double> im_p0 = s_w2i(p0);
00241 vgl_vector_2d<double> im_u = s_w2i.delta(p0, u1);
00242 vgl_vector_2d<double> im_v = s_w2i.delta(p0, v1);
00243
00244 vil_resample_bilin(image.image(),sample,
00245 im_p0.x(),im_p0.y(), im_u.x(),im_u.y(),
00246 im_v.x(),im_v.y(),
00247 nsi,nsj);
00248
00249 vnl_vector<double> v(n_pixels_*np);
00250
00251 const float* s = sample.top_left_ptr();
00252 vcl_ptrdiff_t s_jstep = sample.jstep();
00253
00254 double best_r=9.99e9;
00255 int best_i=0,best_j=0;
00256 for (unsigned j=0;j<(unsigned)nj;++j,s+=s_jstep)
00257 {
00258 for (int i=0;i<ni;++i)
00259 {
00260 mfpf_sample_region(s+i*np,s_jstep,np,roi_,v);
00261 if (norm_method_==1) mfpf_norm_vec(v);
00262 double r = -1*pdf().log_p(v);
00263 if (r<best_r) { best_r=r; best_i=i; best_j=j; }
00264 }
00265 }
00266
00267
00268 new_p = p+(best_i-search_ni_)*u1+(best_j-search_nj_)*v1;
00269 return best_r;
00270 }
00271
00272
00273 bool mfpf_region_pdf::is_inside(const mfpf_pose& pose,
00274 const vgl_point_2d<double>& p,
00275 double f) const
00276 {
00277
00278 vimt_transform_2d t1;
00279 t1.set_similarity(step_size()*pose.u(),pose.p());
00280
00281 vgl_point_2d<double> q=t1.inverse()(p);
00282 q.x()/=f; q.y()/=f;
00283 q.x()+=ref_x_;
00284 if (q.x()<0 || q.x()>(roi_ni_-1)) return false;
00285 q.y()+=ref_y_;
00286 if (q.y()<0 || q.y()>(roi_nj_-1)) return false;
00287 return true;
00288 }
00289
00290
00291
00292 bool mfpf_region_pdf::overlap(const mfpf_pose& pose1,
00293 const mfpf_pose& pose2) const
00294 {
00295 if (is_inside(pose1,pose2.p(),overlap_f_)) return true;
00296 if (is_inside(pose2,pose1.p(),overlap_f_)) return true;
00297 return false;
00298 }
00299
00300
00301
00302
00303 void mfpf_region_pdf::get_outline(vcl_vector<vgl_point_2d<double> >& pts) const
00304 {
00305 pts.resize(7);
00306 vgl_vector_2d<double> r(ref_x_,ref_y_);
00307 pts[0]=vgl_point_2d<double>(0,roi_nj_)-r;
00308 pts[1]=vgl_point_2d<double>(0,0);
00309 pts[2]=vgl_point_2d<double>(roi_ni_,roi_nj_)-r;
00310 pts[3]=vgl_point_2d<double>(0,roi_nj_)-r;
00311 pts[4]=vgl_point_2d<double>(0,0)-r;
00312 pts[5]=vgl_point_2d<double>(roi_ni_,0)-r;
00313 pts[6]=vgl_point_2d<double>(roi_ni_,roi_nj_)-r;
00314 }
00315
00316
00317 void mfpf_region_pdf::get_image_of_model(vimt_image_2d_of<vxl_byte>& image) const
00318 {
00319 vnl_vector<double> mean = pdf().mean();
00320
00321 assert(mean.size()>=n_pixels_);
00322
00323
00324 vnl_vector_ref<double> mean1(n_pixels_,mean.data_block());
00325 double min1=mean1.min_value();
00326 double max1=mean1.max_value();
00327 double s =255/(max1-min1);
00328 image.image().set_size(roi_ni_,roi_nj_);
00329 image.image().fill(0);
00330 unsigned q=0;
00331 for (unsigned k=0;k<roi_.size();++k)
00332 {
00333 for (int i=roi_[k].start_x();i<=roi_[k].end_x();++i,++q)
00334 image.image()(i,roi_[k].y())=vxl_byte(s*(mean[q]-min1));
00335 }
00336 vimt_transform_2d ref2im;
00337 ref2im.set_zoom_only(1.0/step_size_,ref_x_,ref_y_);
00338 image.set_world2im(ref2im);
00339 }
00340
00341
00342
00343
00344
00345 vcl_string mfpf_region_pdf::is_a() const
00346 {
00347 return vcl_string("mfpf_region_pdf");
00348 }
00349
00350
00351 mfpf_point_finder* mfpf_region_pdf::clone() const
00352 {
00353 return new mfpf_region_pdf(*this);
00354 }
00355
00356
00357
00358
00359
00360 void mfpf_region_pdf::print_summary(vcl_ostream& os) const
00361 {
00362 os << "{ size: "<<roi_ni_<<" x "<<roi_nj_
00363 << " n_pixels: "<<n_pixels_
00364 << " ref_pt: ("<<ref_x_<<','<<ref_y_<<')'<<'\n';
00365 vsl_indent_inc(os);
00366 if (norm_method_==0) os<<vsl_indent()<<"norm: none"<<'\n';
00367 else os<<vsl_indent()<<"norm: linear"<<'\n';
00368 os <<vsl_indent()<< "PDF: ";
00369 if (pdf_.ptr()==0) os << "--"<<vcl_endl; else os << pdf_<<'\n';
00370 os<<vsl_indent();
00371 mfpf_point_finder::print_summary(os);
00372 os <<vcl_endl <<vsl_indent()<<"overlap_f: "<<overlap_f_<<'\n';
00373 vsl_indent_dec(os);
00374 os<<vsl_indent()<<'}';
00375 }
00376
00377 void mfpf_region_pdf::print_shape(vcl_ostream& os) const
00378 {
00379 vil_image_view<vxl_byte> im(roi_ni_,roi_nj_);
00380 im.fill(0);
00381 for (unsigned k=0;k<roi_.size();++k)
00382 for (int i=roi_[k].start_x();i<=roi_[k].end_x();++i)
00383 im(i,roi_[k].y())=1;
00384 for (unsigned j=0;j<im.nj();++j)
00385 {
00386 for (unsigned i=0;i<im.ni();++i)
00387 if (im(i,j)==0) os<<' ';
00388 else os<<'X';
00389 os<<'\n';
00390 }
00391 }
00392
00393 short mfpf_region_pdf::version_no() const
00394 {
00395 return 1;
00396 }
00397
00398
00399 void mfpf_region_pdf::b_write(vsl_b_ostream& bfs) const
00400 {
00401 vsl_b_write(bfs,version_no());
00402 mfpf_point_finder::b_write(bfs);
00403 vsl_b_write(bfs,roi_);
00404 vsl_b_write(bfs,roi_ni_);
00405 vsl_b_write(bfs,roi_nj_);
00406 vsl_b_write(bfs,n_pixels_);
00407 vsl_b_write(bfs,pdf_);
00408 vsl_b_write(bfs,ref_x_);
00409 vsl_b_write(bfs,ref_y_);
00410 vsl_b_write(bfs,norm_method_);
00411 vsl_b_write(bfs,overlap_f_);
00412 }
00413
00414
00415
00416
00417
00418 void mfpf_region_pdf::b_read(vsl_b_istream& bfs)
00419 {
00420 if (!bfs) return;
00421 short version;
00422 vsl_b_read(bfs,version);
00423 switch (version)
00424 {
00425 case (1):
00426 case (2):
00427 mfpf_point_finder::b_read(bfs);
00428 vsl_b_read(bfs,roi_);
00429 vsl_b_read(bfs,roi_ni_);
00430 vsl_b_read(bfs,roi_nj_);
00431 vsl_b_read(bfs,n_pixels_);
00432 vsl_b_read(bfs,pdf_);
00433 vsl_b_read(bfs,ref_x_);
00434 vsl_b_read(bfs,ref_y_);
00435 vsl_b_read(bfs,norm_method_);
00436 if (version==1) overlap_f_=1.0;
00437 else vsl_b_read(bfs,overlap_f_);
00438 break;
00439 default:
00440 vcl_cerr << "I/O ERROR: vsl_b_read(vsl_b_istream&)\n"
00441 << " Unknown version number "<< version << vcl_endl;
00442 bfs.is().clear(vcl_ios::badbit);
00443 return;
00444 }
00445 }
00446
00447
00448 bool mfpf_region_pdf::operator==(const mfpf_region_pdf& nc) const
00449 {
00450 if (!base_equality(nc)) return false;
00451 if (roi_ni_!=nc.roi_ni_) return false;
00452 if (roi_nj_!=nc.roi_nj_) return false;
00453 if (norm_method_!=nc.norm_method_) return false;
00454 if (n_pixels_!=nc.n_pixels_) return false;
00455 if (vcl_fabs(ref_x_-nc.ref_x_)>1e-6) return false;
00456 if (vcl_fabs(ref_y_-nc.ref_y_)>1e-6) return false;
00457
00458 return true;
00459 }
00460
00461