#pragma once #include #include #include #include #include #include class ImageManipulator { public: ImageManipulator() = delete; /// \brief Copy contructor ImageManipulator(const ImageManipulator& other); /// \brief Move constructor ImageManipulator(ImageManipulator&& other) noexcept; /// \brief Load image from input, and prepare for output ImageManipulator(std::string const t_input_path, std::string const t_output_path, int const iterations); /// \brief Basically makes views from image 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); /** * \brief Copy assignment operator * * Copy assignment operator, will copy all of the input’s members except for * its mutex, a new one will be generated. * * \param[in] other Element to copy * \return ImageManipulator */ [[nodiscard]] inline auto operator=(const ImageManipulator& other) -> ImageManipulator { return ImageManipulator(other); } /** * \brief Move assignment operator * * Move assignment operator, will move all of the input’s members except for * its mutex, a new one will be generated. * * \param[in] other Element to move * \return ImageManipulator */ [[nodiscard]] inline auto operator=(ImageManipulator&& other) noexcept -> ImageManipulator { return ImageManipulator{std::move(other)}; } /// \brief Execute the nth method on the current object void exec_method(int const t_nb_method, bool const t_controlled_size, int const t_cols, int const t_rows, int const t_submethod); /** * \brief Write the generated image to the output path * * Write the generated image as a file to the specified path stored in the * object */ inline void write_file() const { cv::imwrite(output_path_, generated_image_); } /// \brief Returns a reference to the generated image [[nodiscard]] inline auto const& get_generated_image() const noexcept { return generated_image_; } /// \brief Destructor virtual ~ImageManipulator() noexcept = default; protected: private: // methods ////////////////////////////////////////////////////////////////// /// \brief Calculates the euclidian distance between two images [[nodiscard]] auto euclidian_distance(cv::Mat const& t_img) const noexcept -> double; /// \brief Creates and returns a random color [[nodiscard]] auto random_color() const noexcept; /// \brief Generates random square coordinates [[nodiscard]] auto get_square_values() const noexcept; /// \brief Generates controlled random square coordinates [[nodiscard]] auto get_controlled_square_values() const noexcept; /// \brief Generates a candidate for image generation improvement [[nodiscard]] auto create_candidate(bool const t_controlled_size) const; /// \brief Generates organized views of the reference image for method 5 [[nodiscard]] auto generate_tiles(int const t_cols, int const t_rows) const; /// \brief Gets all colors from the reference image void get_color_set(); /// \brief Threaded helper for \ref get_color_set void threaded_get_color(int const t_h); /// \brief Draw a square on an image void draw_square(cv::Mat& t_img, cv::Point const& t_top_left, int const t_size, cv::Scalar const& t_color) const; /// \brief Update this object’s generated image void update_gen_image(cv::Mat const& t_img, double const t_diff); /// \brief Merges tiles generated by method5 void merge_tiles(std::vector> const& t_tiles); /// \brief First method as described in the /// [report](https://labs.phundrak.fr/phundrak/genetic-images/blob/master/report/report.pdf) void method1(); /// \brief Second method as described in the /// [report](https://labs.phundrak.fr/phundrak/genetic-images/blob/master/report/report.pdf) void method2(); /// \brief Third method as described in the /// [report](https://labs.phundrak.fr/phundrak/genetic-images/blob/master/report/report.pdf) void method3(); /// \brief Fourth method as described in the /// [report](https://labs.phundrak.fr/phundrak/genetic-images/blob/master/report/report.pdf) void method4(bool const t_controlled_size); /// \brief Fifth method as described in the /// [report](https://labs.phundrak.fr/phundrak/genetic-images/blob/master/report/report.pdf) void method5(bool const t_controlled_size, int const cols, int const rows, int const submethod); // members ////////////////////////////////////////////////////////////////// std::vector> colors_{}; /*!< Color set from reference */ cv::Mat const reference_{}; /*!< Reference image */ cv::Mat generated_image_{ reference_.size().height, reference_.size().width, CV_8UC3, cv::Scalar(0, 0, 0)}; /*!< Working, generated image */ mutable std::mutex colors_mutex_{}; /*!< Thread mutex for color set generation */ std::string const output_path_{""}; /*!< Write path for the generated image */ double diff_{euclidian_distance(generated_image_)}; /*!< Euclidian difference between \ref reference_ and \ref generated_image_ */ int const total_iterations_{0}; /*!< Number of iterations to perform */ int remaining_iter_{ total_iterations_}; /*!< Remaining iterations to perform */ int const width_{reference_.size().width}; /*!< Width of the image */ int const height_{reference_.size().height}; /*!< Height of the image */ };