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
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038 #ifdef HAVE_FFTW3_H
00039
00040 #include "Surprise/SurpriseMapFFT.H"
00041
00042 #include "Image/All.H"
00043 #include "Image/Kernels.H"
00044 #include "Image/Conversions.H"
00045 #include "Image/MathOps.H"
00046 #include "Util/Assert.H"
00047 #include "Raster/Raster.H"
00048 #include "Image/Pixels.H"
00049
00050 #ifdef HAVE_FFTW3_H
00051 #include <fftw3.h>
00052 #endif
00053
00054
00055 template <class T>
00056 SurpriseMapFFT<T>::SurpriseMapFFT() :
00057 itsModels(), itsQlen(0), itsInitialModel(),
00058 itsNeighSigma(0.0f), itsLocSigma(0.0f), itsNweights(), itsNWmin(0.0f),
00059 itsNeighUpdFac(0.7), itsProbe(-1, -1), itsSLfac(1.0), itsSSfac(0.1),
00060 itsSFSfac(1.0),itsSFPfac(1.0), itsDescrName("blank"),itsTagName("blank"),
00061 itsCounter(0)
00062 {}
00063
00064
00065 template <class T>
00066 void SurpriseMapFFT<T>::init(const uint qlen, const double updatefac,
00067 const double neighupdatefac,
00068 const double sampleval, const double samplevar,
00069 const float neighsigma, const float locsigma,
00070 const Point2D<int>& probe, const double slfac,
00071 const double ssfac, const double sfsfac,
00072 const double sfpfac,
00073 const std::string& descrName,
00074 const std::string& tagName)
00075 {
00076 itsQlen = qlen;
00077 itsModels.clear();
00078 for(uint j = 0; j < itsFFTPModels.size(); j ++)
00079 {
00080 itsFFTSModels[j].clear();
00081 itsFFTPModels[j].clear();
00082 }
00083 itsInitialModel.init(updatefac, sampleval, samplevar);
00084 itsNeighSigma = neighsigma; itsLocSigma = locsigma;
00085 itsNweights.freeMem();
00086 itsNeighUpdFac = neighupdatefac;
00087 itsProbe = probe;
00088 itsVariance = samplevar;
00089 itsUpdatefac = updatefac;
00090 itsSLfac = slfac; itsSSfac = ssfac; itsSFSfac = sfsfac; itsSFPfac = sfpfac;
00091 itsDescrName = descrName;
00092 itsTagName = tagName;
00093 const int N = FFT_TIME_SLICE;
00094 LINFO("NEW FFT IN");
00095 in = static_cast<fftw_complex*>(fftw_malloc(sizeof(fftw_complex) * N));
00096 LINFO("NEW FFT OUT");
00097 out = static_cast<fftw_complex*>(fftw_malloc(sizeof(fftw_complex) * N));
00098
00099 LINFO("NEW FFT PLAN");
00100 p = fftw_plan_dft_1d(N, in, out, FFTW_FORWARD, FFTW_PATIENT);
00101 LINFO("DONE");
00102 itsCounter = 0;
00103 }
00104
00105
00106 template <class T>
00107 SurpriseMapFFT<T>::~SurpriseMapFFT()
00108 {}
00109
00110
00111 template <class T>
00112 void SurpriseMapFFT<T>::reset()
00113 {
00114
00115 for(uint j = 0; j < itsFFTSModels.size(); j ++)
00116 {
00117 itsFFTSModels[j].reset();
00118 itsFFTPModels[j].reset();
00119 }
00120
00121 LINFO("DESTROY FFT PLAN");
00122 fftw_destroy_plan(p);
00123 fftw_free(in);
00124 fftw_free(out);
00125 LINFO("DONE");
00126 }
00127
00128
00129 template <class T>
00130 Image<double> SurpriseMapFFT<T>::surprise(const SurpriseImage<T>& sample,
00131 const Image<double>& inputI,
00132 const Image<double>& var)
00133 {
00134
00135
00136 itsVarianceImage = var;
00137 if(fftStack.size() != FFT_TIME_SLICE)
00138 {
00139 fftStackCount = 0;
00140 fftStackReady = false;
00141
00142 fftBins = (unsigned char)(floor(log(FFT_TIME_SLICE/2)/log(2)));
00143 unsigned char tempsize = 1;
00144
00145 for(unsigned char i = 0; i < fftBins; i++)
00146 {
00147 fftBinSize.push_back(tempsize);
00148 tempsize = tempsize * 2;
00149 }
00150 Image<double> temp;
00151 fftStack.resize(FFT_TIME_SLICE,temp);
00152 }
00153
00154 fftStack.pop_front();
00155 fftStack.push_back(inputI);
00156
00157
00158
00159
00160 if (itsModels.empty())
00161 {
00162
00163 SurpriseImage<T> models(sample.getDims());
00164 models.clear(itsInitialModel);
00165 models.reset();
00166 itsFFTSModels.clear();
00167 itsFFTPModels.clear();
00168 itsModels.clear();
00169 for (uint i = 0; i < fftBins; i ++)
00170 {
00171 itsFFTSModels.push_back(models);
00172 itsFFTPModels.push_back(models);
00173 itsModels.clear();
00174 }
00175
00176
00177 const int w = sample.getWidth(), h = sample.getHeight();
00178 const float sigma = itsNeighSigma * float(std::max(w, h));
00179 Dims d(w * 2 + 1, h * 2 + 1); Point2D<int> p(w, h);
00180 itsNweights = gaussianBlob<float>(d, p, sigma, sigma);
00181 itsNweights -= gaussianBlob<float>(d, p, itsLocSigma,
00182 itsLocSigma) *
00183 (itsLocSigma*itsLocSigma / (sigma * sigma) * 1.5f);
00184
00185 inplaceRectify(itsNweights);
00186
00187 float mi, ma; getMinMax(itsNweights, mi, ma);
00188 itsNWmin = 0.01f * ma;
00189 }
00190 else if (itsModels[0].isSameSize(sample) == false)
00191 LFATAL("Inconsistent input size!");
00192 else if (itsFFTSModels[0].isSameSize(sample) == false)
00193 LFATAL("Inconsistent FFT signal mag input size!");
00194 else if (itsFFTPModels[0].isSameSize(sample) == false)
00195 LFATAL("Inconsistent FFT phase input size!");
00196
00197
00198
00199
00200 SurpriseImage<T> input(sample);
00201 Image<double> s;
00202
00203 Image<float> locstot(input.getDims(), ZEROS);
00204 std::vector<Image<double> > sfs;
00205 std::vector<Image<double> > sfp;
00206
00207 if(fftStackReady == true)
00208 {
00209
00210 Image<double> temp;
00211 setFFTModels(input, itsNweights, itsNWmin, sfs, sfp);
00212
00213
00214
00215
00216
00217
00218
00219
00220
00221
00222
00223
00224
00225
00226
00227
00228
00229
00230
00231
00232
00233
00234
00235
00236
00237
00238
00239 Image<double> stot(sfs[0].getDims(), ZEROS);
00240 float mi, ma;
00241 Image<float> locstot(sfs[0].getDims(), ZEROS);
00242 float mi1, ma1;
00243 Image<float> lsf(sfs[0].getDims(), ZEROS);
00244 if (itsSFSfac)
00245 {
00246 if (itsSFSfac != 1.0)
00247 {
00248 for(uint j = 0; j < sfs.size() - 2; j++)
00249 {
00250
00251 stot += (sfs[j] * itsSFSfac)/sfs.size();
00252 locstot = stot;
00253 lsf = sfs[j];
00254 getMinMax(locstot, mi, ma);
00255 getMinMax(lsf, mi1, ma1);
00256 Image<byte> foo = sfs[j];
00257
00258
00259
00260 }
00261 }
00262 else
00263 {
00264 for(uint j = 0; j < sfs.size() - 2; j++)
00265 {
00266
00267 stot += sfs[j]/sfs.size();
00268 locstot = stot;
00269 lsf = sfs[j];
00270 getMinMax(locstot, mi, ma);
00271 getMinMax(lsf, mi1, ma1);
00272 Image<byte> foo = sfs[j];
00273
00274
00275
00276 }
00277 }
00278 }
00279
00280
00281
00282 s = stot;
00283 locstot = s;
00284 getMinMax(locstot, mi, ma);
00285
00286
00287
00288
00289
00290
00291
00292 inplaceRectify(s);
00293
00294
00295
00296
00297 locstot = s;
00298 getMinMax(locstot, mi, ma);
00299
00300 }
00301 else
00302 {
00303 s = locstot;
00304 }
00305 itsCounter++;
00306
00307
00308
00309
00310 if(fftStackCount < FFT_TIME_SLICE)
00311 fftStackCount++;
00312 else
00313 fftStackReady = true;
00314
00315
00316
00317 return s;
00318 }
00319
00320
00321 template <class T>
00322 const SurpriseImage<T>& SurpriseMapFFT<T>::getSurpriseImage(const
00323 uint index) const
00324 {
00325 ASSERT(index < itsModels.size());
00326 return itsModels[index];
00327 }
00328
00329
00330 template <class T>
00331 const SurpriseImage<T>& SurpriseMapFFT<T>::getSurpriseImageSFFT(
00332 const uint i) const
00333 {
00334 ASSERT(i < itsFFTSModels.size());
00335 return itsFFTSModels[i];
00336 }
00337
00338
00339 template <class T>
00340 const SurpriseImage<T>& SurpriseMapFFT<T>::getSurpriseImagePFFT(
00341 const uint i) const
00342 {
00343 ASSERT(i < itsFFTPModels.size());
00344 return itsFFTPModels[i];
00345 }
00346
00347 template <class T>
00348 void SurpriseMapFFT<T>::setFFTModels(const SurpriseImage<T>& models,
00349 const Image<float>& weights,
00350 const float wmin,
00351 std::vector<Image<double> >& sfs,
00352 std::vector<Image<double> >& sfp)
00353 {
00354 #ifndef HAVE_FFTW3_H
00355 LFATAL("this program requires fftw3, "
00356 "but <fftw3.h> was not found during the configure process");
00357 #else
00358
00359 const int N = FFT_TIME_SLICE;
00360 const double veryBigNumber = pow(10,10);
00361 const double verySmallNumber = 0.0000000000001F;
00362
00363
00364
00365
00366
00367
00368
00369 Image<double> SSpaces, PSpaces;
00370 SSpaces.resize(itsFFTSModels[0].getWidth(),
00371 itsFFTSModels[0].getHeight());
00372 PSpaces.resize(itsFFTSModels[0].getWidth(),
00373 itsFFTSModels[0].getHeight());
00374
00375 Image<double>::iterator iSSpace = SSpaces.beginw();
00376 Image<double>::iterator iPSpace = PSpaces.beginw();
00377 const unsigned int tpixels = itsFFTSModels[0].getWidth() *
00378 itsFFTSModels[0].getHeight();
00379 for(unsigned int i = 0; i < tpixels ; i++ , ++iSSpace, ++iPSpace)
00380 {
00381 *iSSpace = 0; *iPSpace = 0;
00382 }
00383
00384 Image<float> temps;
00385
00386
00387
00388
00389
00390
00391
00392
00393
00394
00395
00396
00397
00398 std::vector<Image<double> > VSSpaces(itsFFTSModels.size(),SSpaces);
00399 std::vector<Image<double> > VPSpaces(itsFFTSModels.size(),PSpaces);
00400
00401 for(int i = 0; i < itsFFTSModels[0].getWidth(); i++)
00402 {
00403 for(int j = 0; j < itsFFTSModels[0].getHeight(); j++)
00404 {
00405 for(unsigned int k = 0; k < (unsigned)N; k++)
00406 {
00407 in[k][1] = fftStack[k].getVal(i,j);
00408 in[k][0] = fftStack[k].getVal(i,j);
00409
00410 }
00411
00412 fftw_execute(p);
00413 unsigned char binSize = 1;
00414 unsigned char binCount = 1;
00415 unsigned char bin = 0;
00416 float val = 0.0F;
00417 int k = 0;
00418
00419 while(bin != (unsigned char)itsFFTSModels.size())
00420 {
00421
00422
00423
00424
00425
00426
00427 if((fabs(out[k][1]) < veryBigNumber) &&
00428 (fabs(out[k][0]) < veryBigNumber))
00429 {
00430 if(out[k][0] != 0)
00431 val = VPSpaces[bin].getVal(i,j) + fabs(atan(out[k][1]/out[k][0]));
00432 else
00433 val = 0.0F;
00434 }
00435 else
00436 {
00437
00438 val = verySmallNumber;
00439 }
00440 VPSpaces[bin].setVal(i,j,val);
00441
00442 if(fabs(out[k][1]) < veryBigNumber)
00443 out[k][1] = out[k][1];
00444 else
00445 out[k][1] = verySmallNumber;
00446
00447 if(fabs(out[k][0]) < veryBigNumber)
00448 out[k][0] = out[k][0];
00449 else
00450 out[k][0] = verySmallNumber;
00451
00452
00453 val = VSSpaces[bin].getVal(i,j)
00454 + sqrt(pow(out[k][0],2) + pow(out[k][1],2));
00455
00456 VSSpaces[bin].setVal(i,j,val);
00457
00458 if(binCount == binSize)
00459 {
00460
00461
00462 val = (VSSpaces[bin].getVal(i,j)/binSize) * 1/(N * sqrt(2));
00463 VSSpaces[bin].setVal(i,j,val);
00464 val = (VPSpaces[bin].getVal(i,j)/binSize) * (255.0F/(3.14159F/2.0F));
00465 VPSpaces[bin].setVal(i,j,val);
00466 binSize = binSize * 2;
00467 binCount = 1;
00468 bin++;
00469 }
00470 else
00471 {
00472 binCount++;
00473 }
00474 k++;
00475 }
00476 }
00477 }
00478
00479
00480
00481
00482 Image<double> temp;
00483 Image<float> holder;
00484 float mi, ma;
00485 for(int bin = 0; bin < (unsigned char)itsFFTSModels.size(); bin++)
00486 {
00487
00488 Image<double> invar(VSSpaces[bin].getDims(), NO_INIT);
00489
00490
00491 holder = VSSpaces[bin];
00492 getMinMax(holder, mi, ma);
00493
00494 holder = VPSpaces[bin];
00495 getMinMax(holder, mi, ma);
00496
00497
00498 Image<float> outImageO = VSSpaces[bin];
00499 Image<PixRGB<float> > outImageF;
00500 outImageO = rescale(outImageO,200,(int)round(200.0F*
00501 ((float)outImageO.getHeight()/
00502 (float)outImageO.getWidth())));
00503 outImageF = normalizeWithScale(outImageO,0,255.0F,255.0F,1,3);
00504 Image<PixRGB<byte> > outImage = outImageF;
00505 Raster::WriteRGB(outImage,sformat("out.fft.spec.frame%d.%s.%d.%dx%d.png",
00506 itsCounter,
00507 itsTagName.c_str(),
00508 bin,
00509 VSSpaces[bin].getWidth(),
00510 VSSpaces[bin].getHeight()
00511 ));
00512
00513
00514 Image<float> outImageO2 = VPSpaces[bin];
00515 Image<PixRGB<float> > outImageF2;
00516 outImageO2 = rescale(outImageO2,200,(int)round(200.0F*
00517 ((float)outImageO2.getHeight()/
00518 (float)outImageO2.getWidth())));
00519 outImageF2 = normalizeWithScale(outImageO2,0,255.0F,255.0F,1,3);
00520 outImage = outImageF2;
00521 Raster::WriteRGB(outImage,sformat("out.fft.phas.frame%d.%s.%d.%dx%d.png",
00522 itsCounter,
00523 itsTagName.c_str(),
00524 bin,
00525 VPSpaces[bin].getWidth(),
00526 VPSpaces[bin].getHeight()
00527 ));
00528
00529
00530 SurpriseImage<T> SSSpaces(itsNeighUpdFac,
00531 VSSpaces[bin],itsVarianceImage);
00532 SurpriseImage<T> SPSpaces(itsNeighUpdFac,
00533 VPSpaces[bin],itsVarianceImage);
00534
00535
00536
00537
00538
00539
00540 temp = itsFFTSModels[bin].surprise(SSSpaces);
00541
00542
00543 sfs.push_back(temp);
00544
00545
00546 temp = itsFFTPModels[bin].surprise(SPSpaces);
00547 sfp.push_back(temp);
00548 }
00549
00550 #endif
00551 }
00552
00553
00554
00555
00556
00557
00558
00559
00560 template class SurpriseMapFFT<SurpriseModelSG>;
00561 template class SurpriseMapFFT<SurpriseModelSP>;
00562 template class SurpriseMapFFT<SurpriseModelOD>;
00563
00564 #endif // HAVE_FFTW3_H
00565
00566
00567
00568
00569
00570