SpectralPeakDescriptors.cxx
Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #include "ProcessingData.hxx"
00026 #include "SpectralPeakDescriptors.hxx"
00027 #include "SpectralPeakArray.hxx"
00028 #include "CLAM_Math.hxx"
00029
00030 namespace CLAM{
00031
00032 DataArray Add(DataArray &a, DataArray &b);
00033 DataArray Multiply(TData &factor, DataArray &a);
00034 DataArray Multiply(DataArray &a, DataArray &b);
00035
00036 SpectralPeakDescriptors::SpectralPeakDescriptors(SpectralPeakArray* pSpectralPeakArray): Descriptor(eNumAttr)
00037 {
00038 CLAM_ASSERT(pSpectralPeakArray->GetScale()==EScale::eLinear,
00039 "Spectral Peak Descriptors require a linear magnitude SpectralPeakArray");
00040 MandatoryInit();
00041 mpSpectralPeakArray=pSpectralPeakArray;
00042 }
00043
00044 SpectralPeakDescriptors::SpectralPeakDescriptors(TData initVal):Descriptor(eNumAttr)
00045 {
00046 MandatoryInit();
00047 AddAll();
00048 UpdateData();
00049
00050 SetMagnitudeMean(initVal);
00051 SetHarmonicCentroid(initVal);
00052 SetFirstTristimulus(initVal);
00053 SetSecondTristimulus(initVal);
00054 SetThirdTristimulus(initVal);
00055 SetHarmonicDeviation(initVal);
00056 SetOddHarmonics(initVal);
00057 SetEvenHarmonics(initVal);
00058 SetOddToEvenRatio(initVal);
00059 }
00060
00061 void SpectralPeakDescriptors::DefaultInit() {
00062 mpSpectralPeakArray=0;
00063 mpStats=0;
00064 }
00065
00066 void SpectralPeakDescriptors::CopyInit(const SpectralPeakDescriptors & copied) {
00067 mpSpectralPeakArray=copied.mpSpectralPeakArray;
00068 mpStats=0;
00069 }
00070
00071 const SpectralPeakArray* SpectralPeakDescriptors::GetpSpectralPeakArray() const {
00072 return mpSpectralPeakArray;
00073 }
00074
00075 void SpectralPeakDescriptors::SetpSpectralPeakArray(SpectralPeakArray* pSpectralPeakArray)
00076 {
00077 CLAM_ASSERT(pSpectralPeakArray->GetScale()==EScale::eLinear,
00078 "Spectral Peak Descriptors require a linear magnitude SpectralPeakArray");
00079 mpSpectralPeakArray=pSpectralPeakArray;
00080
00081 InitStats(&mpSpectralPeakArray->GetMagBuffer());
00082 mCentroid.Reset();
00083 }
00084
00085
00086 void SpectralPeakDescriptors::ConcreteCompute()
00087 {
00088
00089 if (HasMagnitudeMean())
00090 SetMagnitudeMean(mpStats->GetMean());
00091 if (HasHarmonicCentroid())
00092 SetHarmonicCentroid(ComputeCentroid());
00093 if(HasFirstTristimulus())
00094 SetFirstTristimulus(ComputeFirstTristimulus());
00095 if(HasSecondTristimulus())
00096 SetSecondTristimulus(ComputeSecondTristimulus());
00097 if(HasThirdTristimulus())
00098 SetThirdTristimulus(ComputeThirdTristimulus());
00099 if(HasHarmonicDeviation())
00100 SetHarmonicDeviation(ComputeHarmonicDeviation());
00101 if(HasOddHarmonics())
00102 SetOddHarmonics(ComputeOddHarmonics());
00103 if(HasEvenHarmonics())
00104 SetEvenHarmonics(ComputeEvenHarmonics());
00105 if(HasOddToEvenRatio())
00106 SetOddToEvenRatio(ComputeOddToEvenRatio());
00107 }
00108
00109 TData SpectralPeakDescriptors::ComputeCentroid()
00110 {
00111 unsigned size = mpSpectralPeakArray->GetnPeaks();
00112 if (size<=0) return 0;
00113 const Array<TData> & magnitudes = mpSpectralPeakArray->GetMagBuffer();
00114 const Array<TData> & frequencies = mpSpectralPeakArray->GetFreqBuffer();
00115 TData crossProduct=0.0;
00116 for (unsigned i = 0; i < size; i++)
00117 {
00118 crossProduct += magnitudes[i]*frequencies[i];
00119 }
00120 return crossProduct/(mpStats->GetMean()*size);
00121 }
00122
00123 TData SpectralPeakDescriptors::ComputeFirstTristimulus()
00124 {
00125 if (mpSpectralPeakArray->GetnPeaks()<=0) return 0;
00126 const TData firstHarmonicMag=mpSpectralPeakArray->GetMagBuffer()[0];
00127 return firstHarmonicMag*firstHarmonicMag/mpStats->GetEnergy();
00128 }
00129
00130 TData SpectralPeakDescriptors::ComputeSecondTristimulus()
00131 {
00132 if (mpSpectralPeakArray->GetnPeaks()<=3) return 0;
00133
00134 const TData secondHarmonicMag=mpSpectralPeakArray->GetMagBuffer()[1];
00135 const TData thirdHarmonicMag=mpSpectralPeakArray->GetMagBuffer()[2];
00136 const TData fourthHarmonicMag=mpSpectralPeakArray->GetMagBuffer()[3];
00137
00138 return (secondHarmonicMag*secondHarmonicMag+thirdHarmonicMag*thirdHarmonicMag+
00139 fourthHarmonicMag*fourthHarmonicMag)/mpStats->GetEnergy();
00140 }
00141
00142 TData SpectralPeakDescriptors::ComputeThirdTristimulus()
00143 {
00144 if (mpSpectralPeakArray->GetnPeaks()<=4) return 0;
00145 const DataArray& a=mpSpectralPeakArray->GetMagBuffer();
00146 return accumulate(a.GetPtr()+4,a.GetPtr()+a.Size(),0.,Power<2>())/mpStats->GetEnergy();
00147 }
00148
00149 TData SpectralPeakDescriptors::ComputeHarmonicDeviation()
00150 {
00151 const unsigned size=mpSpectralPeakArray->GetnPeaks();
00152 if (size<4) return 0.0;
00153 const DataArray & data=mpSpectralPeakArray->GetMagBuffer();
00154
00155 TData denom = 0;
00156 TData nom = 0;
00157
00158 const TData tmp0 = log10((data[0]+data[1])/2);
00159 const TData logdata0=log10(data[0]);
00160 denom += logdata0;
00161 nom += CLAM::Abs(logdata0 - tmp0);
00162
00163 for (unsigned i=1;i<size-1;i++)
00164 {
00165 const TData tmpi = log10((data[i-1]+data[i]+data[i+1])/3);
00166 const TData logdatai=log10(data[i]);
00167 denom += logdatai;
00168 nom += CLAM::Abs(logdatai - tmpi);
00169 }
00170
00171 const TData tmpN = log10((data[size-2]+data[size-1])/2);
00172 const TData logdataN=log10(data[size-1]);
00173 denom += logdataN;
00174 nom += CLAM::Abs(logdataN - tmpN);
00175
00176 return nom/denom;
00177 }
00178
00179 TData SpectralPeakDescriptors::ComputeOddHarmonics()
00180 {
00181 const unsigned size=mpSpectralPeakArray->GetnPeaks();
00182 if (size<3) return 0;
00183 const DataArray& data=mpSpectralPeakArray->GetMagBuffer();
00184 TData oddEnergy = 0.0;
00185 for (unsigned i=2;i<size;i+=2)
00186 {
00187 oddEnergy+=data[i]*data[i];
00188 }
00189 return oddEnergy/mpStats->GetEnergy();
00190 }
00191
00192 TData SpectralPeakDescriptors::ComputeEvenHarmonics()
00193 {
00194 const unsigned size=mpSpectralPeakArray->GetnPeaks();
00195 if (size<2) return 0;
00196 const DataArray& data=mpSpectralPeakArray->GetMagBuffer();
00197 TData evenEnergy = 0.0;
00198 for (unsigned i=1;i<size;i+=2)
00199 {
00200 evenEnergy+=data[i]*data[i];
00201 }
00202 return evenEnergy/mpStats->GetEnergy();
00203 }
00204
00205 TData SpectralPeakDescriptors::ComputeOddToEvenRatio()
00206 {
00207 if (mpSpectralPeakArray->GetnPeaks()<=1) return 0.5;
00208 TData odd,even;
00209 if (HasOddHarmonics()) odd=GetOddHarmonics();
00210 else odd=ComputeOddHarmonics();
00211 if (HasEvenHarmonics()) even=GetEvenHarmonics();
00212 else even=ComputeEvenHarmonics();
00213
00214 return odd/(even+odd);
00215 }
00216
00217 SpectralPeakDescriptors operator * (const SpectralPeakDescriptors& a,TData mult)
00218 {
00219 SpectralPeakDescriptors tmpD(a);
00220
00221 if (a.HasMagnitudeMean())
00222 {
00223 tmpD.SetMagnitudeMean(a.GetMagnitudeMean()*mult);
00224 }
00225 if (a.HasHarmonicCentroid())
00226 {
00227 tmpD.SetHarmonicCentroid(a.GetHarmonicCentroid()*mult);
00228 }
00229 if (a.HasFirstTristimulus())
00230 {
00231 tmpD.SetFirstTristimulus(a.GetFirstTristimulus()*mult);
00232 }
00233 if (a.HasSecondTristimulus())
00234 {
00235 tmpD.SetSecondTristimulus(a.GetSecondTristimulus()*mult);
00236 }
00237 if (a.HasThirdTristimulus())
00238 {
00239 tmpD.SetThirdTristimulus(a.GetThirdTristimulus()*mult);
00240 }
00241 if (a.HasHarmonicDeviation())
00242 {
00243 tmpD.SetHarmonicDeviation(a.GetHarmonicDeviation()*mult);
00244 }
00245 if (a.HasOddHarmonics())
00246 {
00247 tmpD.SetOddHarmonics(a.GetOddHarmonics()*mult);
00248 }
00249 if (a.HasEvenHarmonics())
00250 {
00251 tmpD.SetEvenHarmonics(a.GetEvenHarmonics()*mult);
00252 }
00253 if (a.HasOddToEvenRatio())
00254 {
00255 tmpD.SetOddToEvenRatio(a.GetOddToEvenRatio()*mult);
00256 }
00257 if(a.HasHPCP())
00258 tmpD.SetHPCP(Multiply(mult,a.GetHPCP()));
00259
00260 return tmpD;
00261 }
00262
00263 SpectralPeakDescriptors operator * (const SpectralPeakDescriptors& a,const SpectralPeakDescriptors& b)
00264 {
00265 SpectralPeakDescriptors tmpD;
00266
00267 if (a.HasMagnitudeMean() && b.HasMagnitudeMean())
00268 {
00269 tmpD.AddMagnitudeMean();
00270 tmpD.UpdateData();
00271 tmpD.SetMagnitudeMean(a.GetMagnitudeMean()*b.GetMagnitudeMean());
00272 }
00273 if (a.HasHarmonicCentroid() && b.HasHarmonicCentroid())
00274 {
00275 tmpD.AddHarmonicCentroid();
00276 tmpD.UpdateData();
00277 tmpD.SetHarmonicCentroid(a.GetHarmonicCentroid()*b.GetHarmonicCentroid());
00278 }
00279 if (a.HasFirstTristimulus() && b.HasFirstTristimulus())
00280 {
00281 tmpD.AddFirstTristimulus();
00282 tmpD.UpdateData();
00283 tmpD.SetFirstTristimulus(a.GetFirstTristimulus()*b.GetFirstTristimulus());
00284 }
00285 if (a.HasSecondTristimulus() && b.HasSecondTristimulus())
00286 {
00287 tmpD.AddSecondTristimulus();
00288 tmpD.UpdateData();
00289 tmpD.SetSecondTristimulus(a.GetSecondTristimulus()*b.GetSecondTristimulus());
00290 }
00291 if (a.HasThirdTristimulus() && b.HasThirdTristimulus())
00292 {
00293 tmpD.AddThirdTristimulus();
00294 tmpD.UpdateData();
00295 tmpD.SetThirdTristimulus(a.GetThirdTristimulus()*b.GetThirdTristimulus());
00296 }
00297 if (a.HasHarmonicDeviation() && b.HasHarmonicDeviation())
00298 {
00299 tmpD.AddHarmonicDeviation();
00300 tmpD.UpdateData();
00301 tmpD.SetHarmonicDeviation(a.GetHarmonicDeviation()*b.GetHarmonicDeviation());
00302 }
00303 if (a.HasOddHarmonics() && b.HasOddHarmonics())
00304 {
00305 tmpD.AddOddHarmonics();
00306 tmpD.UpdateData();
00307 tmpD.SetOddHarmonics(a.GetOddHarmonics()*b.GetOddHarmonics());
00308 }
00309 if (a.HasEvenHarmonics() && b.HasEvenHarmonics())
00310 {
00311 tmpD.AddEvenHarmonics();
00312 tmpD.UpdateData();
00313 tmpD.SetEvenHarmonics(a.GetEvenHarmonics()*b.GetEvenHarmonics());
00314 }
00315 if (a.HasOddToEvenRatio() && b.HasOddToEvenRatio())
00316 {
00317 tmpD.AddOddToEvenRatio();
00318 tmpD.UpdateData();
00319 tmpD.SetOddToEvenRatio(a.GetOddToEvenRatio()*b.GetOddToEvenRatio());
00320 }
00321 if (a.HasHPCP() && b.HasHPCP())
00322 {
00323 tmpD.AddHPCP();
00324 tmpD.UpdateData();
00325 tmpD.SetHPCP(Multiply(a.GetHPCP(),b.GetHPCP()));
00326 }
00327
00328 return tmpD;
00329 }
00330
00331 SpectralPeakDescriptors operator + (const SpectralPeakDescriptors& a,const SpectralPeakDescriptors& b)
00332 {
00333 SpectralPeakDescriptors tmpD;
00334
00335 if (a.HasMagnitudeMean() && b.HasMagnitudeMean())
00336 {
00337 tmpD.AddMagnitudeMean();
00338 tmpD.UpdateData();
00339 tmpD.SetMagnitudeMean(a.GetMagnitudeMean()+b.GetMagnitudeMean());
00340 }
00341 if (a.HasHarmonicCentroid() && b.HasHarmonicCentroid())
00342 {
00343 tmpD.AddHarmonicCentroid();
00344 tmpD.UpdateData();
00345 tmpD.SetHarmonicCentroid(a.GetHarmonicCentroid()+b.GetHarmonicCentroid());
00346 }
00347 if (a.HasFirstTristimulus() && b.HasFirstTristimulus())
00348 {
00349 tmpD.AddFirstTristimulus();
00350 tmpD.UpdateData();
00351 tmpD.SetFirstTristimulus(a.GetFirstTristimulus()+b.GetFirstTristimulus());
00352 }
00353 if (a.HasSecondTristimulus() && b.HasSecondTristimulus())
00354 {
00355 tmpD.AddSecondTristimulus();
00356 tmpD.UpdateData();
00357 tmpD.SetSecondTristimulus(a.GetSecondTristimulus()+b.GetSecondTristimulus());
00358 }
00359 if (a.HasThirdTristimulus() && b.HasThirdTristimulus())
00360 {
00361 tmpD.AddThirdTristimulus();
00362 tmpD.UpdateData();
00363 tmpD.SetThirdTristimulus(a.GetThirdTristimulus()+b.GetThirdTristimulus());
00364 }
00365 if (a.HasHarmonicDeviation() && b.HasHarmonicDeviation())
00366 {
00367 tmpD.AddHarmonicDeviation();
00368 tmpD.UpdateData();
00369 tmpD.SetHarmonicDeviation(a.GetHarmonicDeviation()+b.GetHarmonicDeviation());
00370 }
00371 if (a.HasOddHarmonics() && b.HasOddHarmonics())
00372 {
00373 tmpD.AddOddHarmonics();
00374 tmpD.UpdateData();
00375 tmpD.SetOddHarmonics(a.GetOddHarmonics()+b.GetOddHarmonics());
00376 }
00377 if (a.HasEvenHarmonics() && b.HasEvenHarmonics())
00378 {
00379 tmpD.AddEvenHarmonics();
00380 tmpD.UpdateData();
00381 tmpD.SetEvenHarmonics(a.GetEvenHarmonics()+b.GetEvenHarmonics());
00382 }
00383 if (a.HasOddToEvenRatio() && b.HasOddToEvenRatio())
00384 {
00385 tmpD.AddOddToEvenRatio();
00386 tmpD.UpdateData();
00387 tmpD.SetOddToEvenRatio(a.GetOddToEvenRatio()+b.GetOddToEvenRatio());
00388 }
00389 if(a.HasHPCP() && b.HasHPCP() )
00390 {
00391 tmpD.AddHPCP();
00392 tmpD.UpdateData();
00393 tmpD.SetHPCP(Add(a.GetHPCP(),b.GetHPCP()));
00394 }
00395
00396
00397 return tmpD;
00398 }
00399
00400 SpectralPeakDescriptors operator / (const SpectralPeakDescriptors& a,TData div)
00401 {
00402 return a*(1/div);
00403 }
00404
00405 SpectralPeakDescriptors operator * (TData mult, const SpectralPeakDescriptors& a)
00406 {
00407 return a*mult;
00408 }
00409
00410 }
00411