correction d'erreurs

This commit is contained in:
Guillaume Courrier 2019-12-09 12:10:42 +01:00
parent fd8ce8bbff
commit f895134c04
3 changed files with 88 additions and 55 deletions

View file

@ -4,34 +4,53 @@ int main(int argc, char** argv) {
std::string imagename = ""; std::string imagename = "";
int seuil = 25; int seuil = 25;
int cmax = 10; int cmax = 10;
if (argc > 2) {
if (argc > 1) {
imagename = argv[1]; imagename = argv[1];
} else {
std::cout << "Invalid number of arguments: test-descripteurs <path_to_image> [<threshold>]";
return 0;
}
if (argc > 2) {
seuil = atoi(argv[2]); seuil = atoi(argv[2]);
} }
cv::namedWindow("Image", CV_WINDOW_AUTOSIZE); cv::namedWindow("Image", CV_WINDOW_AUTOSIZE);
cv::namedWindow("Binaire", CV_WINDOW_AUTOSIZE); cv::namedWindow("Binaire", CV_WINDOW_AUTOSIZE);
cv::namedWindow("Contour", CV_WINDOW_AUTOSIZE); cv::namedWindow("Contour", CV_WINDOW_AUTOSIZE);
cv::namedWindow("New Contour", CV_WINDOW_AUTOSIZE);
cv::Mat image = cv::imread(imagename, CV_LOAD_IMAGE_COLOR); cv::Mat image = cv::imread(imagename, CV_LOAD_IMAGE_COLOR);
cv::Mat binaire(image.rows, image.cols, CV_8UC1); cv::Mat binaire(image.rows, image.cols, CV_8UC1);
cv::Mat contour_image(image.rows, image.cols, CV_8UC1); cv::Mat contour_image(image.rows, image.cols, CV_8UC1);
cv::Mat new_contour_image(image.rows, image.cols, CV_8UC1);
std::vector<std::vector<cv::Point>> contours; std::vector<math::contour> contours;
std::vector<std::vector<cv::Point>> contrs; std::vector<math::contour> contrs;
std::vector<cv::Vec4i> hierarchy; std::vector<cv::Vec4i> hierarchy;
math::filter(image, binaire, seuil); math::filter(image, binaire, seuil);
cv::findContours(binaire, contours, hierarchy, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_NONE); cv::findContours(binaire, contours, hierarchy, CV_RETR_EXTERNAL, CV_CHAIN_APPROX_NONE);
int index = math::max_cont(contours); int index = math::max_cont(contours);
math::contour c = contours[index];
c = math::simplify_contour(c, cmax);
std::array<int, 4> bounds = math::bounds(c);
c = transform(c, bounds);
contrs.push_back(contours[index]); contrs.push_back(contours[index]);
contrs.push_back(math::simplify_contour(contrs[0], cmax)); contrs.push_back(c);
cv::drawContours(contour_image, contrs, -1, 255); cv::drawContours(contour_image, contrs, 0, 255);
cv::drawContours(new_contour_image, contrs, 1, 255);
/*
*/
imshow("Image", image); imshow("Image", image);
imshow("Binaire", binaire); imshow("Binaire", binaire);
imshow("Contour", contour_image); imshow("Contour", contour_image);
imshow("New Contour", new_contour_image);
cv::waitKey(0); cv::waitKey(0);
return 0; return 0;

View file

@ -22,18 +22,21 @@ namespace math {
int indexNB; int indexNB;
for (int index=0,indexNB=0;index<dim*rows*cols;index+=dim,indexNB++) { for (int index=0,indexNB=0;index<dim*rows*cols;index+=dim,indexNB++) {
detect=0; detect = false;
B = img.data[index ]; B = img.data[index ];
G = img.data[index + 1]; G = img.data[index+1];
R = img.data[index + 2]; R = img.data[index+2];
if ((R>G) && (R>B)) if ((R>G) && (R>B)) {
if (((R-B)>=seuil) || ((R-G)>=seuil)) if (((R-B)>=seuil) || ((R-G)>=seuil)) {
detect=1; detect = true;
if (detect==1) }
}
if (detect==1) {
output.data[indexNB]=255; output.data[indexNB]=255;
else } else {
output.data[indexNB]=0; output.data[indexNB]=0;
}
} }
} }
@ -105,6 +108,7 @@ namespace math {
} else { } else {
opt_size = 1 << (int)std::ceil(std::log(N)/std::log(2)); opt_size = 1 << (int)std::ceil(std::log(N)/std::log(2));
} }
opt_size = input.size();
csignal sig(input); csignal sig(input);
for (int i=0; i<opt_size-input.size(); ++i) { for (int i=0; i<opt_size-input.size(); ++i) {
sig.push_back(complex(0, 0)); sig.push_back(complex(0, 0));
@ -136,12 +140,12 @@ namespace math {
} }
} }
csignal extract(const csignal& tfd, int cmax) { csignal extract(const csignal& tfd, int cmin, int cmax) {
csignal res; csignal res;
for (int k=0; k<cmax; ++k) { int kmin = tfd.size()/2 + cmin;
res.push_back(tfd[tfd.size() - cmax + k]); int kmax = tfd.size()/2 + cmax;
}
for (int k=cmax; k<2*cmax; ++k) { for (int k=kmin; k<kmax; ++k) {
res.push_back(tfd[k]); res.push_back(tfd[k]);
} }
return res; return res;
@ -155,41 +159,75 @@ namespace math {
return res; return res;
} }
csignal desc2sig(const csignal& desc, complex mean, int N, int kmin) { csignal desc2sig(const csignal& desc, complex mean, int N, int cmin, int cmax) {
csignal cont; csignal cont;
auto desc_it = desc.begin(); auto desc_it = desc.begin();
int kmin = desc.size()/2 + cmin;
int kmax = desc.size()/2 + cmax;
for (int m=0; m<N; ++m) { for (int m=0; m<N; ++m) {
complex sum; complex sum;
for (int k=0; k<desc.size(); ++k) { for (int k=kmin; k<kmax; ++k) {
sum += desc[k]*std::exp(complex(0, 2*pi()*(k+kmin)*m/N)); sum += desc[k]*std::exp(complex(0, 2*pi()*k*m/N));
} }
cont.push_back(mean + sum); cont.push_back(mean + sum);
} }
return cont; return cont;
}; };
std::array<int, 4> bounds(const contour& cont) {
std::array<int, 4> res = {cont[0].x, cont[0].y, cont[0].x, cont[0].y};
for (auto p: cont) {
if (res[0] > p.x) {
res[0] = p.x;
}
if (res[1] > p.y) {
res[1] = p.y;
}
if (res[2] < p.x) {
res[2] = p.x;
}
if (res[3] < p.y) {
res[3] = p.y;
}
}
return res;
}
contour transform(contour& cont, std::array<int, 4>& bounds) {
contour res;
for (auto p: cont) {
int px = (p.x - bounds[0])/(bounds[2]-bounds[0]);
int py = (p.y - bounds[1])/(bounds[3]-bounds[1]);
res.push_back(cv::Point(px, py));
}
return res;
}
contour simplify_contour(const contour& cont, int cmax) { contour simplify_contour(const contour& cont, int cmax) {
csignal z = cont2sig(cont); csignal z = cont2sig(cont);
complex zm = mean(z); complex zm = mean(z);
csignal tfd = fft(diff(z, zm)); csignal tfd = fft(diff(z, zm));
tfd /= tfd.size(); tfd /= tfd.size();
csignal desc = extract(tfd, cmax); int cmin = -cmax;
csignal desc = extract(tfd, cmin, cmax);
if (std::abs(desc[desc.size()-1]) > std::abs(desc[0])) { if (std::abs(desc[desc.size()/2-1]) > std::abs(desc[desc.size()/2+1])) {
std::reverse(desc.begin(), desc.end()); std::reverse(desc.begin(), desc.end());
} }
double phy = std::arg(desc[desc.size()-1]*desc[0])/2; double phy = std::arg(desc[desc.size()/2-1]*desc[desc.size()/2+1])/2;
desc *= std::exp(complex(0, -phy)); desc *= std::exp(complex(0, -phy));
double theta = std::arg(desc[0]); double theta = std::arg(desc[desc.size()/2+1]);
for (int k=0; k<desc.size(); ++k) { for (int k=0; k<desc.size(); ++k) {
desc[k] *= std::exp(complex(0, -theta*k)); desc[k] *= std::exp(complex(0, -theta*(k-cmin)));
} }
desc /= desc[0]; desc /= desc[desc.size()/2+1];
csignal sig = desc2sig(desc, zm, z.size(), cmax); csignal sig = desc2sig(desc, zm, z.size(), cmin, cmax);
return sig2cont(sig); return sig2cont(sig);
}; };

View file

@ -3,32 +3,8 @@
#include <algorithm> #include <algorithm>
#include "math.hpp" #include "math.hpp"
int filter(const cv::Mat& img, cv::Mat output, int seuil) {
bool detect = false;
uchar R, G, B;
int rows = img.rows;
int cols = img.cols;
int dim = img.channels();
int indexNB;
for (int index=0,indexNB=0;index<dim*rows*cols;index+=dim,indexNB++) {
detect=0;
B = img.data[index ];
G = img.data[index + 1];
R = img.data[index + 2];
if ((R>G) && (R>B))
if (((R-B)>=seuil) || ((R-G)>=seuil))
detect=1;
if (detect==1)
output.data[indexNB]=255;
else
output.data[indexNB]=0;
}
}
int main(int argc, char** argv) { int main(int argc, char** argv) {
int seuil=80; int seuil=65;
int cmax = 10; int cmax = 10;
int N = 5000; int N = 5000;
@ -61,7 +37,7 @@ int main(int argc, char** argv) {
Y=frame.cols; Y=frame.cols;
DIM=frame.channels(); DIM=frame.channels();
filter(frame, binaire, seuil); math::filter(frame, binaire, seuil);
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);