Go to the documentation of this file.00001
00002 #include "vifa_group_pgram.h"
00003
00004
00005
00006 #include <vcl_cmath.h>
00007 #include <vnl/vnl_math.h>
00008 #include <vgl/vgl_point_2d.h>
00009 #include <vgl/vgl_vector_2d.h>
00010 #include <vgl/vgl_clip.h>
00011
00012 #ifndef DEGTORAD
00013 #define DEGTORAD (vnl_math::pi_over_180)
00014 #endif
00015
00016
00017 vifa_group_pgram::
00018 vifa_group_pgram(imp_line_list& lg,
00019 const vifa_group_pgram_params& old_params,
00020 double angle_range)
00021 : vifa_group_pgram_params(old_params)
00022 {
00023 angle_range_ = angle_range;
00024 th_dim_ = (int)vcl_ceil(angle_range_/angle_increment());
00025 th_dim_++;
00026 bb_ = new vifa_bbox;
00027
00028 for (int i = 0; i < th_dim_; i++)
00029 {
00030 imp_line_list* illp = new imp_line_list;
00031 curves_.push_back(illp);
00032 }
00033 this->Index(lg);
00034 }
00035
00036
00037
00038 vifa_group_pgram::
00039 ~vifa_group_pgram()
00040 {
00041 for (imp_line_table::iterator ilti = curves_.begin(); ilti != curves_.end();
00042 ilti++)
00043 {
00044 imp_line_list* illp = (*ilti);
00045 for (imp_line_iterator ili = illp->begin(); ili != illp->end(); ili++)
00046 {
00047 (*ili) = 0;
00048 }
00049
00050 delete illp;
00051 }
00052 }
00053
00054
00055
00056 void vifa_group_pgram::
00057 Index(imp_line_sptr il)
00058 {
00059 int ang_bin = this->AngleLoc(il);
00060 curves_[ang_bin]->push_back(il);
00061
00062 this->touch();
00063 }
00064
00065
00066
00067 void vifa_group_pgram::
00068 Index(imp_line_list& lg)
00069 {
00070 for (imp_line_iterator ili = lg.begin(); ili != lg.end(); ili++)
00071 Index(*ili);
00072 }
00073
00074
00075
00076 void vifa_group_pgram::
00077 Clear()
00078 {
00079 for (imp_line_table::iterator ilti = curves_.begin(); ilti != curves_.end();
00080 ilti++)
00081 {
00082 imp_line_list* illp = (*ilti);
00083 for (imp_line_iterator ili = illp->begin(); ili != illp->end(); ili++)
00084 (*ili) = 0;
00085
00086 delete illp;
00087 (*ilti) = new imp_line_list;
00088 }
00089
00090 this->touch();
00091 }
00092
00093
00094
00095
00096 vifa_histogram_sptr vifa_group_pgram::
00097 GetCoverageHist(void)
00098 {
00099 vifa_histogram_sptr h = new vifa_histogram(th_dim_, 0.0f, float(angle_range_));
00100
00101 float* cnts = h->GetCounts();
00102 for (int i = 0; i < th_dim_; i++)
00103 cnts[i] = float(this->LineCoverage(i));
00104 return h;
00105 }
00106
00107
00108
00109
00110 vifa_line_cover_sptr vifa_group_pgram::
00111 GetLineCover(int angle_bin)
00112 {
00113 imp_line_sptr il = this->LineAtAngle(angle_bin);
00114
00115
00116 imp_line_list lg;
00117 this->CollectAdjacentLines(angle_bin, lg);
00118
00119 if (!lg.size())
00120 {
00121 return NULL;
00122 }
00123
00124
00125
00126 double bx;
00127 double by;
00128 double ex;
00129 double ey;
00130 this->CheckUpdateBoundingBox();
00131 if (!vgl_clip_line_to_box(il->a(), il->b(), il->c(),
00132 bb_->min_x(), bb_->min_y(),
00133 bb_->max_x(), bb_->max_y(),
00134 bx, by, ex, ey))
00135 {
00136 vcl_cerr << "In vifa_group_pgram::GetLineCover(): No intersection found\n";
00137 return NULL;
00138 }
00139
00140
00141 vgl_point_2d<double> b(bx, by);
00142 vgl_point_2d<double> e(ex, ey);
00143 il->set_points(b, e);
00144
00145
00146 int len = int(il->length());
00147 if (!len)
00148 {
00149 return NULL;
00150 }
00151
00152 vifa_line_cover_sptr cov = new vifa_line_cover(il, len);
00153 for (imp_line_iterator ili = lg.begin(); ili != lg.end(); ili++)
00154 {
00155 cov->InsertLine(*ili);
00156 }
00157
00158 return cov;
00159 }
00160
00161
00162
00163
00164 double vifa_group_pgram::
00165 LineCoverage(int angle_bin)
00166 {
00167 vifa_line_cover_sptr lc = this->GetLineCover(angle_bin);
00168 return lc ? lc->GetCoverage() : 0.0;
00169 }
00170
00171
00172
00173
00174 void vifa_group_pgram::
00175 CollectAdjacentLines(int angle_bin,
00176 imp_line_list& lg)
00177 {
00178 if (angle_bin >= 0 && angle_bin < th_dim_)
00179 {
00180 if (angle_bin == 0)
00181 {
00182
00183 lg.insert(lg.end(), curves_[th_dim_ - 1]->begin(),
00184 curves_[th_dim_ - 1]->end());
00185 lg.insert(lg.end(), curves_[0]->begin(),
00186 curves_[0]->end());
00187 lg.insert(lg.end(), curves_[1]->begin(),
00188 curves_[1]->end());
00189 }
00190 else if (angle_bin == th_dim_ - 1)
00191 {
00192
00193 lg.insert(lg.end(), curves_[th_dim_ - 2]->begin(),
00194 curves_[th_dim_ - 2]->end());
00195 lg.insert(lg.end(), curves_[th_dim_ - 1]->begin(),
00196 curves_[th_dim_ - 1]->end());
00197 lg.insert(lg.end(), curves_[0]->begin(),
00198 curves_[0]->end());
00199 }
00200 else
00201 {
00202
00203 lg.insert(lg.end(), curves_[angle_bin - 1]->begin(),
00204 curves_[angle_bin - 1]->end());
00205 lg.insert(lg.end(), curves_[angle_bin]->begin(),
00206 curves_[angle_bin]->end());
00207 lg.insert(lg.end(), curves_[angle_bin + 1]->begin(),
00208 curves_[angle_bin + 1]->end());
00209 }
00210 }
00211 else
00212 vcl_cerr << "vifa_group_pgram::CollectAdjacentLines(): bad angle_bin\n";
00213 }
00214
00215
00216
00217
00218 double vifa_group_pgram::
00219 GetAdjacentPerimeter(int bin)
00220 {
00221 imp_line_list lg;
00222 this->CollectAdjacentLines(bin, lg);
00223
00224 double sum = 0;
00225 for (imp_line_iterator ili = lg.begin(); ili != lg.end(); ili++)
00226 {
00227 vgl_vector_2d<double> v = (*ili)->point2() - (*ili)->point1();
00228 sum += v.length();
00229 }
00230
00231 return sum;
00232 }
00233
00234
00235
00236 double vifa_group_pgram::
00237 norm_parallel_line_length(void)
00238 {
00239 this->ComputeDominantDirs();
00240 if (dominant_dirs_.size() < 1)
00241 {
00242
00243 return 0.0;
00244 }
00245
00246 double max_cover = 0.0;
00247 int max_dir = 0;
00248 vcl_vector<int>::iterator iit = dominant_dirs_.begin();
00249 for (; iit != dominant_dirs_.end(); iit++)
00250 {
00251 int dir = (*iit);
00252 vifa_line_cover_sptr lc = this->GetLineCover(dir);
00253 if (!(lc.ptr()))
00254 {
00255
00256
00257
00258
00259
00260 continue;
00261 }
00262
00263 double cov = lc->GetCoverage();
00264
00265 if (cov > max_cover)
00266 {
00267 max_cover = cov;
00268 max_dir = dir;
00269 }
00270 }
00271
00272 double per = this->GetAdjacentPerimeter(max_dir);
00273
00274
00275
00276
00277 return 1.5 * per / tmp1_;
00278 }
00279
00280
00281
00282 int vifa_group_pgram::
00283 AngleLoc(imp_line_sptr il)
00284 {
00285
00286 double angle = vcl_fmod(il->slope_degrees(), 180.0);
00287 if (angle < 0.0)
00288 angle += 180.0;
00289
00290 if (angle > angle_range_)
00291 {
00292 vcl_cerr << "In vifa_group_pgram::AngleLoc(): angle " << angle
00293 << " was outside the angle range " << angle_range_ << vcl_endl;
00294 return 0;
00295 }
00296
00297 return (int)(vcl_floor(angle / angle_increment()));
00298 }
00299
00300
00301
00302 imp_line_sptr vifa_group_pgram::
00303 LineAtAngle(int angle_bin)
00304 {
00305
00306 double ang_rad = DEGTORAD * angle_bin * angle_increment();
00307 vgl_vector_2d<double> d(vcl_cos(ang_rad), vcl_sin(ang_rad));
00308
00309
00310 this->CheckUpdateBoundingBox();
00311 vgl_point_2d<double> m = bb_->centroid();
00312
00313
00314 imp_line_sptr il = new imp_line(d, m);
00315 return il;
00316 }
00317
00318
00319
00320
00321 void vifa_group_pgram::
00322 ComputeBoundingBox(void)
00323 {
00324
00325 bb_->empty();
00326
00327 for (imp_line_table::iterator ilti = curves_.begin(); ilti != curves_.end();
00328 ilti++)
00329 {
00330 imp_line_list* illp = (*ilti);
00331 for (imp_line_iterator ili = illp->begin(); ili != illp->end(); ili++)
00332 {
00333 imp_line_sptr il = (*ili);
00334
00335 bb_->add(il->point1());
00336 bb_->add(il->point2());
00337 }
00338 }
00339
00340
00341 bb_->touch();
00342 }
00343
00344
00345
00346
00347
00348 void vifa_group_pgram::
00349 ComputeDominantDirs(void)
00350 {
00351 dominant_dirs_.clear();
00352
00353
00354 vifa_histogram_sptr h = this->GetCoverageHist();
00355 vifa_histogram_sptr h_sup = h->NonMaximumSupress(max_suppress_radius(), true);
00356 float* cnts = h_sup->GetCounts();
00357 int max_idx = h_sup->GetRes();
00358
00359
00360 for (int i = 0; i < max_idx; i++)
00361 if (cnts[i] > 0)
00362 dominant_dirs_.push_back(i);
00363
00364
00365
00366 }