less duplicate code
This commit is contained in:
parent
15488ace23
commit
72b91ab1b1
@ -4,6 +4,33 @@
|
|||||||
#include <opencv2/core/core.hpp>
|
#include <opencv2/core/core.hpp>
|
||||||
#include <opencv2/highgui/highgui.hpp>
|
#include <opencv2/highgui/highgui.hpp>
|
||||||
#include <spdlog/spdlog.h>
|
#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);
|
void method1(cv::Mat const&, cv::Mat&, int);
|
||||||
|
|
||||||
|
109
src/methods.cc
109
src/methods.cc
@ -4,7 +4,9 @@
|
|||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <array>
|
#include <array>
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
|
#include <optional>
|
||||||
#include <thread>
|
#include <thread>
|
||||||
|
#include <utility>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
auto const thread_nbr = std::thread::hardware_concurrency();
|
auto const thread_nbr = std::thread::hardware_concurrency();
|
||||||
@ -17,6 +19,57 @@ using std::rand;
|
|||||||
|
|
||||||
namespace methods_private {
|
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)
|
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 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)
|
void threadedGetColor(cv::Mat const& t_reference, ColorSet& t_colors, int t_h)
|
||||||
{
|
{
|
||||||
if (t_h > t_reference.size().height)
|
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{};
|
adjustSize(t_process_img, t_top_left, t_size);
|
||||||
for (int h = 0; h < t_reference.size().height; h += thread_nbr) {
|
draw_shape(t_process_img, t_top_left, t_size, randomColor(), Shapes::Square);
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void newSquare2(cv::Mat& t_process_img,
|
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);
|
spdlog::debug("Beginning method1, initial difference: {}", diff);
|
||||||
while (t_iterations > 0 && diff >= 0) {
|
while (t_iterations > 0 && diff >= 0) {
|
||||||
auto temp_image = t_output.clone();
|
auto temp_image = t_output.clone();
|
||||||
int const rand_x = rand() % temp_image.size().width;
|
auto const [rand_x, rand_y, size]
|
||||||
int const rand_y = rand() % temp_image.size().height;
|
= methods_private::getSquareValues(temp_image);
|
||||||
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);
|
methods_private::newSquare1(temp_image, cv::Point{rand_x, rand_y}, size);
|
||||||
if (auto const new_diff = euclidian_distance(t_reference, temp_image);
|
if (auto const new_diff = euclidian_distance(t_reference, temp_image);
|
||||||
new_diff < diff) {
|
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)
|
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);
|
auto diff = euclidian_distance(t_reference, t_output);
|
||||||
spdlog::debug("Beginning method2, initial difference: {}", diff);
|
spdlog::debug("Beginning method2, initial difference: {}", diff);
|
||||||
spdlog::debug("Running {} threads.", thread_nbr);
|
|
||||||
auto const colors = methods_private::getColorSet(t_reference);
|
auto const colors = methods_private::getColorSet(t_reference);
|
||||||
spdlog::debug("{} colors detected.", colors.size());
|
spdlog::debug("{} colors detected.", colors.size());
|
||||||
|
|
||||||
while (t_iterations > 0) {
|
while (t_iterations > 0) {
|
||||||
auto temp_image = t_output.clone();
|
if (auto result = methods_private::createCandidate(t_output, t_reference,
|
||||||
int const rand_x = rand() % temp_image.size().width;
|
colors, diff, false);
|
||||||
int const rand_y = rand() % temp_image.size().height;
|
result.has_value()) {
|
||||||
int const size = rand()
|
diff = result->second;
|
||||||
% std::min(t_reference.size().width - rand_x,
|
result->first.copyTo(t_output);
|
||||||
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;
|
--t_iterations;
|
||||||
spdlog::debug("iteration:{} diff:{}", t_iterations, diff);
|
spdlog::debug("iteration:{} diff:{}", t_iterations, diff);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user