Euclidian distance fixed, C random now
This commit is contained in:
parent
e1a7b127af
commit
b2361e1974
@ -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);
|
||||
}
|
||||
|
||||
|
12
src/main.cc
12
src/main.cc
@ -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) {
|
||||
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<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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user