Go to the documentation of this file.00001
00002
00003
00004
00005
00006 #include "mfpf_dp_snake.h"
00007
00008 #include <vcl_cmath.h>
00009
00010 #include <vsl/vsl_indent.h>
00011 #include <vsl/vsl_binary_loader.h>
00012 #include <vsl/vsl_vector_io.h>
00013
00014 #include <vgl/vgl_point_2d.h>
00015 #include <vgl/vgl_vector_2d.h>
00016
00017 #include <mbl/mbl_dyn_prog.h>
00018 #include <mbl/mbl_stats_1d.h>
00019
00020
00021
00022
00023
00024 mfpf_dp_snake::mfpf_dp_snake()
00025 : max_its_(10)
00026 {
00027 }
00028
00029
00030
00031
00032
00033
00034 mfpf_dp_snake::~mfpf_dp_snake()
00035 {
00036 }
00037
00038
00039 mfpf_point_finder& mfpf_dp_snake::finder()
00040 {
00041 return finder_;
00042 }
00043
00044
00045
00046 void mfpf_dp_snake::set_to_circle(const mfpf_point_finder& finder,
00047 unsigned n_points,
00048 const vgl_point_2d<double>& c,
00049 double r)
00050 {
00051 finder_=finder;
00052
00053 pts_.resize(n_points);
00054 for (unsigned iA=0;iA<n_points;++iA)
00055 {
00056 double A = iA*6.283/n_points;
00057 double dx=vcl_cos(A),dy=vcl_sin(A);
00058 pts_[iA] = vgl_point_2d<double>(c.x()+r*dx,c.y()+r*dy);
00059 }
00060 }
00061
00062
00063 void mfpf_dp_snake::smooth_curve(
00064 vcl_vector<vgl_point_2d<double> >& src_pts,
00065 vcl_vector<vgl_point_2d<double> >& dest_pts)
00066 {
00067 unsigned n = src_pts.size();
00068 dest_pts.resize(n);
00069 for (unsigned i=0;i<n;++i)
00070 dest_pts[i] = centre(src_pts[(i+n-1)%n],src_pts[i],src_pts[(i+1)%n]);
00071 }
00072
00073
00074
00075
00076 double mfpf_dp_snake::update_step(const vimt_image_2d_of<float>& image)
00077 {
00078 unsigned n = pts_.size();
00079
00080 unsigned s_ni = finder().search_ni();
00081 unsigned nr = 1+2*s_ni;
00082
00083 vcl_vector<vgl_vector_2d<double> > u(n);
00084
00085
00086
00087 vcl_vector<vgl_point_2d<double> > ref_pts(n);
00088
00089
00090 vnl_matrix<double> D(n,nr);
00091
00092 int dt = 3;
00093
00094 vimt_image_2d_of<double> response;
00095
00096 for (unsigned i=0;i<n;++i)
00097 {
00098
00099 vgl_vector_2d<double> t = pts_[(i+n-dt)%n]-pts_[(i+dt)%n];
00100 t/=(t.length()+1e-6);
00101 double dx=-t.y(),dy=t.x();
00102 u[i]=vgl_vector_2d<double>(dx,dy);
00103
00104
00105 ref_pts[i] = centre(pts_[(i+n-1)%n],pts_[(i+1)%n]);
00106
00107 finder().evaluate_region(image,ref_pts[i],u[i],response);
00108
00109 for (unsigned j=0;j<nr;++j)
00110 {
00111 double d= response.image()(j,0);
00112 D(i,j)=d;
00113 }
00114 }
00115
00116 mbl_dyn_prog dp;
00117 vnl_vector<double> move_cost(nr);
00118 double shape_k=1.0;
00119 for (unsigned int i=0;i<nr;++i)
00120 {
00121 move_cost[i]=shape_k*i;
00122 }
00123
00124 vcl_vector<int> x;
00125 dp.solve_loop(x,D,move_cost);
00126
00127
00128 double step_size = finder().step_size();
00129 double move_sum=0.0;
00130
00131 for (unsigned i=0;i<n;++i)
00132 {
00133
00134 vgl_point_2d<double> new_pt = ref_pts[i] + (x[i]-int(s_ni))*step_size*u[i];
00135
00136 move_sum += (new_pt-pts_[i]).length();
00137 pts_[i] = new_pt;
00138 }
00139
00140 return move_sum/n;
00141 }
00142
00143
00144 void mfpf_dp_snake::search(const vimt_image_2d_of<float>& image)
00145 {
00146
00147 for (unsigned i=0;i<max_its_;++i)
00148 update_step(image);
00149 }
00150
00151
00152
00153 void mfpf_dp_snake::smooth_curve()
00154 {
00155 vcl_vector<vgl_point_2d<double> > old_pts = pts_;
00156 smooth_curve(old_pts,pts_);
00157 }
00158
00159
00160 vgl_point_2d<double> mfpf_dp_snake::cog() const
00161 {
00162 unsigned n = pts_.size();
00163 if (n==0) return vgl_point_2d<double>(0,0);
00164
00165 double xsum=0,ysum=0;
00166 for (unsigned i=0;i<n;++i)
00167 {
00168 xsum+=pts_[i].x();
00169 ysum+=pts_[i].y();
00170 }
00171 return vgl_point_2d<double>(xsum/n,ysum/n);
00172 }
00173
00174
00175 double mfpf_dp_snake::mean_radius() const
00176 {
00177 unsigned n = pts_.size();
00178 if (n==0) return 0.0;
00179
00180 vgl_point_2d<double> c = cog();
00181 double r_sum=0.0;
00182 for (unsigned i=0;i<n;++i)
00183 r_sum += (pts_[i]-c).length();
00184 return r_sum/n;
00185 }
00186
00187
00188 void mfpf_dp_snake::radius_stats(double& mean, double& sd) const
00189 {
00190 mbl_stats_1d stats;
00191 unsigned n = pts_.size();
00192
00193 vgl_point_2d<double> c = cog();
00194 for (unsigned i=0;i<n;++i)
00195 stats.obs((pts_[i]-c).length());
00196
00197 mean=stats.mean();
00198 sd=stats.sd();
00199 }
00200
00201
00202
00203
00204
00205
00206 short mfpf_dp_snake::version_no() const
00207 {
00208 return 1;
00209 }
00210
00211
00212
00213
00214
00215
00216 vcl_string mfpf_dp_snake::is_a() const
00217 {
00218 return vcl_string("mfpf_dp_snake");
00219 }
00220
00221
00222 void mfpf_dp_snake::print_summary(vcl_ostream& os) const
00223 {
00224 vsl_indent_inc(os);
00225
00226 os<<vsl_indent()<<"n_points: "<<pts_.size()
00227 <<vsl_indent()<<"finder: "<<finder_<<'\n';
00228 vgl_point_2d<double> c = cog();
00229 os<<vsl_indent()<<" CoG: ("<<c.x()<<','<<c.y();
00230
00231 double r_mean,r_sd;
00232 radius_stats(r_mean,r_sd);
00233 os<<") mean radius: "<<r_mean<<" SD: "<<r_sd<<'\n';
00234 vsl_indent_dec(os);
00235 }
00236
00237
00238
00239
00240
00241 void mfpf_dp_snake::b_write(vsl_b_ostream& bfs) const
00242 {
00243 vsl_b_write(bfs,version_no());
00244 vsl_b_write(bfs,max_its_);
00245 vsl_b_write(bfs,finder_);
00246 vsl_b_write(bfs,pts_);
00247 }
00248
00249
00250
00251
00252
00253 void mfpf_dp_snake::b_read(vsl_b_istream& bfs)
00254 {
00255 if (!bfs) return;
00256 short version;
00257 vsl_b_read(bfs,version);
00258 switch (version)
00259 {
00260 case (1):
00261 vsl_b_read(bfs,max_its_);
00262 vsl_b_read(bfs,finder_);
00263 vsl_b_read(bfs,pts_);
00264 break;
00265 default:
00266 vcl_cerr << "I/O ERROR: vsl_b_read(vsl_b_istream&)\n"
00267 << " Unknown version number "<< version << vcl_endl;
00268 bfs.is().clear(vcl_ios::badbit);
00269 return;
00270 }
00271 }
00272
00273
00274
00275
00276
00277 vcl_ostream& operator<<(vcl_ostream& os,const mfpf_dp_snake& b)
00278 {
00279 os << b.is_a() << ": ";
00280 vsl_indent_inc(os);
00281 b.print_summary(os);
00282 vsl_indent_dec(os);
00283 return os;
00284 }
00285
00286
00287 void vsl_b_write(vsl_b_ostream& bfs, const mfpf_dp_snake& b)
00288 {
00289 b.b_write(bfs);
00290 }
00291
00292
00293 void vsl_b_read(vsl_b_istream& bfs, mfpf_dp_snake& b)
00294 {
00295 b.b_read(bfs);
00296 }
00297