added method 2

This commit is contained in:
Phuntsok Drak-pa 2019-03-21 02:49:00 +01:00
parent bad4cc702c
commit 13e59c2dc4
4 changed files with 89 additions and 4 deletions

View File

@ -16,6 +16,7 @@ conan_basic_setup()
enable_cxx_compiler_flag_if_supported("-Wall")
enable_cxx_compiler_flag_if_supported("-pedantic")
enable_cxx_compiler_flag_if_supported("-O3")
# include_directories(<PUBLIC HEADER DIRECTORIES>)
set(TGT genetic-image)

View File

@ -9,4 +9,7 @@
void method1(cv::Mat &t_reference, cv::Mat &t_output, int t_iterations,
std::mt19937 &t_gen);
void method2(cv::Mat &t_reference, cv::Mat &t_output, int t_iterations,
std::mt19937 &t_gen);
#endif /* GENETIC_IMAGE_INCLUDE_GENIMG_METHOD1_METHOD1_HH_ */

View File

@ -18,6 +18,10 @@ int main(int ac, char **av) {
method1(input_image, process_image, iterations, gen);
break;
}
case 2: {
method2(input_image, process_image, iterations, gen);
break;
}
default:
spdlog::error("Requested method {} is not implemented.");
std::exit(-1);

View File

@ -2,12 +2,21 @@
#include "common.hh"
#include "drawing.hh"
#include <algorithm>
#include <array>
#include <thread>
#include <vector>
const auto thread_nbr = std::thread::hardware_concurrency();
std::mutex numbers_mutex;
using randint = std::uniform_int_distribution<>;
using Color = std::array<uchar, 3>;
using ColorSet = std::vector<Color>;
void newSquare(cv::Mat &t_process_img, std::mt19937 &t_gen, randint &t_dist) {
const int square_size = t_dist(t_gen);
auto square_top_left = cv::Point{t_dist(t_gen), t_dist(t_gen)};
void newSquare1(cv::Mat &t_process_img, std::mt19937 &t_gen,
randint &t_rand_pos) {
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)};
draw_shape(t_process_img, square_top_left, square_size, random_color(t_gen),
Shapes::Square);
}
@ -21,7 +30,75 @@ void method1(cv::Mat &t_reference, cv::Mat &t_output, int t_iterations,
spdlog::info("Beginning method1, initial difference: {}", diff);
while (t_iterations > 0) {
auto temp_image = t_output.clone();
newSquare(temp_image, t_gen, dist);
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) {
if (t_h > t_reference.size().height)
return;
for (int w = 0; w < t_reference.size().width; w += 3) {
Color temp = {t_reference.at<uchar>(t_h, w),
t_reference.at<uchar>(t_h, w + 1),
t_reference.at<uchar>(t_h, w + 2)};
auto pos = std::find(std::begin(t_colors), std::end(t_colors), temp);
if (pos == std::end(t_colors)) {
numbers_mutex.lock();
t_colors.push_back(temp);
numbers_mutex.unlock();
}
}
}
ColorSet getColorSet(cv::Mat &t_reference) {
ColorSet res{};
for (int h = 0; h < t_reference.size().height; h += thread_nbr) {
std::vector<std::thread> thread_list{};
for (int i = 0; i < thread_nbr; ++i) {
thread_list.push_back(std::thread(threadedGetColor, std::ref(t_reference),
std::ref(res), h + i));
}
for (auto &th : thread_list)
th.join();
}
res.shrink_to_fit();
return res;
}
void newSquare2(cv::Mat &t_process_img, std::mt19937 &t_gen,
ColorSet const &t_colors, randint &t_rand_pos,
randint &t_rand_color) {
int const square_size = t_rand_pos(t_gen);
auto square_top_left = cv::Point{t_rand_pos(t_gen), t_rand_pos(t_gen)};
const auto color = t_colors[t_rand_color(t_gen)];
draw_shape(t_process_img, square_top_left, square_size,
cv::Scalar{static_cast<double>(color[0]),
static_cast<double>(color[1]),
static_cast<double>(color[2])},
Shapes::Square);
}
void method2(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 method2, initial difference: {}", diff);
auto const colors = getColorSet(t_reference);
spdlog::info("Running {} threads.", thread_nbr);
spdlog::info("{} colors detected.", colors.size());
randint rand_color(0, colors.size());
while (t_iterations > 0) {
auto temp_image = t_output.clone();
newSquare2(temp_image, t_gen, colors, dist, rand_color);
if (auto new_diff = euclidian_distance(t_reference, temp_image);
new_diff < diff) {
diff = new_diff;