00001
00002 #include <vtol/vtol_intensity_face.h>
00003 #include <vifa/vifa_int_face_attr.h>
00004
00005
00006 vifa_int_face_attr::
00007 vifa_int_face_attr(vdgl_fit_lines_params* fitter_params,
00008 vifa_group_pgram_params* gpp,
00009 vifa_group_pgram_params* gpp_w,
00010 vifa_norm_params* np) :
00011 vifa_int_face_attr_common(fitter_params, gpp, gpp_w, 0, np),
00012 face_(NULL),
00013 cached_min_(0.0f),
00014 cached_max_(0.0f),
00015 cached_mean_(0.0f),
00016 cached_var_(0.0f),
00017 npobj_(0)
00018 {
00019 }
00020
00021 vifa_int_face_attr::
00022 vifa_int_face_attr(vtol_intensity_face_sptr f,
00023 vdgl_fit_lines_params* fitter_params,
00024 vifa_group_pgram_params* gpp,
00025 vifa_group_pgram_params* gpp_w,
00026 vifa_norm_params* np) :
00027 vifa_int_face_attr_common(fitter_params, gpp, gpp_w, 0, np),
00028 face_(f),
00029 cached_min_(0.0f),
00030 cached_max_(0.0f),
00031 cached_mean_(0.0f),
00032 cached_var_(0.0f),
00033 cached_2_parallel_(-1),
00034 cached_4_parallel_(-1),
00035 cached_80_parallel_(-1),
00036 npobj_(0)
00037 {
00038 attributes_valid_ = this->ComputeAttributes();
00039 }
00040
00041 vifa_int_face_attr::
00042 ~vifa_int_face_attr()
00043 {
00044 delete npobj_;
00045 }
00046
00047
00048
00049
00050
00051
00052 void vifa_int_face_attr::
00053 SetFace(vtol_intensity_face_sptr f)
00054 {
00055 face_ = f;
00056 delete npobj_;
00057 npobj_ = 0;
00058 attributes_valid_ = this->ComputeAttributes();
00059 }
00060
00061 edge_2d_list& vifa_int_face_attr::
00062 GetEdges()
00063 {
00064
00065 if (!edges_.empty())
00066 return edges_;
00067
00068 if (!face_)
00069 {
00070 vcl_cerr << "vifa_int_face_attr::GetFaces(): face_ is not set\n";
00071 return edges_;
00072 }
00073
00074 edge_list fedges; face_->edges(fedges);
00075 for (edge_iterator eli = fedges.begin(); eli != fedges.end(); eli++)
00076 {
00077 vtol_edge_2d_sptr e = (*eli)->cast_to_edge_2d();
00078 if (e)
00079 edges_.push_back(e);
00080 }
00081
00082 return edges_;
00083 }
00084
00085
00086
00087
00088
00089
00090 bool vifa_int_face_attr::
00091 ComputeAttributes()
00092 {
00093 ComputeCacheValues();
00094 attributes_valid_ = true;
00095 return this->valid_p();
00096 }
00097
00098
00099
00100 bool vifa_int_face_attr::
00101 GetAttributes(vcl_vector<float>& attrs)
00102 {
00103
00104 return this->vifa_int_face_attr::GetNativeAttributes(attrs);
00105 }
00106
00107
00108
00109 void vifa_int_face_attr::
00110 GetAttributeNames(vcl_vector<vcl_string>& names)
00111 {
00112 names.push_back("IntMax");
00113 names.push_back("IntMin");
00114 names.push_back("IntMean");
00115 names.push_back("IntVar");
00116 names.push_back("Area");
00117 names.push_back("AspectRatio");
00118 names.push_back("PerimeterLength");
00119 names.push_back("WeightedPerimeterLength");
00120 names.push_back("Complexity");
00121 names.push_back("WeightedComplexity");
00122 names.push_back("StrongParallel");
00123 names.push_back("WeakParallel");
00124 names.push_back("TwoPeakParallel");
00125 names.push_back("FourPeakParallel");
00126 names.push_back("EightyPercentParallel");
00127 }
00128
00129
00130
00131 bool vifa_int_face_attr::
00132 GetNativeAttributes(vcl_vector<float>& attrs)
00133 {
00134 if (!this->ComputeAttributes())
00135 {
00136 vcl_cerr << "Couldn't compute single face attributes?\n";
00137 return false;
00138 }
00139
00140 attrs.push_back(this->IntMax());
00141 attrs.push_back(this->IntMin());
00142 attrs.push_back(this->IntMean());
00143 attrs.push_back(this->IntVar());
00144 attrs.push_back(this->Area());
00145 attrs.push_back(this->AspectRatio());
00146 attrs.push_back(this->PerimeterLength());
00147 attrs.push_back(this->WeightedPerimeterLength());
00148 attrs.push_back(this->Complexity());
00149 attrs.push_back(this->WeightedComplexity());
00150 attrs.push_back(this->StrongParallelSal());
00151 attrs.push_back(this->WeakParallelSal());
00152 attrs.push_back(this->TwoPeakParallel());
00153 attrs.push_back(this->FourPeakParallel());
00154 attrs.push_back(this->EightyPercentParallel());
00155 return true;
00156 }
00157
00158
00159
00160
00161
00162 float vifa_int_face_attr::
00163 AspectRatio()
00164 {
00165 if (aspect_ratio_ < 0)
00166 aspect_ratio_ = face_->AspectRatio();
00167
00168 return aspect_ratio_;
00169 }
00170
00171 float vifa_int_face_attr::
00172 PerimeterLength()
00173 {
00174 if (peri_length_ < 0)
00175 peri_length_ = float(face_->perimeter());
00176
00177 return peri_length_;
00178 }
00179
00180 float vifa_int_face_attr::
00181 WeightedPerimeterLength()
00182 {
00183 if (weighted_peri_length_ < 0)
00184 {
00185
00186
00187 edge_list edges; face_->edges(edges);
00188 double p = 0.0;
00189 double intensity_sum = 1.0;
00190
00191 for (edge_iterator eit = edges.begin(); eit != edges.end(); eit++)
00192 {
00193 vtol_edge_2d_sptr e = (*eit)->cast_to_edge_2d();
00194 if (e)
00195 {
00196
00197 double int_grad = get_contrast_across_edge(e->cast_to_edge(), 1.0);
00198 p += e->curve()->length() * int_grad;
00199 intensity_sum += int_grad;
00200 }
00201 }
00202
00203 weighted_peri_length_ = float(p / intensity_sum);
00204 }
00205
00206 return weighted_peri_length_;
00207 }
00208
00209 float vifa_int_face_attr::
00210 Complexity()
00211 {
00212 float area = this->Area();
00213 float len = this->PerimeterLength();
00214
00215 if (complexity_ < 0 && len >= 0 && area > 0)
00216 complexity_ = len * len / area;
00217
00218 return complexity_;
00219 }
00220
00221 float vifa_int_face_attr::
00222 WeightedComplexity()
00223 {
00224 float area = this->Area();
00225 float len = this->WeightedPerimeterLength();
00226
00227 if (weighted_complexity_ < 0 && len >= 0 && area > 0)
00228 weighted_complexity_ = len * len / area;
00229
00230 return weighted_complexity_;
00231 }
00232
00233 float vifa_int_face_attr::
00234 TwoPeakParallel()
00235 {
00236 if (cached_2_parallel_ < 0)
00237 {
00238 SetNP();
00239
00240 for (int i = 0; i < 1; i++)
00241 {
00242 float max_angle, std_dev, scale;
00243 npobj_->map_gaussian(max_angle, std_dev, scale);
00244 npobj_->remove_gaussian(max_angle, std_dev, scale);
00245 }
00246
00247 cached_2_parallel_ = npobj_->area();
00248 }
00249
00250 return cached_2_parallel_;
00251 }
00252
00253 float vifa_int_face_attr::
00254 FourPeakParallel()
00255 {
00256 if (cached_4_parallel_ < 0)
00257 {
00258 SetNP();
00259
00260 for (int i = 0; i < 3; i++)
00261 {
00262 float max_angle, std_dev, scale;
00263 npobj_->map_gaussian(max_angle, std_dev, scale);
00264 npobj_->remove_gaussian(max_angle, std_dev, scale);
00265 }
00266
00267 cached_4_parallel_ = npobj_->area();
00268 }
00269
00270 return cached_4_parallel_;
00271 }
00272
00273 float vifa_int_face_attr::
00274 EightyPercentParallel()
00275 {
00276 if (cached_80_parallel_ < 0)
00277 {
00278 SetNP();
00279
00280 for (int i=0; i < 20 && npobj_->area() > 0.3f; ++i)
00281 {
00282 float max_angle, std_dev, scale;
00283 npobj_->map_gaussian(max_angle, std_dev, scale);
00284 npobj_->remove_gaussian(max_angle, std_dev, scale);
00285 cached_80_parallel_ = i;
00286 }
00287 }
00288
00289 return float(cached_80_parallel_);
00290 }
00291
00292 void vifa_int_face_attr::
00293 ComputeCacheValues()
00294 {
00295 float real_min = face_->get_min();
00296 float real_max = face_->get_max();
00297
00298
00299 if (real_min > real_max)
00300 {
00301 real_min = 0.0f;
00302 real_max = 1.0f;
00303 }
00304
00305 int max_bins = int(real_max - real_min + 1);
00306 int nbins = (face_->Npix() > max_bins) ? max_bins : face_->Npix();
00307 vifa_histogram intensity_hist(nbins, real_min, real_max);
00308
00309 for (int i = 0; i < face_->Npix(); i++)
00310 {
00311 float pval = (face_->Ij())[i];
00312 intensity_hist.UpCount(pval);
00313 }
00314
00315 #ifdef DEBUG
00316 vcl_cout << "vifa::ComputeCacheValues(): start dump:\n";
00317 intensity_hist.Print();
00318 vcl_cout << "LowClipVal: " << intensity_hist.LowClipVal(0.1) << vcl_endl
00319 << "HighClipVal: " << intensity_hist.LowClipVal(0.9) << vcl_endl
00320 << "face_->Io(): " << face_->Io() << vcl_endl
00321 << "face_->Npix(): " << face_->Npix() << vcl_endl;
00322 np_->print_info();
00323 vcl_cout << "vifa::ComputeCacheValues(): end dump\n";
00324 #endif
00325
00326 cached_min_ = normalize_intensity(intensity_hist.LowClipVal(0.1f));
00327 cached_max_ = normalize_intensity(intensity_hist.LowClipVal(0.9f));
00328 cached_mean_ = normalize_intensity(face_->Io());
00329
00330 float sum = 0.0f;
00331 const unsigned short* pvals = face_->Ij();
00332
00333 for (int i = 0; i < face_->Npix(); i++)
00334 {
00335 float mapped_pval = normalize_intensity(pvals[i]);
00336 float delta = mapped_pval - cached_mean_;
00337 sum += delta * delta;
00338 }
00339
00340 cached_var_ = sum / face_->Npix();
00341 }
00342
00343 void vifa_int_face_attr::
00344 SetNP()
00345 {
00346 if (npobj_)
00347 npobj_->reset();
00348 else
00349 {
00350 vcl_vector<vtol_intensity_face_sptr> faces;
00351 faces.push_back(face_);
00352
00353 static bool contrast = true;
00354 npobj_ = new vifa_parallel(faces, contrast);
00355 }
00356 }