fourier.cpp
Go to the documentation of this file.
00001 #include <vector>
00002 #include <cmath>
00003 #include <algorithm>
00004 #include <list>
00005 #include <numeric>
00006 #include <iostream>
00007 #include <gsl/gsl_errno.h>
00008 #include <gsl/gsl_fft_real.h>
00009 #include <gsl/gsl_fft_halfcomplex.h>
00010 #include <gsl/gsl_fft_complex.h>
00011 
00012 #include <pm_fourier/angle_shift.h>
00013 #include <lama_common/point.h>
00014 
00015 using std::vector;
00016 using lama_common::Point2;
00017 
00018 double getSimpleDissimilarityFft(const vector<double> &fft1, const vector<double> &fft2, const int size)
00019 {
00020 
00021   if (fft1.size() != fft2.size() || fft1.size() == 0 || fft2.size() == 0)
00022   {
00023     std::cerr << __FUNCTION__ << ": desA.size()!=desB.size() (" << fft1.size();
00024     std::cerr << "!=" << fft2.size() << ")!\n";
00025     return 0;
00026   }
00027 
00028   size_t size_ok = size;
00029   if (size_ok > fft1.size() - 1)
00030     size_ok = fft1.size() - 1;
00031 
00032   vector<double> a(size_ok, 0.0);
00033   vector<double> b(size_ok, 0.0);
00034 
00035   for(size_t i = 0; i < size_ok; i++)
00036   {
00037     a[i] = sqrt(fft1[2 * i] * fft1[2 * i] + fft1[2 * i + 1] * fft1[2 * i + 1]);
00038     b[i] = sqrt(fft2[2 * i] * fft2[2 * i] + fft2[2 * i + 1] * fft2[2 * i + 1]);
00039     //only real part
00040     //a[i] = (fft1[2*i]);
00041     //b[i] = (fft2[2*i]);
00042   }
00043 
00044   double r = 0;
00045   for(size_t i = 0; i < a.size(); i++)
00046   {
00047     r += sqrt((a[i] - b[i]) * (a[i] - b[i]));
00048   }
00049   r /= a.size();
00050   return r;
00051 }
00052 
00053 
00059 static vector<double> convertPolygonToRange(const vector<Point2> &polygon)
00060 {
00061   vector<double> r;
00062   r.reserve(polygon.size());
00063 
00064   double sx = 0;
00065   double sy = 0;
00066 
00067   // Compute the center of the polygon.
00068   for (size_t i = 0; i < polygon.size(); i++)
00069   {
00070     sx += polygon[i].x;
00071     sy += polygon[i].y;
00072   }
00073   sx /= (double)polygon.size();
00074   sy /= (double)polygon.size();
00075 
00076   for (size_t i = 0; i< polygon.size(); i++)
00077   {
00078     const double dx = sx - polygon[i].x;
00079     const double dy = sy - polygon[i].y;
00080     const double d = std::sqrt(dx * dx + dy * dy);
00081     r.push_back(d);
00082   }
00083   return r;
00084 }
00085 
00086 
00087 double getDissimilarityFourier(const vector<Point2> &polygon1, const vector<Point2> &polygon2, const int fftSize)
00088 {
00089   if (fftSize <= 0)
00090   {
00091           std::cerr << "fftSize must be >0 !\n";
00092   }
00093 
00094   vector<double> range1(convertPolygonToRange(polygon1));
00095   vector<double> range2(convertPolygonToRange(polygon2));
00096 
00097   vector<double> f1(fft2(range1));
00098   vector<double> f2(fft2(range2));
00099   vector<double> a1;
00100   vector<double> a2;
00101 
00102   a1.reserve(f1.size());
00103   a2.reserve(f1.size());
00104 
00105   for(int i=0;i<(int)f1.size()/2;i++) {
00106     a1.push_back(f1[2*i]);
00107     a1.push_back(f1[2*i+1]);
00108 
00109     a2.push_back(f2[2*i]);
00110     a2.push_back(f2[2*i+1]);
00111   }
00112 
00113   //const double distance = getDissimilarityNccFft(a1,a2,fftSize);
00114   const double distance = getSimpleDissimilarityFft(a1,a2,fftSize);
00115 
00116   range1.clear();
00117   range2.clear();
00118   f1.clear();
00119   f2.clear();
00120   a1.clear();
00121   a2.clear();
00122 
00123   return distance;
00124 
00125 }
00126 
00127 
00128 /* returns dissimilarity through cross correlation */
00129 double getDissimilarityCorrelation(const vector<double> &range1, const vector<double> &range2)
00130 {
00131   vector<double> f1(fft2(range1));
00132   vector<double> f2(fft2(range2));
00133 
00134   double val;
00135   getAngleShiftFFT(f1, f2, val);
00136 
00137   return val;
00138 }
00139 
00140 
00141 /* returns dissimilarity through cross correlation */
00142 double getDissimilarityCorrelation(const int n1, const int n2, double *des1, double *des2)
00143 {
00144   /*
00145      vector<double> range1(getDescriptorData(n1,des1)); 
00146      vector<double> range2(getDescriptorData(n2,des2)); 
00147      vector<double> cncc(curvesNcc(range1,range2));
00148 
00149      double val = *std::max_element(cncc.begin(),cncc.end());
00150      range1.clear();
00151      range2.clear();
00152      */
00153 
00154   return 0;//val;
00155 }
00156 
00157 double getDissimilarityNccFft(const vector<double> &fft1, const vector<double> &fft2, const int size)  
00158 {
00159   if (fft1.size() != fft2.size() || fft1.size() == 0 || fft2.size() == 0)
00160   {
00161     std::cerr << __FUNCTION__ << ": desA.size()!=desB.size() (" << fft1.size();
00162     std::cerr << "!=" << fft2.size() << ")!\n";
00163     return 0;
00164   }
00165 
00166   size_t size_ok = size;
00167   if (size_ok > fft1.size() - 1)
00168     size_ok = fft1.size() - 1;
00169 
00170   vector<double> a(size_ok, 0.0);
00171   vector<double> b(size_ok, 0.0);
00172 
00173   for(size_t i = 0; i < size_ok; i++)
00174   {
00175     a[i] = fft1[2 * i] * fft1[2 * i] + fft1[2 * i + 1] * fft1[2 * i + 1];
00176     b[i] = fft2[2 * i] * fft2[2 * i] + fft2[2 * i + 1] * fft2[2 * i + 1];
00177   }
00178 
00179   double meanA = std::accumulate(a.begin(), a.end(), 0.0) / a.size();
00180   double meanB = std::accumulate(b.begin(), b.end(), 0.0) / b.size();
00181 
00182   for (size_t i = 0; i < a.size(); i++)
00183   {
00184     a[i] = a[i] - meanA;
00185     b[i] = b[i] - meanB;
00186   }
00187 
00188   double sa = 0;
00189   double sb = 0;
00190   for(size_t i = 0; i < a.size(); i++)
00191   {
00192     sa += a[i] * a[i];
00193     sb += b[i] * b[i];
00194   }
00195   sa = sqrt(sa / a.size());
00196   sb = sqrt(sb / b.size());
00197 
00198   if (sa == 0  || sb == 0)
00199   {
00200     return 0;
00201   }
00202 
00203   for (size_t i = 0; i < a.size(); i++)
00204   {
00205     a[i] = a[i] / sa;
00206     b[i] = b[i] / sb;
00207   }
00208 
00209   double r = 0;
00210   for(int i = 0; i < a.size(); i++)
00211   {
00212     r += a[i] * b[i];
00213   }
00214   r /= a.size();
00215 
00216   r = (r + 1) / 2.0;
00217 
00218   // r = 0.99xxxx --> r = 0.xxxx
00219   r =  (10000.0 * r - 9900.0) / 100.0;
00220   if (r < 0)
00221     return 0;
00222 
00223   return r;
00224 }
00225 


place_matcher_fourier
Author(s): Gaël Ecorchard , Karel Košnar , Vojtěch Vonásek
autogenerated on Sat Jun 8 2019 19:53:01