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