Euclidian distance fixed, C random now

This commit is contained in:
Phuntsok Drak-pa 2019-03-25 12:24:19 +01:00
parent e1a7b127af
commit b2361e1974
5 changed files with 64 additions and 57 deletions

View File

@ -3,13 +3,10 @@
#include <opencv2/core/core.hpp> #include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp> #include <opencv2/highgui/highgui.hpp>
#include <random>
#include <spdlog/spdlog.h> #include <spdlog/spdlog.h>
void method1(cv::Mat &t_reference, cv::Mat &t_output, int t_iterations, 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, void method2(cv::Mat &t_reference, cv::Mat &t_output, int t_iterations);
std::mt19937 &t_gen);
#endif /* GENETIC_IMAGE_INCLUDE_GENIMG_METHODS_HH_ */ #endif /* GENETIC_IMAGE_INCLUDE_GENIMG_METHODS_HH_ */

View File

@ -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_distance(cv::Mat const &t_img1, cv::Mat const &t_img2) {
double euclidian = 0.0; double euclidian = 0.0;
for (int w = 0; w < t_img1.size().width; ++w) { for (auto itr1 = t_img1.begin<uchar>(), itr2 = t_img2.begin<uchar>();
for (int h = 0; h < t_img1.size().height; ++h) { itr1 != t_img1.end<uchar>() && itr2 != t_img2.end<uchar>();
euclidian += std::abs(std::pow(t_img1.at<uchar>(h, w), 2) - ++itr1, ++itr2) {
std::pow(t_img2.at<uchar>(h, w), 2)); euclidian += std::pow(*itr1 - *itr2, 2);
}
} }
euclidian = std::sqrt(euclidian); euclidian = std::sqrt(euclidian);
return euclidian; return euclidian;

View File

@ -5,12 +5,15 @@
#include <spdlog/spdlog.h> #include <spdlog/spdlog.h>
void drawSquare(cv::Mat &t_img, cv::Point const &t_top_left, int const t_size, void drawSquare(cv::Mat &t_img, cv::Point const &t_top_left, int const t_size,
cv::Scalar const &t_color) { cv::Scalar const &t_color) {
std::unique_ptr<cv::Point> points(new cv::Point[4]); auto points = std::make_unique<cv::Point[]>(4);
points.get()[0] = t_top_left; 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()[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}; 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); fillConvexPoly(t_img, points.get(), 4, t_color);
} }

View File

@ -2,8 +2,11 @@
#include "methods.hh" #include "methods.hh"
#include "parseargs.hh" #include "parseargs.hh"
#include <iostream> #include <iostream>
#include <cstdlib>
#include <ctime>
int main(int ac, char **av) { int main(int ac, char **av) {
std::srand(std::time(nullptr));
auto const [input_file, output_file, iterations, method, auto const [input_file, output_file, iterations, method,
verbose] = parse_args(ac, av); verbose] = parse_args(ac, av);
spdlog::set_level(verbose ? spdlog::level::debug : spdlog::level::info); 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("Output file:\t{}", output_file.native());
spdlog::debug("Iterations:\t{}", iterations); 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::mt19937 gen(rd());
switch (method) { switch (method) {
case 1: { case 1: {
method1(input_image, process_image, iterations, gen); method1(input_image, process_image, iterations);
break; break;
} }
case 2: { case 2: {
method2(input_image, process_image, iterations, gen); method2(input_image, process_image, iterations);
break; break;
} }
default: default:
@ -29,8 +30,5 @@ int main(int ac, char **av) {
} }
cv::imwrite(output_file.native(), process_image); cv::imwrite(output_file.native(), process_image);
// Launch image generation
return 0; return 0;
} }

View File

@ -3,6 +3,7 @@
#include "drawing.hh" #include "drawing.hh"
#include <algorithm> #include <algorithm>
#include <array> #include <array>
#include <cstdlib>
#include <thread> #include <thread>
#include <vector> #include <vector>
@ -12,20 +13,31 @@ std::mutex numbers_mutex;
using randint = std::uniform_int_distribution<>; 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>;
using std::rand;
namespace methods_private { 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) {
static std::uniform_int_distribution<> dis(0, 255); int const height = t_process_img.size().height;
return cv::Scalar(dis(t_gen), dis(t_gen), dis(t_gen)); 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, cv::Scalar randomColor() {
randint &t_rand_pos) { static std::uniform_int_distribution<> dis(0, 255);
const int square_size = t_rand_pos(t_gen); return cv::Scalar(rand() % 255, rand() % 255, rand() % 255);
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) { void threadedGetColor(cv::Mat &t_reference, ColorSet &t_colors, int t_h) {
@ -60,61 +72,59 @@ ColorSet getColorSet(cv::Mat &t_reference) {
return res; return res;
} }
void newSquare2(cv::Mat &t_process_img, std::mt19937 &t_gen, void newSquare2(cv::Mat &t_process_img, cv::Point &&t_top_left, int t_size,
ColorSet const &t_colors, randint &t_rand_pos, Color const &t_color) {
randint &t_rand_color) { draw_shape(t_process_img, t_top_left, t_size,
int const square_size = t_rand_pos(t_gen); cv::Scalar{static_cast<double>(t_color[0]),
auto square_top_left = cv::Point{t_rand_pos(t_gen), t_rand_pos(t_gen)}; static_cast<double>(t_color[1]),
const auto color = t_colors[t_rand_color(t_gen)]; static_cast<double>(t_color[2])},
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); Shapes::Square);
} }
} // namespace methods_private } // namespace methods_private
void method1(cv::Mat &t_reference, cv::Mat &t_output, int t_iterations, 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 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); spdlog::debug("Beginning method1, initial difference: {}", diff);
while (t_iterations > 0) { while (t_iterations > 0 && diff >= 0) {
auto temp_image = t_output.clone(); auto temp_image = t_output.clone();
methods_private::newSquare1(temp_image, t_gen, dist); int const rand_x = rand() % temp_image.size().width;
if (auto new_diff = euclidian_distance(t_reference, temp_image); 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) { new_diff < diff) {
diff = new_diff; diff = new_diff;
temp_image.copyTo(t_output); temp_image.copyTo(t_output);
--t_iterations; --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, 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 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); spdlog::debug("Beginning method2, initial difference: {}", diff);
auto const colors = methods_private::getColorSet(t_reference);
spdlog::debug("Running {} threads.", thread_nbr); spdlog::debug("Running {} threads.", thread_nbr);
auto const colors = methods_private::getColorSet(t_reference);
spdlog::debug("{} colors detected.", colors.size()); spdlog::debug("{} colors detected.", 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();
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); 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::debug("Iteration {}: diff {}", t_iterations, diff); spdlog::debug("iteration:{} diff:{}", t_iterations, diff);
} }
} }
} }