From b2361e1974ef8affea4e80ce21d14176ca438ff6 Mon Sep 17 00:00:00 2001 From: Phuntsok Drak-pa Date: Mon, 25 Mar 2019 12:24:19 +0100 Subject: [PATCH] Euclidian distance fixed, C random now --- include/genimg/methods.hh | 7 +--- src/common.cc | 9 ++--- src/drawing.cc | 9 +++-- src/main.cc | 12 +++--- src/methods.cc | 84 ++++++++++++++++++++++----------------- 5 files changed, 64 insertions(+), 57 deletions(-) diff --git a/include/genimg/methods.hh b/include/genimg/methods.hh index d58cf80..f25da5d 100644 --- a/include/genimg/methods.hh +++ b/include/genimg/methods.hh @@ -3,13 +3,10 @@ #include #include -#include #include -void method1(cv::Mat &t_reference, cv::Mat &t_output, int t_iterations, - std::mt19937 &t_gen); +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, - std::mt19937 &t_gen); +void method2(cv::Mat &t_reference, cv::Mat &t_output, int t_iterations); #endif /* GENETIC_IMAGE_INCLUDE_GENIMG_METHODS_HH_ */ diff --git a/src/common.cc b/src/common.cc index 62735ee..1e08b53 100644 --- a/src/common.cc +++ b/src/common.cc @@ -19,11 +19,10 @@ std::pair init_image(std::string const &t_input_file) { double euclidian_distance(cv::Mat const &t_img1, cv::Mat const &t_img2) { double euclidian = 0.0; - for (int w = 0; w < t_img1.size().width; ++w) { - for (int h = 0; h < t_img1.size().height; ++h) { - euclidian += std::abs(std::pow(t_img1.at(h, w), 2) - - std::pow(t_img2.at(h, w), 2)); - } + for (auto itr1 = t_img1.begin(), itr2 = t_img2.begin(); + itr1 != t_img1.end() && itr2 != t_img2.end(); + ++itr1, ++itr2) { + euclidian += std::pow(*itr1 - *itr2, 2); } euclidian = std::sqrt(euclidian); return euclidian; diff --git a/src/drawing.cc b/src/drawing.cc index 8f85ded..0cd8e90 100644 --- a/src/drawing.cc +++ b/src/drawing.cc @@ -5,12 +5,15 @@ #include void drawSquare(cv::Mat &t_img, cv::Point const &t_top_left, int const t_size, - cv::Scalar const &t_color) { - std::unique_ptr points(new cv::Point[4]); + cv::Scalar const &t_color) { + auto points = std::make_unique(4); points.get()[0] = t_top_left; - points.get()[1] = cv::Point{t_top_left.x, t_top_left.y + t_size}; + points.get()[1] = cv::Point{t_top_left.x, t_top_left.y + t_size}; points.get()[2] = cv::Point{t_top_left.x + t_size, t_top_left.y + t_size}; points.get()[3] = cv::Point{t_top_left.x + t_size, t_top_left.y}; + // spdlog::debug("Size:{} 1[{},{}] 2[{},{}] 3[{},{}] 4[{},{}]", t_size, + // points[0].x, points[0].y, points[1].x, points[1].y, points[2].x, + // points[2].y, points[3].x, points[3].y); fillConvexPoly(t_img, points.get(), 4, t_color); } diff --git a/src/main.cc b/src/main.cc index b6f72b2..bf9d6d0 100644 --- a/src/main.cc +++ b/src/main.cc @@ -2,8 +2,11 @@ #include "methods.hh" #include "parseargs.hh" #include +#include +#include int main(int ac, char **av) { + std::srand(std::time(nullptr)); auto const [input_file, output_file, iterations, method, verbose] = parse_args(ac, av); spdlog::set_level(verbose ? spdlog::level::debug : spdlog::level::info); @@ -11,16 +14,14 @@ int main(int ac, char **av) { spdlog::debug("Output file:\t{}", output_file.native()); spdlog::debug("Iterations:\t{}", iterations); auto [input_image, process_image] = init_image(input_file.native()); - std::random_device rd; - std::mt19937 gen(rd()); switch (method) { case 1: { - method1(input_image, process_image, iterations, gen); + method1(input_image, process_image, iterations); break; } case 2: { - method2(input_image, process_image, iterations, gen); + method2(input_image, process_image, iterations); break; } default: @@ -29,8 +30,5 @@ int main(int ac, char **av) { } cv::imwrite(output_file.native(), process_image); - - // Launch image generation - return 0; } diff --git a/src/methods.cc b/src/methods.cc index 2117648..f4f9672 100644 --- a/src/methods.cc +++ b/src/methods.cc @@ -3,6 +3,7 @@ #include "drawing.hh" #include #include +#include #include #include @@ -12,20 +13,31 @@ std::mutex numbers_mutex; using randint = std::uniform_int_distribution<>; using Color = std::array; using ColorSet = std::vector; +using std::rand; 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 adjustSize(cv::Mat const &t_process_img, cv::Point &t_top_left, int size) { + int const height = t_process_img.size().height; + int const width = t_process_img.size().width; + int const shape_total_width = t_top_left.x + size; + int const shape_total_height = t_top_left.y + size; + if (int const diff = shape_total_height - height; diff > 0) { + t_top_left.y -= diff + 1; + } + if (int const diff = shape_total_width - width; diff > 0) { + t_top_left.x -= diff + 1; + } } -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, randomColor(t_gen), - Shapes::Square); +cv::Scalar randomColor() { + static std::uniform_int_distribution<> dis(0, 255); + return cv::Scalar(rand() % 255, rand() % 255, rand() % 255); +} + +void newSquare1(cv::Mat &t_process_img, cv::Point &&t_top_left, int t_size) { + adjustSize(t_process_img, t_top_left, t_size); + draw_shape(t_process_img, t_top_left, t_size, randomColor(), Shapes::Square); } void threadedGetColor(cv::Mat &t_reference, ColorSet &t_colors, int t_h) { @@ -60,61 +72,59 @@ ColorSet getColorSet(cv::Mat &t_reference) { 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(color[0]), - static_cast(color[1]), - static_cast(color[2])}, +void newSquare2(cv::Mat &t_process_img, cv::Point &&t_top_left, int t_size, + Color const &t_color) { + draw_shape(t_process_img, t_top_left, t_size, + cv::Scalar{static_cast(t_color[0]), + static_cast(t_color[1]), + static_cast(t_color[2])}, Shapes::Square); } } // namespace methods_private -void method1(cv::Mat &t_reference, cv::Mat &t_output, int t_iterations, - std::mt19937 &t_gen) { +void method1(cv::Mat &t_reference, cv::Mat &t_output, int t_iterations) { 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) { + while (t_iterations > 0 && diff >= 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); + int const rand_x = rand() % temp_image.size().width; + int const rand_y = rand() % temp_image.size().height; + int const size = rand() % std::min(t_reference.size().width - rand_x, + t_reference.size().height - rand_y); + methods_private::newSquare1(temp_image, cv::Point{rand_x, rand_y}, size); + if (auto const 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); + spdlog::debug("iteration:{} diff:{}", t_iterations, diff); } } } -void method2(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) { 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 method2, initial difference: {}", diff); - auto const colors = methods_private::getColorSet(t_reference); + spdlog::debug("Running {} threads.", thread_nbr); + auto const colors = methods_private::getColorSet(t_reference); spdlog::debug("{} colors detected.", colors.size()); - randint rand_color(0, colors.size()); + while (t_iterations > 0) { auto temp_image = t_output.clone(); - methods_private::newSquare2(temp_image, t_gen, colors, dist, rand_color); + int const rand_x = rand() % temp_image.size().width; + int const rand_y = rand() % temp_image.size().height; + int const size = rand() % std::min(t_reference.size().width - rand_x, + t_reference.size().height - rand_y); + methods_private::newSquare2(temp_image, cv::Point{rand_x, rand_y}, size, + colors[rand() % colors.size()]); 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); + spdlog::debug("iteration:{} diff:{}", t_iterations, diff); } } }