Séparation des fonctions de calculs et de traitement.
This commit is contained in:
parent
5f35ec91a1
commit
ea42e1722a
6 changed files with 204 additions and 15 deletions
|
@ -1,5 +1,11 @@
|
||||||
include_directories (${CMAKE_SOURCE_DIR}/src)
|
include_directories (${CMAKE_SOURCE_DIR}/src)
|
||||||
|
|
||||||
|
find_package(Qt5 COMPONENTS
|
||||||
|
Widgets
|
||||||
|
PrintSupport
|
||||||
|
REQUIRED
|
||||||
|
)
|
||||||
|
|
||||||
file(
|
file(
|
||||||
GLOB
|
GLOB
|
||||||
usage_examples
|
usage_examples
|
||||||
|
@ -9,7 +15,7 @@ file(
|
||||||
foreach(f ${usage_examples})
|
foreach(f ${usage_examples})
|
||||||
get_filename_component(exampleName ${f} NAME_WE)
|
get_filename_component(exampleName ${f} NAME_WE)
|
||||||
add_executable(${exampleName} ${f})
|
add_executable(${exampleName} ${f})
|
||||||
target_link_libraries(${exampleName} ${OpenCV_LIBS})
|
target_link_libraries(${exampleName} ${OpenCV_LIBS} fftw3 plotcpp qcustomplot Qt5::Widgets Qt5::PrintSupport)
|
||||||
install(PROGRAMS ${CMAKE_CURRENT_BINARY_DIR}/${exampleName}
|
install(PROGRAMS ${CMAKE_CURRENT_BINARY_DIR}/${exampleName}
|
||||||
DESTINATION bin
|
DESTINATION bin
|
||||||
RENAME ${CMAKE_PROJECT_NAME}-${exampleName})
|
RENAME ${CMAKE_PROJECT_NAME}-${exampleName})
|
||||||
|
|
51
examples/test-fft.cpp
Normal file
51
examples/test-fft.cpp
Normal file
|
@ -0,0 +1,51 @@
|
||||||
|
#include <fftw3.h>
|
||||||
|
#include <cmath>
|
||||||
|
#include <libplotcpp/plotcpp.hpp>
|
||||||
|
|
||||||
|
double pi() {
|
||||||
|
return 3.1415;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<double> tfd2vect(fftw_complex* tfd, int N) {
|
||||||
|
std::vector<double> res;
|
||||||
|
auto it = tfd;
|
||||||
|
for (int i = 0; i != N; ++i) {
|
||||||
|
fftw_complex c = {*it[0], *it[1]};
|
||||||
|
res.push_back(sqrt(c[0]*c[0] + c[1]*c[1]));
|
||||||
|
it++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, char** argv) {
|
||||||
|
QApplication app(argc, argv);
|
||||||
|
fftw_complex *in, *out;
|
||||||
|
fftw_plan p;
|
||||||
|
|
||||||
|
int N = 500;
|
||||||
|
in = (fftw_complex*) fftw_malloc(sizeof(fftw_complex) * N);
|
||||||
|
out = (fftw_complex*) fftw_malloc(sizeof(fftw_complex) * N);
|
||||||
|
p = fftw_plan_dft_1d(N, in, out, FFTW_FORWARD, FFTW_MEASURE);
|
||||||
|
|
||||||
|
std::vector<double> xx;
|
||||||
|
for (int i = 0; i != N; ++i) {
|
||||||
|
xx.push_back(i);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = 0; i != N; ++i) {
|
||||||
|
in[i][0] = sin(2*pi()*50*i/N);
|
||||||
|
}
|
||||||
|
|
||||||
|
fftw_execute(p); /* repeat as needed */
|
||||||
|
|
||||||
|
std::vector<double> res = tfd2vect(out, N);
|
||||||
|
PlotCpp g;
|
||||||
|
g.plot(xx, res);
|
||||||
|
g.draw();
|
||||||
|
|
||||||
|
|
||||||
|
fftw_destroy_plan(p);
|
||||||
|
fftw_free(in); fftw_free(out);
|
||||||
|
return app.exec();
|
||||||
|
}
|
|
@ -1,8 +1,11 @@
|
||||||
# file(GLOB headers *.hpp)
|
# file(GLOB headers *.hpp)
|
||||||
# file(GLOB lib_files *.cpp)
|
# file(GLOB lib_files *.cpp)
|
||||||
|
|
||||||
add_executable(traitement traitement.cpp)
|
# add_executable(traitement traitement.cpp)
|
||||||
target_link_libraries(traitement ${OpenCV_LIBS})
|
# target_link_libraries(traitement ${OpenCV_LIBS} fftw3)
|
||||||
|
|
||||||
|
add_executable(test-fft test-fft.cpp)
|
||||||
|
target_link_libraries(test-fft)
|
||||||
|
|
||||||
# target_include_directories(blk PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})
|
# target_include_directories(blk PUBLIC ${CMAKE_CURRENT_SOURCE_DIR})
|
||||||
# target_compile_options (blk PUBLIC -std=c++11 )
|
# target_compile_options (blk PUBLIC -std=c++11 )
|
||||||
|
|
111
src/math.hpp
Normal file
111
src/math.hpp
Normal file
|
@ -0,0 +1,111 @@
|
||||||
|
#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;
|
||||||
|
};
|
||||||
|
}
|
13
src/test-fft.cpp
Normal file
13
src/test-fft.cpp
Normal file
|
@ -0,0 +1,13 @@
|
||||||
|
#include <math.hpp>
|
||||||
|
#include <cmath>
|
||||||
|
|
||||||
|
int main(int argc, char** argv) {
|
||||||
|
math::signal s;
|
||||||
|
|
||||||
|
for (int i=0; i<100; ++i) {
|
||||||
|
s.push_back(std::sin(2*math::pi()*50*i/100));
|
||||||
|
}
|
||||||
|
math::fft(s);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
|
@ -1,4 +1,7 @@
|
||||||
#include "opencv2/opencv.hpp"
|
#include "opencv2/opencv.hpp"
|
||||||
|
#include <math.h>
|
||||||
|
#include <algorithm>
|
||||||
|
#include "math.hpp"
|
||||||
|
|
||||||
int filter(const cv::Mat& img, cv::Mat output, int seuil) {
|
int filter(const cv::Mat& img, cv::Mat output, int seuil) {
|
||||||
bool detect = false;
|
bool detect = false;
|
||||||
|
@ -25,12 +28,15 @@ int filter(const cv::Mat& img, cv::Mat output, int seuil) {
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(int argc, char** argv) {
|
int main(int argc, char** argv) {
|
||||||
int seuil=80;
|
int seuil=0;
|
||||||
|
|
||||||
if (argc > 1) {
|
if (argc > 1) {
|
||||||
seuil = atol(argv[1]);
|
seuil = atol(argv[1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int cmax = 10;
|
||||||
|
int N = 5000;
|
||||||
|
|
||||||
char detect;
|
char detect;
|
||||||
cv::VideoCapture cap(0);
|
cv::VideoCapture cap(0);
|
||||||
if(!cap.isOpened())
|
if(!cap.isOpened())
|
||||||
|
@ -60,15 +66,14 @@ int main(int argc, char** argv) {
|
||||||
cv::imshow("Detection", binaire);
|
cv::imshow("Detection", binaire);
|
||||||
cv::findContours(binaire, contours, hierarchy, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_NONE);
|
cv::findContours(binaire, contours, hierarchy, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_NONE);
|
||||||
cv::Mat Dessin = cv::Mat::zeros(X,Y, CV_8UC1);
|
cv::Mat Dessin = cv::Mat::zeros(X,Y, CV_8UC1);
|
||||||
unsigned int max = 0;
|
|
||||||
int id = 0;
|
int id = math::max_cont(contours);
|
||||||
for(numc = 0; numc<contours.size(); numc++) {
|
std::cout << contours[id].size() << std::endl;
|
||||||
if (contours[numc].size() > max) {
|
|
||||||
max = contours[numc].size();
|
std::vector<cv::Point> new_cont = math::simplify_contour(contours[id], cmax);
|
||||||
id = numc;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
cv::drawContours(Dessin, contours, id, 255);
|
cv::drawContours(Dessin, contours, id, 255);
|
||||||
|
cv::drawContours(Dessin, new_cont, id, 255);
|
||||||
cv::imshow("Contours", Dessin);
|
cv::imshow("Contours", Dessin);
|
||||||
if(cv::waitKey(30) == 27) {
|
if(cv::waitKey(30) == 27) {
|
||||||
break;
|
break;
|
||||||
|
|
Loading…
Reference in a new issue