miniprojet/src/math.hpp

112 lines
2.6 KiB
C++

#pragma once
#include <vector>
#include <complex>
#include <opencv2/opencv.hpp>
#include <iterator>
#include <cmath>
namespace math {
using complex = std::complex<float>;
using signal = std::vector<double>;
using csignal = std::vector<complex>;
using contour = std::vector<cv::Point>;
constexpr double pi() {return std::atan(1)*4;}
//TODO implémenter la fft
csignal fft(const signal& input) {
//TODO: s'assurer que le signal est bien formé (i.e. bonne taille)
return fft_rec(input);
};
csignal fft_rec(const signal& input) {
int size = input.size();
if (size == 1) {
return input;
} else {
signal odd;
signal even;
std::back_insert_iterator<signal> odd_back_it(odd);
std::back_insert_iterator<signal> even_back_it(even);
bool insert_in_even = false;
for (auto it = input.begin(); it != input.end(); ++it) {
if (insert_in_even) {
*even_back_it++ = *it;
insert_in_even = false;
} else {
*odd_back_it++ = *it;
insert_in_even = true;
}
}
signal odd_fft = fft_rec(odd);
signal even_fft = fft_rec(even);
signal res;
res.reserve(size);
for (int k = 0; k<size/2; ++k) {
complex t = std::exp(complex(0, -2*pi()*k/size))*odd[k];
res[k] = even[k] + t;
res[size/2+k] = even[k] - t;
}
return res;
}
}
complex mean(const signal& sig) {
complex res = 0;
for (auto x: sig) {
res += x;
}
return complex(res.real()/sig.size(), res.imag()/sig.size());
};
signal cont2sig(const contour& cont) {
signal sig;
auto sig_it = sig.begin();
auto cont_it = cont.begin();
for (auto cont_it = cont.begin(); cont_it != cont.end(); ++cont_it) {
*sig_it = complex((*cont_it).x, (*cont_it).y);
sig_it++;
}
return sig;
};
contour coef2cont(const signal& tfd, complex mean, int size, int cmax) {
contour cont;
auto tf_it = tfd.begin();
auto cont_it = cont.begin();
for (auto tf_it = tfd.begin(); tf_it != tfd.end(); ++tf_it) {
//TODO retrouver la formule
//*cont_it = mean;
}
return cont;
};
int max_cont(const std::vector<contour>& contours) {
int max = 0;
int id = 0;
for (int i=0; i<contours.size(); ++i) {
if (contours[i].size() > max) {
max = contours[i].size();
id = i;
}
}
return id;
};
contour simplify_contour(const contour& cont, int cmax) {
contour res;
signal z = cont2sig(cont);
complex zm = mean(z);
signal tfd = fft(z);
res = coef2cont(tfd, zm, 0, cmax);
return res;
};
}