Euclidian distance fixed, C random now

parent e1a7b127
......@@ -3,13 +3,10 @@
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <random>
#include <spdlog/spdlog.h>
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_ */
......@@ -19,11 +19,10 @@ std::pair<cv::Mat, cv::Mat> 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<uchar>(h, w), 2) -
std::pow(t_img2.at<uchar>(h, w), 2));
}
for (auto itr1 = t_img1.begin<uchar>(), itr2 = t_img2.begin<uchar>();
itr1 != t_img1.end<uchar>() && itr2 != t_img2.end<uchar>();
++itr1, ++itr2) {
euclidian += std::pow(*itr1 - *itr2, 2);
}
euclidian = std::sqrt(euclidian);
return euclidian;
......
......@@ -5,12 +5,15 @@
#include <spdlog/spdlog.h>
void drawSquare(cv::Mat &t_img, cv::Point const &t_top_left, int const t_size,
cv::Scalar const &t_color) {
std::unique_ptr<cv::Point> points(new cv::Point[4]);
cv::Scalar const &t_color) {
auto points = std::make_unique<cv::Point[]>(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);
}
......
......@@ -2,8 +2,11 @@
#include "methods.hh"
#include "parseargs.hh"
#include <iostream>
#include <cstdlib>
#include <ctime>
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;
}
......@@ -3,6 +3,7 @@
#include "drawing.hh"
#include <algorithm>
#include <array>
#include <cstdlib>
#include <thread>
#include <vector>
......@@ -12,20 +13,31 @@ std::mutex numbers_mutex;
using randint = std::uniform_int_distribution<>;
using Color = std::array<uchar, 3>;
using ColorSet = std::vector<Color>;
using std::rand;
namespace methods_private {
cv::Scalar randomColor(std::mt19937 &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;
}
}
cv::Scalar randomColor() {
static std::uniform_int_distribution<> dis(0, 255);
return cv::Scalar(dis(t_gen), dis(t_gen), dis(t_gen));
return cv::Scalar(rand() % 255, rand() % 255, rand() % 255);
}
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);
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<double>(color[0]),
static_cast<double>(color[1]),
static_cast<double>(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<double>(t_color[0]),
static_cast<double>(t_color[1]),
static_cast<double>(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);
}
}
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment