Big code refactor, now the interface is easier to use

parent 4201e547
#ifndef GENETIC_IMAGE_INCLUDE_GENIMG_COMMON_HH_
#define GENETIC_IMAGE_INCLUDE_GENIMG_COMMON_HH_
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <spdlog/spdlog.h>
#include <string>
#include <utility>
[[nodiscard]] auto init_image(std::string const&) noexcept
-> std::pair<cv::Mat, cv::Mat>;
[[nodiscard]] auto euclidian_distance(cv::Mat const&, cv::Mat const&) -> double;
#endif /* GENETIC_IMAGE_INCLUDE_GENIMG_COMMON_HH_ */
#ifndef GENETIC_IMAGE_INCLUDE_GENIMG_DRAWING_HH_
#define GENETIC_IMAGE_INCLUDE_GENIMG_DRAWING_HH_
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
enum class Shapes { Square, Circle };
void draw_shape(cv::Mat&,
cv::Point const&,
int const,
cv::Scalar const&,
Shapes const&);
#endif /* GENETIC_IMAGE_INCLUDE_GENIMG_DRAWING_HH_ */
#ifndef GENETIC_IMAGE_INCLUDE_GENIMG_METHODS_HH_
#define GENETIC_IMAGE_INCLUDE_GENIMG_METHODS_HH_
#pragma once
#include <filesystem>
#include <opencv2/core/core.hpp>
#include <opencv2/highgui/highgui.hpp>
#include <opencv2/imgproc.hpp>
#include <spdlog/spdlog.h>
#include <string>
#include <thread>
#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 getControlledSquareValues(cv::Mat const& t_img,
int const t_init_iter,
int const t_iter);
[[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,
int const t_init_iter,
int const t_iter);
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 method2(cv::Mat const&, cv::Mat&, int);
void method3(cv::Mat const&, cv::Mat&, int);
void method4(cv::Mat const&, cv::Mat&, int, bool);
void method5(cv::Mat const&, cv::Mat&, int, int, bool);
#endif /* GENETIC_IMAGE_INCLUDE_GENIMG_METHODS_HH_ */
class ImageManipulator {
public:
ImageManipulator() = delete;
ImageManipulator(const ImageManipulator& other) = delete;
ImageManipulator(ImageManipulator&& other) noexcept = delete;
ImageManipulator& operator=(const ImageManipulator& other) = delete;
ImageManipulator& operator=(ImageManipulator&& other) noexcept = delete;
// Load image from input, and prepare for output
ImageManipulator(std::filesystem::path const t_input_path,
std::filesystem::path const t_output_path,
int const iterations);
// ImageManipulator(cv::Mat const& t_origin_image,
// int const iterations,
// int const t_x,
// int const t_y,
// int const t_width,
// int const t_height);
void exec_method(int const t_nb_method, bool const t_controlled_size);
void write_file() const;
//! Destructor
virtual ~ImageManipulator() noexcept = default;
protected:
private:
[[nodiscard]] auto euclidian_distance(cv::Mat const& t_img) const noexcept
-> double;
[[nodiscard]] auto random_color() const noexcept;
[[nodiscard]] auto get_square_values() const noexcept;
[[nodiscard]] auto get_controlled_square_values() const noexcept;
[[nodiscard]] auto create_candidate(bool const t_controlled_size) const;
void get_color_set();
void threaded_get_color(int t_h);
void adjust_size(cv::Point& t_top_left, int const size) noexcept;
void draw_square(cv::Mat& t_img,
cv::Point const& t_top_left,
int const t_size,
cv::Scalar const& t_color) const;
void update_gen_image(cv::Mat const& t_img, double const t_diff);
void method1();
void method2();
void method3();
void method4(bool const t_controlled_size);
std::vector<std::array<uchar, 3>> colors_
= std::vector<std::array<uchar, 3>>{};
cv::Mat const reference_;
cv::Mat generated_image_;
std::mutex colors_mutex_ = std::mutex{};
std::string const output_path_;
double diff_ = 0.0;
int const total_iterations_ = 0;
int remaining_iter_ = 0;
int const width_;
int const height_;
};
#include "common.hh"
#include <cassert>
#include <cmath>
#include <cstdlib>
[[nodiscard]] auto init_image(std::string const& t_input_file) noexcept
-> std::pair<cv::Mat, cv::Mat>
{
cv::Mat input_image = cv::imread(t_input_file, cv::IMREAD_COLOR);
if (!input_image.data) {
spdlog::critical("Could not open or find image!\n");
exit(-1);
}
spdlog::debug("Image loaded!");
spdlog::debug("Width:\t{}", input_image.size().width);
spdlog::debug("Height:\t{}", input_image.size().height);
cv::Mat process_image(input_image.size().height, input_image.size().width,
CV_8UC3, cv::Scalar(0, 0, 0));
return std::make_pair(std::move(input_image), process_image);
}
[[nodiscard]] auto euclidian_distance(cv::Mat const& t_img1,
cv::Mat const& t_img2) -> double
{
double euclidian = 0.0;
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;
}
#include "drawing.hh"
#include <cstdlib>
#include <memory>
#include <opencv2/imgproc.hpp>
#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)
{
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()[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};
fillConvexPoly(t_img, points.get(), 4, t_color);
}
void draw_shape(cv::Mat& t_img,
cv::Point const& t_top_left,
int const t_size,
cv::Scalar const& t_color,
Shapes const& t_shape)
{
switch (t_shape) {
case Shapes::Square: {
drawSquare(t_img, t_top_left, t_size, t_color);
break;
}
default:
spdlog::error("Shape does not exist. Aborting...");
std::exit(1);
}
}
#include "common.hh"
#include "methods.hh"
#include "parseargs.hh"
#include <cstdlib>
......@@ -9,37 +8,16 @@ int main(int ac, char** av)
{
std::srand(std::time(nullptr));
auto const [input_file, output_file, iterations, method, division,
controlled_size, verbose
] = parse_args(ac, av);
controlled_size, verbose]
= parse_args(ac, av);
spdlog::set_level(verbose ? spdlog::level::debug : spdlog::level::info);
spdlog::set_pattern("[thread %t] %+");
spdlog::debug("Input file:\t{}", input_file.native());
spdlog::debug("Output file:\t{}", output_file.native());
spdlog::debug("Iterations:\t{}", iterations);
auto [input_image, process_image] = init_image(input_file.native());
switch (method) {
case 1: {
method1(input_image, process_image, iterations);
break;
}
case 2: {
method2(input_image, process_image, iterations);
break;
}
case 3: {
method3(input_image, process_image, iterations);
break;
}
case 4: {
method4(input_image, process_image, iterations, controlled_size);
break;
}
default:
spdlog::error("Requested method {} is not implemented.", method);
std::exit(-1);
}
cv::imwrite(output_file.native(), process_image);
ImageManipulator image_process{input_file, output_file, iterations};
image_process.exec_method(method, controlled_size);
image_process.write_file();
return 0;
}
This diff is collapsed.
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