code cleanup, started report, new verbose option
This commit is contained in:
parent
13e59c2dc4
commit
eb1046603d
@ -17,6 +17,7 @@ conan_basic_setup()
|
|||||||
enable_cxx_compiler_flag_if_supported("-Wall")
|
enable_cxx_compiler_flag_if_supported("-Wall")
|
||||||
enable_cxx_compiler_flag_if_supported("-pedantic")
|
enable_cxx_compiler_flag_if_supported("-pedantic")
|
||||||
enable_cxx_compiler_flag_if_supported("-O3")
|
enable_cxx_compiler_flag_if_supported("-O3")
|
||||||
|
enable_cxx_compiler_flag_if_supported("-flto")
|
||||||
|
|
||||||
# include_directories(<PUBLIC HEADER DIRECTORIES>)
|
# include_directories(<PUBLIC HEADER DIRECTORIES>)
|
||||||
set(TGT genetic-image)
|
set(TGT genetic-image)
|
||||||
|
13
README.org
13
README.org
@ -53,7 +53,7 @@ use it, first install clang-7 and lldb 7, then run this:
|
|||||||
conan profile new default --detect
|
conan profile new default --detect
|
||||||
conan profile update settings.compiler=clang default
|
conan profile update settings.compiler=clang default
|
||||||
conan profile update settings.compiler.version=7.0 default
|
conan profile update settings.compiler.version=7.0 default
|
||||||
conan profile update settings.compiler.libcxx=libstdc++ default
|
conan profile update settings.compiler.libcxx=libstdc++11 default
|
||||||
conan profile update env.CC=/bin/clang default
|
conan profile update env.CC=/bin/clang default
|
||||||
conan profile update env.CXX=/bin/clang++ default
|
conan profile update env.CXX=/bin/clang++ default
|
||||||
#+end_src
|
#+end_src
|
||||||
@ -65,7 +65,7 @@ Then, To build and run the program, go to the root of the project and run this:
|
|||||||
#+begin_src shell
|
#+begin_src shell
|
||||||
mkdir build && cd build
|
mkdir build && cd build
|
||||||
conan install .. --build missing
|
conan install .. --build missing
|
||||||
cmake -DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++ .. -G Ninja
|
cmake -DCMAKE_CXX_COMPILER=clang++ .. -G Ninja
|
||||||
cmake --build .
|
cmake --build .
|
||||||
#+end_src
|
#+end_src
|
||||||
If you want to use another profile than your default one, you should run the
|
If you want to use another profile than your default one, you should run the
|
||||||
@ -74,6 +74,15 @@ following line instead of the second line:
|
|||||||
conan install .. --build missing --profile <your_profile>
|
conan install .. --build missing --profile <your_profile>
|
||||||
#+end_src
|
#+end_src
|
||||||
|
|
||||||
|
If you do not wish to build your project with Ninja but with another generator,
|
||||||
|
such as Unix Makefiles, simply replace ~Ninja~ in the second to last ~cmake~
|
||||||
|
command with the name of your generator. For instance:
|
||||||
|
#+begin_src shell
|
||||||
|
cmake -DCMAKE_CXX_COMPILER=clang++ .. -G "Unix Makefiles"
|
||||||
|
#+end_src
|
||||||
|
You can still build your project by running ~cmake --build .~ or by running
|
||||||
|
~make~ manually.
|
||||||
|
|
||||||
This project was built and tested using clang-7, lldb and gdb on Void Linux
|
This project was built and tested using clang-7, lldb and gdb on Void Linux
|
||||||
(kernel 4.19) and Arch Linux (kernel 5.0).
|
(kernel 4.19) and Arch Linux (kernel 5.0).
|
||||||
|
|
||||||
|
5
doc/.gitignore
vendored
Normal file
5
doc/.gitignore
vendored
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
# Ignore everything in this directory
|
||||||
|
*
|
||||||
|
# Except this file
|
||||||
|
!.gitignore
|
||||||
|
!Doxyfile
|
2494
doc/Doxyfile
Normal file
2494
doc/Doxyfile
Normal file
File diff suppressed because it is too large
Load Diff
BIN
img/mahakala-monochrome.jpg
Normal file
BIN
img/mahakala-monochrome.jpg
Normal file
Binary file not shown.
After Width: | Height: | Size: 68 KiB |
@ -5,13 +5,10 @@
|
|||||||
#include <opencv2/highgui/highgui.hpp>
|
#include <opencv2/highgui/highgui.hpp>
|
||||||
#include <spdlog/spdlog.h>
|
#include <spdlog/spdlog.h>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <tuple>
|
#include <utility>
|
||||||
#include <random>
|
|
||||||
|
|
||||||
std::tuple<cv::Mat, cv::Mat> init_image(std::string const &);
|
std::pair<cv::Mat, cv::Mat> init_image(std::string const &);
|
||||||
|
|
||||||
double euclidian_distance(cv::Mat const &, cv::Mat const &);
|
double euclidian_distance(cv::Mat const &, cv::Mat const &);
|
||||||
|
|
||||||
cv::Scalar random_color(std::mt19937 &);
|
|
||||||
|
|
||||||
#endif /* GENETIC_IMAGE_INCLUDE_GENIMG_COMMON_HH_ */
|
#endif /* GENETIC_IMAGE_INCLUDE_GENIMG_COMMON_HH_ */
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
#ifndef GENETIC_IMAGE_INCLUDE_GENIMG_METHOD1_METHOD1_HH_
|
#ifndef GENETIC_IMAGE_INCLUDE_GENIMG_METHODS_HH_
|
||||||
#define GENETIC_IMAGE_INCLUDE_GENIMG_METHOD1_METHOD1_HH_
|
#define GENETIC_IMAGE_INCLUDE_GENIMG_METHODS_HH_
|
||||||
|
|
||||||
#include <opencv2/core/core.hpp>
|
#include <opencv2/core/core.hpp>
|
||||||
#include <opencv2/highgui/highgui.hpp>
|
#include <opencv2/highgui/highgui.hpp>
|
||||||
@ -12,4 +12,4 @@ void method1(cv::Mat &t_reference, cv::Mat &t_output, int t_iterations,
|
|||||||
void method2(cv::Mat &t_reference, cv::Mat &t_output, int t_iterations,
|
void method2(cv::Mat &t_reference, cv::Mat &t_output, int t_iterations,
|
||||||
std::mt19937 &t_gen);
|
std::mt19937 &t_gen);
|
||||||
|
|
||||||
#endif /* GENETIC_IMAGE_INCLUDE_GENIMG_METHOD1_METHOD1_HH_ */
|
#endif /* GENETIC_IMAGE_INCLUDE_GENIMG_METHODS_HH_ */
|
@ -2,10 +2,9 @@
|
|||||||
#define GENETIC_IMAGE_INCLUDE_GENIMG_PARSEARGS_HH_
|
#define GENETIC_IMAGE_INCLUDE_GENIMG_PARSEARGS_HH_
|
||||||
|
|
||||||
#include <filesystem>
|
#include <filesystem>
|
||||||
#include <string>
|
|
||||||
#include <tuple>
|
#include <tuple>
|
||||||
|
|
||||||
std::tuple<std::filesystem::path, std::filesystem::path, bool, int, int>
|
std::tuple<std::filesystem::path, std::filesystem::path, bool, int, int, bool>
|
||||||
parse_args(int, char **);
|
parse_args(int, char **);
|
||||||
|
|
||||||
#endif /* GENETIC_IMAGE_INCLUDE_GENIMG_PARSEARGS_HH_ */
|
#endif /* GENETIC_IMAGE_INCLUDE_GENIMG_PARSEARGS_HH_ */
|
||||||
|
3
report/.gitignore
vendored
Normal file
3
report/.gitignore
vendored
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
auto/
|
||||||
|
_minted*/
|
||||||
|
*.tex
|
91
report/report.org
Normal file
91
report/report.org
Normal file
@ -0,0 +1,91 @@
|
|||||||
|
#+TITLE: Création d’images par algorithme génétique avec référence
|
||||||
|
#+SUBTITLE: Rapport de projet
|
||||||
|
#+AUTHOR: Lucien Cartier-Tilet
|
||||||
|
#+EMAIL: phundrak@phundrak.fr
|
||||||
|
#+CREATOR: Lucien Cartier-Tilet
|
||||||
|
#+LANGUAGE: fr
|
||||||
|
#+LATEX_CLASS: article
|
||||||
|
#+LaTeX_CLASS_OPTIONS: [a4paper,twoside]
|
||||||
|
#+LATEX_HEADER: \usepackage{xltxtra,fontspec,xunicode}\usepackage[total={6.5in,9.5in}]{geometry}\setromanfont[Numbers=Lowercase]{Charis SIL}
|
||||||
|
#+LATEX_HEADER: \usepackage{xcolor} \usepackage{hyperref}
|
||||||
|
#+LATEX_HEADER: \hypersetup{colorlinks=true,linkbordercolor=red,linkcolor=blue,pdfborderstyle={/S/U/W 1}}
|
||||||
|
#+STARTUP: latexpreview
|
||||||
|
|
||||||
|
* Sujet
|
||||||
|
|
||||||
|
Le sujet de ce projet est la création d’un logiciel pouvant recréer une image
|
||||||
|
fournie grâce à des générations aléatoires et successives de formes aux,
|
||||||
|
positions, couleurs et taille aléatoires. L’algorithme commence par créer une
|
||||||
|
image vide aux dimensions identiques à l’image de référence, puis applique une
|
||||||
|
de ces formes aléatoires. Si la ressemblance de l’image ainsi générée augmente
|
||||||
|
par rapport à sa version précédente par rapport à l’image de référence, alors
|
||||||
|
cette modification est conservée, sinon elle est annulée. Répéter jusqu’à
|
||||||
|
satisfaction.
|
||||||
|
|
||||||
|
* Les méthodes utilisées
|
||||||
|
|
||||||
|
Plusieurs approches au problème sont possibles, allant de la simple
|
||||||
|
implémentation naïve du problème à des moyen pouvant au moins décupler la
|
||||||
|
vitesse de génération de l’image. Sauf indication contraire, j’ai utilisé dans
|
||||||
|
l’implémentation de chaque méthode des carrés comme forme d’éléments appliqués
|
||||||
|
aléatoirement à l’image.
|
||||||
|
|
||||||
|
Pour évaluer la ressemblance entre deux image, j’évalue une distance euclidienne
|
||||||
|
entre le vecteur de leurs pixels qui peut se résumer à ceci :
|
||||||
|
#+begin_export latex
|
||||||
|
$$\sqrt{\sum_{i=0}^{n} V_{i}^{2}+W_{i}^{2}}$$
|
||||||
|
#+end_export
|
||||||
|
~V~ étant le vecteur de pixels de l’image de référence, ~W~ étant le vecteur de
|
||||||
|
pixels de l’image générée, et ~n~ la taille de ces deux vecteurs.
|
||||||
|
|
||||||
|
Les tests de temps sont réalisés sur un Thinkpad x220, disposant d’un processeur
|
||||||
|
Intel® Core™ i5-2540M à 2.6GHz, composé de deux cœurs supportant chacun deux
|
||||||
|
threads, et de 4Go de RAM. Le programme est compilé avec les options
|
||||||
|
d’optimisation ~-O3~ et ~-flto~.
|
||||||
|
|
||||||
|
Voici également ci-dessous la liste des options et arguments possibles
|
||||||
|
concernant l’exécution du logiciel.
|
||||||
|
#+begin_src text
|
||||||
|
$ ./bin/genetic-image -h
|
||||||
|
Allowed options:
|
||||||
|
-h [ --help ] Display this help message
|
||||||
|
-i [ --input ] arg Input image
|
||||||
|
-o [ --output ] arg Image or video output path (default: input path +
|
||||||
|
"_output")
|
||||||
|
-m [ --method ] arg Method number to be used (default: 1)
|
||||||
|
-n [ --iterations ] arg Number of iterations (default: 5000)
|
||||||
|
-v [ --video ] Enable video output
|
||||||
|
#+end_src
|
||||||
|
|
||||||
|
** Méthode naïve
|
||||||
|
|
||||||
|
J’ai tout d’abord implémenté la méthode naïve afin d’avoir une référence en
|
||||||
|
matière de temps. Cette dernière est implémentée dans ~src/methods.cc~ avec la
|
||||||
|
fonction ~method1()~. Comme ce à quoi je m’attendais, cette méthode de
|
||||||
|
génération d’images est très lente, principalement dû au fait que l’algorithme
|
||||||
|
en l’état essaiera d’appliquer des couleurs n’existant pas dans l’image de
|
||||||
|
référence, voire complètement à l’opposées de la palette de couleurs de l’image
|
||||||
|
de référence.
|
||||||
|
|
||||||
|
Voici la ligne de commande utilisée depuis le répertoire ~build~ afin de pouvoir
|
||||||
|
obtenir un temps d’exécution :
|
||||||
|
#+begin_src shell
|
||||||
|
perf stat -r nombreDExécutions -B ./bin/genetic-image \
|
||||||
|
-i ../img/mahakala-monochrome.jpg -o output.png -n 200 -m 1
|
||||||
|
#+end_src
|
||||||
|
|
||||||
|
| / | < | < |
|
||||||
|
| nombre d’itérations réussies | nombre d’exécutions | temps d’exécution moyen |
|
||||||
|
|------------------------------+---------------------+-------------------------|
|
||||||
|
| 10 | 100 | 0.09447s (±0.02%) |
|
||||||
|
| 50 | 100 | 1.1331s (±2.85%) |
|
||||||
|
| 100 | 50 | |
|
||||||
|
| 200 | 20 | |
|
||||||
|
| 500 | 10 | |
|
||||||
|
| 1000 | 5 | |
|
||||||
|
|
||||||
|
Naturellement, la variation en temps d’exécution croît en même temps que le
|
||||||
|
nombre d’améliorations nécessaires à apporter à l’image à améliorer, dû à la
|
||||||
|
nature aléatoire de l’algorithme. Cependant, on constate également une
|
||||||
|
croissance importante du temps d’exécution suivant également ce nombre
|
||||||
|
d’itérations réussies.
|
BIN
report/report.pdf
Normal file
BIN
report/report.pdf
Normal file
Binary file not shown.
@ -3,18 +3,18 @@
|
|||||||
#include <cmath>
|
#include <cmath>
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
|
|
||||||
std::tuple<cv::Mat, cv::Mat> init_image(std::string const &t_input_file) {
|
std::pair<cv::Mat, cv::Mat> init_image(std::string const &t_input_file) {
|
||||||
cv::Mat input_image = cv::imread(t_input_file, cv::IMREAD_COLOR);
|
cv::Mat input_image = cv::imread(t_input_file, cv::IMREAD_COLOR);
|
||||||
if (!input_image.data) {
|
if (!input_image.data) {
|
||||||
spdlog::critical("Could not open or find image!\n");
|
spdlog::critical("Could not open or find image!\n");
|
||||||
exit(-1);
|
exit(-1);
|
||||||
}
|
}
|
||||||
spdlog::info("Image loaded!");
|
spdlog::debug("Image loaded!");
|
||||||
spdlog::info("Width:\t\t{}", input_image.size().width);
|
spdlog::debug("Width:\t\t{}", input_image.size().width);
|
||||||
spdlog::info("Height:\t{}", input_image.size().height);
|
spdlog::debug("Height:\t{}", input_image.size().height);
|
||||||
cv::Mat process_image(input_image.size().height, input_image.size().width,
|
cv::Mat process_image(input_image.size().height, input_image.size().width,
|
||||||
CV_8UC3, cv::Scalar(0, 0, 0));
|
CV_8UC3, cv::Scalar(0, 0, 0));
|
||||||
return std::make_tuple(std::move(input_image), process_image);
|
return std::make_pair(std::move(input_image), process_image);
|
||||||
}
|
}
|
||||||
|
|
||||||
double euclidian_distance(cv::Mat const &t_img1, cv::Mat const &t_img2) {
|
double euclidian_distance(cv::Mat const &t_img1, cv::Mat const &t_img2) {
|
||||||
@ -28,8 +28,3 @@ double euclidian_distance(cv::Mat const &t_img1, cv::Mat const &t_img2) {
|
|||||||
euclidian = std::sqrt(euclidian);
|
euclidian = std::sqrt(euclidian);
|
||||||
return euclidian;
|
return euclidian;
|
||||||
}
|
}
|
||||||
|
|
||||||
cv::Scalar random_color(std::mt19937 &t_gen) {
|
|
||||||
static std::uniform_int_distribution<> dis(0, 255);
|
|
||||||
return cv::Scalar(dis(t_gen), dis(t_gen), dis(t_gen));
|
|
||||||
}
|
|
||||||
|
16
src/main.cc
16
src/main.cc
@ -1,14 +1,16 @@
|
|||||||
#include "common.hh"
|
#include "common.hh"
|
||||||
#include "method1.hh"
|
#include "methods.hh"
|
||||||
#include "parseargs.hh"
|
#include "parseargs.hh"
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
int main(int ac, char **av) {
|
int main(int ac, char **av) {
|
||||||
auto const [input_file, output_file, video_output, iterations, method] =
|
auto const [input_file, output_file, video_output, iterations, method,
|
||||||
parse_args(ac, av);
|
verbose] = parse_args(ac, av);
|
||||||
spdlog::info("Input file:\t{}", input_file.native());
|
spdlog::set_level(verbose ? spdlog::level::debug : spdlog::level::info);
|
||||||
spdlog::info("Output file:\t{}", output_file.native());
|
spdlog::debug("Input file:\t{}", input_file.native());
|
||||||
spdlog::info("Video output:\t{}", video_output);
|
spdlog::debug("Output file:\t{}", output_file.native());
|
||||||
spdlog::info("Iterations:\t{}", iterations);
|
spdlog::debug("Video output:\t{}", video_output);
|
||||||
|
spdlog::debug("Iterations:\t{}", iterations);
|
||||||
auto [input_image, process_image] = init_image(input_file.native());
|
auto [input_image, process_image] = init_image(input_file.native());
|
||||||
std::random_device rd;
|
std::random_device rd;
|
||||||
std::mt19937 gen(rd());
|
std::mt19937 gen(rd());
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
#include "method1.hh"
|
#include "methods.hh"
|
||||||
#include "common.hh"
|
#include "common.hh"
|
||||||
#include "drawing.hh"
|
#include "drawing.hh"
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
@ -13,34 +13,21 @@ using randint = std::uniform_int_distribution<>;
|
|||||||
using Color = std::array<uchar, 3>;
|
using Color = std::array<uchar, 3>;
|
||||||
using ColorSet = std::vector<Color>;
|
using ColorSet = std::vector<Color>;
|
||||||
|
|
||||||
|
namespace methods_private {
|
||||||
|
|
||||||
|
cv::Scalar randomColor(std::mt19937 &t_gen) {
|
||||||
|
static std::uniform_int_distribution<> dis(0, 255);
|
||||||
|
return cv::Scalar(dis(t_gen), dis(t_gen), dis(t_gen));
|
||||||
|
}
|
||||||
|
|
||||||
void newSquare1(cv::Mat &t_process_img, std::mt19937 &t_gen,
|
void newSquare1(cv::Mat &t_process_img, std::mt19937 &t_gen,
|
||||||
randint &t_rand_pos) {
|
randint &t_rand_pos) {
|
||||||
const int square_size = t_rand_pos(t_gen);
|
const int square_size = t_rand_pos(t_gen);
|
||||||
auto square_top_left = cv::Point{t_rand_pos(t_gen), t_rand_pos(t_gen)};
|
auto square_top_left = cv::Point{t_rand_pos(t_gen), t_rand_pos(t_gen)};
|
||||||
draw_shape(t_process_img, square_top_left, square_size, random_color(t_gen),
|
draw_shape(t_process_img, square_top_left, square_size, randomColor(t_gen),
|
||||||
Shapes::Square);
|
Shapes::Square);
|
||||||
}
|
}
|
||||||
|
|
||||||
void method1(cv::Mat &t_reference, cv::Mat &t_output, int t_iterations,
|
|
||||||
std::mt19937 &t_gen) {
|
|
||||||
auto diff = euclidian_distance(t_reference, t_output);
|
|
||||||
auto const max_size =
|
|
||||||
std::max(t_reference.size().width, t_reference.size().height);
|
|
||||||
randint dist(0, max_size);
|
|
||||||
spdlog::info("Beginning method1, initial difference: {}", diff);
|
|
||||||
while (t_iterations > 0) {
|
|
||||||
auto temp_image = t_output.clone();
|
|
||||||
newSquare1(temp_image, t_gen, dist);
|
|
||||||
if (auto new_diff = euclidian_distance(t_reference, temp_image);
|
|
||||||
new_diff < diff) {
|
|
||||||
diff = new_diff;
|
|
||||||
temp_image.copyTo(t_output);
|
|
||||||
--t_iterations;
|
|
||||||
spdlog::info("Iteration {}: diff {}", t_iterations, diff);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void threadedGetColor(cv::Mat &t_reference, ColorSet &t_colors, int t_h) {
|
void threadedGetColor(cv::Mat &t_reference, ColorSet &t_colors, int t_h) {
|
||||||
if (t_h > t_reference.size().height)
|
if (t_h > t_reference.size().height)
|
||||||
return;
|
return;
|
||||||
@ -62,8 +49,9 @@ ColorSet getColorSet(cv::Mat &t_reference) {
|
|||||||
for (int h = 0; h < t_reference.size().height; h += thread_nbr) {
|
for (int h = 0; h < t_reference.size().height; h += thread_nbr) {
|
||||||
std::vector<std::thread> thread_list{};
|
std::vector<std::thread> thread_list{};
|
||||||
for (int i = 0; i < thread_nbr; ++i) {
|
for (int i = 0; i < thread_nbr; ++i) {
|
||||||
thread_list.push_back(std::thread(threadedGetColor, std::ref(t_reference),
|
thread_list.push_back(std::thread(methods_private::threadedGetColor,
|
||||||
std::ref(res), h + i));
|
std::ref(t_reference), std::ref(res),
|
||||||
|
h + i));
|
||||||
}
|
}
|
||||||
for (auto &th : thread_list)
|
for (auto &th : thread_list)
|
||||||
th.join();
|
th.join();
|
||||||
@ -85,26 +73,48 @@ void newSquare2(cv::Mat &t_process_img, std::mt19937 &t_gen,
|
|||||||
Shapes::Square);
|
Shapes::Square);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} // namespace methods_private
|
||||||
|
|
||||||
|
void method1(cv::Mat &t_reference, cv::Mat &t_output, int t_iterations,
|
||||||
|
std::mt19937 &t_gen) {
|
||||||
|
auto diff = euclidian_distance(t_reference, t_output);
|
||||||
|
auto const max_size =
|
||||||
|
std::max(t_reference.size().width, t_reference.size().height);
|
||||||
|
randint dist(0, max_size);
|
||||||
|
spdlog::debug("Beginning method1, initial difference: {}", diff);
|
||||||
|
while (t_iterations > 0) {
|
||||||
|
auto temp_image = t_output.clone();
|
||||||
|
methods_private::newSquare1(temp_image, t_gen, dist);
|
||||||
|
if (auto new_diff = euclidian_distance(t_reference, temp_image);
|
||||||
|
new_diff < diff) {
|
||||||
|
diff = new_diff;
|
||||||
|
temp_image.copyTo(t_output);
|
||||||
|
--t_iterations;
|
||||||
|
spdlog::debug("Iteration {}: diff {}", t_iterations, diff);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void method2(cv::Mat &t_reference, cv::Mat &t_output, int t_iterations,
|
void method2(cv::Mat &t_reference, cv::Mat &t_output, int t_iterations,
|
||||||
std::mt19937 &t_gen) {
|
std::mt19937 &t_gen) {
|
||||||
auto diff = euclidian_distance(t_reference, t_output);
|
auto diff = euclidian_distance(t_reference, t_output);
|
||||||
auto const max_size =
|
auto const max_size =
|
||||||
std::max(t_reference.size().width, t_reference.size().height);
|
std::max(t_reference.size().width, t_reference.size().height);
|
||||||
randint dist(0, max_size);
|
randint dist(0, max_size);
|
||||||
spdlog::info("Beginning method2, initial difference: {}", diff);
|
spdlog::debug("Beginning method2, initial difference: {}", diff);
|
||||||
auto const colors = getColorSet(t_reference);
|
auto const colors = methods_private::getColorSet(t_reference);
|
||||||
spdlog::info("Running {} threads.", thread_nbr);
|
spdlog::debug("Running {} threads.", thread_nbr);
|
||||||
spdlog::info("{} colors detected.", colors.size());
|
spdlog::debug("{} colors detected.", colors.size());
|
||||||
randint rand_color(0, colors.size());
|
randint rand_color(0, colors.size());
|
||||||
while (t_iterations > 0) {
|
while (t_iterations > 0) {
|
||||||
auto temp_image = t_output.clone();
|
auto temp_image = t_output.clone();
|
||||||
newSquare2(temp_image, t_gen, colors, dist, rand_color);
|
methods_private::newSquare2(temp_image, t_gen, colors, dist, rand_color);
|
||||||
if (auto new_diff = euclidian_distance(t_reference, temp_image);
|
if (auto new_diff = euclidian_distance(t_reference, temp_image);
|
||||||
new_diff < diff) {
|
new_diff < diff) {
|
||||||
diff = new_diff;
|
diff = new_diff;
|
||||||
temp_image.copyTo(t_output);
|
temp_image.copyTo(t_output);
|
||||||
--t_iterations;
|
--t_iterations;
|
||||||
spdlog::info("Iteration {}: diff {}", t_iterations, diff);
|
spdlog::debug("Iteration {}: diff {}", t_iterations, diff);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -21,7 +21,7 @@ void processFilenames(po::variables_map const &vm, path const &t_input,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::tuple<path, path, bool, int, int> parse_args(int t_ac, char **t_av) {
|
std::tuple<path, path, bool, int, int, bool> parse_args(int t_ac, char **t_av) {
|
||||||
po::options_description desc("Allowed options");
|
po::options_description desc("Allowed options");
|
||||||
desc.add_options()
|
desc.add_options()
|
||||||
("help,h", "Display this help message")
|
("help,h", "Display this help message")
|
||||||
@ -30,7 +30,8 @@ std::tuple<path, path, bool, int, int> parse_args(int t_ac, char **t_av) {
|
|||||||
"Image or video output path (default: input path + \"_output\")")
|
"Image or video output path (default: input path + \"_output\")")
|
||||||
("method,m", po::value<int>(), "Method number to be used (default: 1)")
|
("method,m", po::value<int>(), "Method number to be used (default: 1)")
|
||||||
("iterations,n", po::value<int>(), "Number of iterations (default: 5000)")
|
("iterations,n", po::value<int>(), "Number of iterations (default: 5000)")
|
||||||
("video,v", "Enable video output");
|
("video,V", "Enable video output")
|
||||||
|
("verbose,v", "Enables verbosity");
|
||||||
po::variables_map vm;
|
po::variables_map vm;
|
||||||
po::store(po::parse_command_line(t_ac, t_av, desc), vm);
|
po::store(po::parse_command_line(t_ac, t_av, desc), vm);
|
||||||
po::notify(vm);
|
po::notify(vm);
|
||||||
@ -49,5 +50,6 @@ std::tuple<path, path, bool, int, int> parse_args(int t_ac, char **t_av) {
|
|||||||
output_path,
|
output_path,
|
||||||
vm.count("video") ? true : false,
|
vm.count("video") ? true : false,
|
||||||
vm.count("iterations") ? vm["iterations"].as<int>() : DEFAULT_ITERATIONS,
|
vm.count("iterations") ? vm["iterations"].as<int>() : DEFAULT_ITERATIONS,
|
||||||
vm.count("method") ? vm["method"].as<int>() : 1);
|
vm.count("method") ? vm["method"].as<int>() : 1,
|
||||||
|
vm.count("verbose") ? true : false);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user