5 changed files with 209 additions and 116 deletions
@ -1,13 +1,7 @@ |
|||
# file(GLOB headers *.hpp) |
|||
# file(GLOB lib_files *.cpp) |
|||
|
|||
add_executable(traitement traitement.cpp) |
|||
target_link_libraries(traitement ${OpenCV_LIBS}) |
|||
|
|||
#add_executable(k_proches_voisins k_proches_voisins.cpp) |
|||
#target_link_libraries(k_proches_voisins ${OpenCV_LIBS}) |
|||
# target_include_directories(blk PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}) |
|||
# target_compile_options (blk PUBLIC -std=c++11 ) |
|||
find_package(Boost COMPONENTS system filesystem REQUIRED) |
|||
|
|||
# install(TARGETS blk DESTINATION lib ) |
|||
# install(FILES ${headers} DESTINATION include/${CMAKE_PROJECT_NAME}) |
|||
add_executable(knn knn.cpp) |
|||
target_link_libraries(knn ${OpenCV_LIBS} ${Boost_FILESYSTEM_LIBRARY} ${Boost_SYSTEM_LIBRARY}) |
|||
|
|||
@ -1,87 +0,0 @@ |
|||
#include <map> |
|||
#include "math.hpp" |
|||
#include <stdexcept> |
|||
|
|||
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; |
|||
double di; |
|||
for (int i=0; i<v1.size(); ++i){ |
|||
di = std::abs(v1[i] - v2[i]); |
|||
di = std::pow(di, n); |
|||
d = d + di; |
|||
}; |
|||
return std::pow(d, 1/n); |
|||
}; |
|||
|
|||
int argmax(std::vector<int>& 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; |
|||
}; |
|||
|
|||
//int main(math::csignal new_vect, std::map< math::csignal, std::string > dico, int k){
|
|||
int main(int argc, char** argv) { |
|||
std::vector<std::pair<double, math::csignal>> k_min; |
|||
std::map<math::csignal, std::string> dico; |
|||
math::csignal new_vect; |
|||
int k; |
|||
double d; |
|||
int avance = 0; |
|||
int arret = 0; |
|||
int droite = 0; |
|||
int gauche = 0; |
|||
int rejet = 0; |
|||
std::vector<int> vchoix; |
|||
for(auto& ref_vect : dico){ |
|||
d = distance(new_vect, ref_vect.first); |
|||
if (k_min.size() < k ){ |
|||
k_min.push_back({d, ref_vect.first}); |
|||
} else if (d < k_min[k-1].first){ |
|||
k_min.push_back({d, ref_vect.first}); |
|||
sort(k_min.begin(), k_min.end()); |
|||
k_min.pop_back(); |
|||
} |
|||
|
|||
} |
|||
for(auto i = k_min.begin(); i != k_min.end(); i++) { |
|||
if (dico[k_min[i].second].second == "avance"){ |
|||
avance = avance + 1 |
|||
} else if (dico[k_min[i].second].second == "arret"){ |
|||
arret = arret + 1 |
|||
} else if (dico[k_min[i].second].second == "droite"){ |
|||
arret = droite + 1 |
|||
} else if (dico[k_min[i].second].second == "gauche"){ |
|||
arret = gauche + 1 |
|||
} else if (dico[k_min[i].second].second == "rejet"){ |
|||
arret = rejet + 1 |
|||
} |
|||
} |
|||
vchoix.push_back(avance); |
|||
vchoix.push_back(arret); |
|||
vchoix.push_back(droite); |
|||
vchoix.push_back(gauche); |
|||
vchoix.push_back(rejet); |
|||
|
|||
int nchoix = argmax(vchoix); |
|||
std::string choix; |
|||
if (nchoix == 0){ |
|||
choix = "avance" |
|||
} else if (nchoix == 1){ |
|||
choix = "arret" |
|||
} else if (nchoix == 2){ |
|||
choix = "droite" |
|||
} else if (nchoix == 3){ |
|||
choix = "gauche" |
|||
} else if (nchoix == 4){ |
|||
choix = "rejet" |
|||
} |
|||
}; |
|||
@ -0,0 +1,139 @@ |
|||
#include <map> |
|||
#include "math.hpp" |
|||
#include <stdexcept> |
|||
#include <queue> |
|||
#include <opencv2/opencv.hpp> |
|||
#include <boost/filesystem.hpp> |
|||
#include <iterator> |
|||
#include <iostream> |
|||
#include <algorithm> |
|||
|
|||
using dataset = std::vector<std::pair<math::csignal, std::string>>; |
|||
|
|||
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<std::string>& 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<int>& 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<double, std::string> a, std::pair<double, std::string> 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<std::string> dirs; |
|||
read_directory(path, dirs); |
|||
for (auto dir: dirs) { |
|||
std::vector<std::string> files; |
|||
read_directory(path+"/"+dir, files); |
|||
|
|||
std::string label = dir; |
|||
int count = 0; |
|||
for (int i=0; count<size/4 && i<files.size(); ++i) { |
|||
try { |
|||
math::csignal d = img2desc(path+"/"+dir+"/"+files[i], cmax, threshold); |
|||
res.push_back({d, label}); |
|||
count++; |
|||
} catch (std::length_error& e) { |
|||
std::cout << "No contour: image skiped." << std::endl; |
|||
} |
|||
} |
|||
std::cout << res.size() << std::endl; |
|||
} |
|||
return res; |
|||
} |
|||
|
|||
int main(int argc, char** argv) { |
|||
|
|||
int k = 20; |
|||
int size = 100; |
|||
std::string path; |
|||
int cmax = 10; |
|||
int threshold = 20; |
|||
|
|||
if (argc > 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::pair<double, std::string>, std::vector<std::pair<double, std::string>>, pair_comp> neighbors; |
|||
std::map<std::string, int> labels; |
|||
|
|||
for (auto desc: references) { |
|||
double d = distance(desc.first, sample, 1); |
|||
neighbors.push({d, desc.second}); |
|||
} |
|||
|
|||
for (int i=0; i<k; ++i) { |
|||
std::pair<double, std::string> 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; |
|||
}; |
|||
Loading…
Reference in new issue