less duplicate code
This commit is contained in:
parent
15488ace23
commit
72b91ab1b1
@ -4,6 +4,33 @@
|
||||
#include <opencv2/core/core.hpp>
|
||||
#include <opencv2/highgui/highgui.hpp>
|
||||
#include <spdlog/spdlog.h>
|
||||
#include <tuple>
|
||||
#include <vector>
|
||||
|
||||
namespace methods_private {
|
||||
|
||||
[[nodiscard]] auto randomColor();
|
||||
[[nodiscard]] auto getColorSet(cv::Mat const& t_reference);
|
||||
[[nodiscard]] auto getSquareValues(cv::Mat const& t_img);
|
||||
[[nodiscard]] auto createCandidate(
|
||||
cv::Mat const& t_base,
|
||||
cv::Mat const& t_ref,
|
||||
std::vector<std::array<uchar, 3>> const& t_colors,
|
||||
double const diff,
|
||||
bool const t_controlled_size);
|
||||
void adjustSize(cv::Mat const& t_process_img,
|
||||
cv::Point& t_top_left,
|
||||
int t_size);
|
||||
void threadedGetColor(cv::Mat const& t_reference,
|
||||
std::vector<std::array<uchar, 3>>& t_colors,
|
||||
int t_h);
|
||||
void newSquare1(cv::Mat& t_process_img, cv::Point&& t_top_left, int t_size);
|
||||
void newSquare2(cv::Mat& t_process_img,
|
||||
cv::Point&& t_top_left,
|
||||
int t_size,
|
||||
std::array<uchar, 3> const& t_color);
|
||||
|
||||
} // namespace methods_private
|
||||
|
||||
void method1(cv::Mat const&, cv::Mat&, int);
|
||||
|
||||
|
109
src/methods.cc
109
src/methods.cc
@ -4,7 +4,9 @@
|
||||
#include <algorithm>
|
||||
#include <array>
|
||||
#include <cstdlib>
|
||||
#include <optional>
|
||||
#include <thread>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
auto const thread_nbr = std::thread::hardware_concurrency();
|
||||
@ -17,6 +19,57 @@ using std::rand;
|
||||
|
||||
namespace methods_private {
|
||||
|
||||
[[nodiscard]] auto randomColor()
|
||||
{
|
||||
static std::uniform_int_distribution<> dis(0, 255);
|
||||
return cv::Scalar(rand() % 255, rand() % 255, rand() % 255);
|
||||
}
|
||||
|
||||
[[nodiscard]] auto getColorSet(cv::Mat const& t_reference)
|
||||
{
|
||||
ColorSet res{};
|
||||
for (int h = 0; h < t_reference.size().height; h += thread_nbr) {
|
||||
std::vector<std::thread> thread_list{};
|
||||
for (auto i = 0u; i < thread_nbr; ++i) {
|
||||
thread_list.push_back(std::thread(methods_private::threadedGetColor,
|
||||
std::ref(t_reference), std::ref(res),
|
||||
h + i));
|
||||
}
|
||||
for (auto& th : thread_list)
|
||||
th.join();
|
||||
}
|
||||
res.shrink_to_fit();
|
||||
return res;
|
||||
}
|
||||
|
||||
[[nodiscard]] auto getSquareValues(cv::Mat const& t_img)
|
||||
{
|
||||
int rand_x = rand() % t_img.size().width;
|
||||
int rand_y = rand() % t_img.size().height;
|
||||
int size
|
||||
= rand()
|
||||
% std::min(t_img.size().width - rand_x, t_img.size().height - rand_y);
|
||||
return std::tuple<int, int, int>(rand_x, rand_y, size);
|
||||
}
|
||||
|
||||
[[nodiscard]] auto createCandidate(cv::Mat const& t_base,
|
||||
cv::Mat const& t_ref,
|
||||
ColorSet const& t_colors,
|
||||
double const diff,
|
||||
bool const t_controlled_size)
|
||||
{
|
||||
auto temp_image = t_base.clone();
|
||||
auto const [rand_x, rand_y, size]
|
||||
= methods_private::getSquareValues(temp_image);
|
||||
methods_private::newSquare2(temp_image, cv::Point{rand_x, rand_y}, size,
|
||||
t_colors[rand() % t_colors.size()]);
|
||||
auto new_diff = euclidian_distance(t_ref, temp_image);
|
||||
return (new_diff < diff)
|
||||
? std::optional<std::pair<cv::Mat, double>>{std::make_pair(
|
||||
std::move(temp_image), new_diff)}
|
||||
: std::nullopt;
|
||||
}
|
||||
|
||||
void adjustSize(cv::Mat const& t_process_img, cv::Point& t_top_left, int size)
|
||||
{
|
||||
int const height = t_process_img.size().height;
|
||||
@ -31,18 +84,6 @@ void adjustSize(cv::Mat const& t_process_img, cv::Point& t_top_left, int size)
|
||||
}
|
||||
}
|
||||
|
||||
[[nodiscard]] auto randomColor() -> cv::Scalar
|
||||
{
|
||||
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 const& t_reference, ColorSet& t_colors, int t_h)
|
||||
{
|
||||
if (t_h > t_reference.size().height)
|
||||
@ -60,21 +101,10 @@ void threadedGetColor(cv::Mat const& t_reference, ColorSet& t_colors, int t_h)
|
||||
}
|
||||
}
|
||||
|
||||
[[nodiscard]] auto getColorSet(cv::Mat const& t_reference) -> ColorSet
|
||||
void newSquare1(cv::Mat& t_process_img, cv::Point&& t_top_left, int t_size)
|
||||
{
|
||||
ColorSet res{};
|
||||
for (int h = 0; h < t_reference.size().height; h += thread_nbr) {
|
||||
std::vector<std::thread> thread_list{};
|
||||
for (auto i = 0u; i < thread_nbr; ++i) {
|
||||
thread_list.push_back(std::thread(methods_private::threadedGetColor,
|
||||
std::ref(t_reference), std::ref(res),
|
||||
h + i));
|
||||
}
|
||||
for (auto& th : thread_list)
|
||||
th.join();
|
||||
}
|
||||
res.shrink_to_fit();
|
||||
return res;
|
||||
adjustSize(t_process_img, t_top_left, t_size);
|
||||
draw_shape(t_process_img, t_top_left, t_size, randomColor(), Shapes::Square);
|
||||
}
|
||||
|
||||
void newSquare2(cv::Mat& t_process_img,
|
||||
@ -97,11 +127,8 @@ void method1(cv::Mat const& t_reference, cv::Mat& t_output, int t_iterations)
|
||||
spdlog::debug("Beginning method1, initial difference: {}", diff);
|
||||
while (t_iterations > 0 && diff >= 0) {
|
||||
auto temp_image = t_output.clone();
|
||||
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);
|
||||
auto const [rand_x, rand_y, size]
|
||||
= methods_private::getSquareValues(temp_image);
|
||||
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) {
|
||||
@ -115,25 +142,17 @@ void method1(cv::Mat const& t_reference, cv::Mat& t_output, int t_iterations)
|
||||
|
||||
void method2(cv::Mat const& t_reference, cv::Mat& t_output, int t_iterations)
|
||||
{
|
||||
spdlog::debug("Running on {} thread(s).", thread_nbr);
|
||||
auto diff = euclidian_distance(t_reference, t_output);
|
||||
spdlog::debug("Beginning method2, initial difference: {}", diff);
|
||||
spdlog::debug("Running {} threads.", thread_nbr);
|
||||
auto const colors = methods_private::getColorSet(t_reference);
|
||||
spdlog::debug("{} colors detected.", colors.size());
|
||||
|
||||
while (t_iterations > 0) {
|
||||
auto temp_image = t_output.clone();
|
||||
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);
|
||||
if (auto result = methods_private::createCandidate(t_output, t_reference,
|
||||
colors, diff, false);
|
||||
result.has_value()) {
|
||||
diff = result->second;
|
||||
result->first.copyTo(t_output);
|
||||
--t_iterations;
|
||||
spdlog::debug("iteration:{} diff:{}", t_iterations, diff);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user