#include #include "math.hpp" #include #include #include #include #include #include #include using dataset = std::vector>; struct path_leaf_string { std::string operator()(const boost::filesystem::directory_entry& entry) const { return entry.path().leaf().string(); } }; void read_directory(const std::string& name, std::vector& v) { boost::filesystem::path p(name); boost::filesystem::directory_iterator start(p); boost::filesystem::directory_iterator end; std::transform(start, end, std::back_inserter(v), path_leaf_string()); } double distance(math::csignal& v1, math::csignal& v2, int n){ if (v1.size() != v2.size()) { throw std::runtime_error("les deux vecteurs doivent être de même longueur"); } double d = 0; auto v1_it = v1.begin(); auto v2_it = v2.begin(); while (v1_it != v1.end()) { double dist = std::abs(*(v1_it++) - *(v2_it++)); d += std::pow(dist, n); } return std::pow(d, 1/n); }; int argmax(std::vector& v){ int arg = 0; int max = v[0]; for(int i = 1; i < v.size() ; ++i){ if (v[i]>max){ arg = i; max = v[i]; }; }; return arg; }; struct pair_comp { bool operator()(std::pair a, std::pair b) { if (a.first == b.first) { return false; } if (a.first > b.first) { return true; } return false; }; }; math::csignal img2desc(std::string filename, int cmax, int threshold) { cv::Mat img = cv::imread(filename, CV_LOAD_IMAGE_COLOR); return math::descriptors(img, cmax, threshold); } dataset get_data(std::string path, int size, int cmax, int threshold) { dataset res; std::vector dirs; read_directory(path, dirs); for (auto dir: dirs) { std::vector files; read_directory(path+"/"+dir, files); std::string label = dir; int count = 0; for (int i=0; count 2) { path = argv[1]; threshold = atoi(argv[2]); } else { std::cout << "Invalid number of arguments" << std::endl; return 0; } dataset references = get_data(path, size, cmax, threshold); math::csignal sample = img2desc(path+"/arret/arret0199.jpg", cmax, threshold); std::priority_queue, std::vector>, pair_comp> neighbors; std::map labels; for (auto desc: references) { double d = distance(desc.first, sample, 1); neighbors.push({d, desc.second}); } for (int i=0; i nearest = neighbors.top(); neighbors.pop(); labels[nearest.second] += 1; } int max = 0; std::string label; for (auto val: labels) { if (val.second > max) { max = val.second; label = val.first; } } std::cout << label << std::endl; };