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