-
- #include <cmath>
- #include <cstdint>
- #include <cstdio>
- #include <functional>
- #include <memory>
- #include <random>
- #include <CImg.h>
-
- using cimg_library::CImg;
- using cimg_library::CImgDisplay;
-
- struct Rectangle {
- int x, y, w, h;
- };
-
- static double distance(const CImg<std::uint8_t> &original, const CImg<std::uint8_t> &img,
- Rectangle bounds)
- {
- int sum = 0;
-
- for (int c = 0; c < 3; ++c) {
- for (int y = 0; y < bounds.h; ++y) {
- for (int x = 0; x < bounds.w; ++x) {
- std::uint8_t orig_val = original(x + bounds.x, y + bounds.y, 0, c);
- std::uint8_t img_val = img(x + bounds.x, y + bounds.y, 0, c);
-
- std::int16_t diff = img_val - orig_val;
- sum += diff * diff;
- }
- }
- }
-
- return std::sqrt(sum) / bounds.w * bounds.h;
- }
-
- static double distance(const CImg<std::uint8_t> &original, std::uint8_t *colour,
- Rectangle bounds)
- {
- int sum = 0;
-
- for (int c = 0; c < 3; ++c) {
- for (int y = 0; y < bounds.h; ++y) {
- for (int x = 0; x < bounds.w; ++x) {
- std::uint8_t orig_val = original(x + bounds.x, y + bounds.y, 0, c);
- std::uint8_t img_val = colour[c];
-
- std::int16_t diff = img_val - orig_val;
- sum += diff * diff;
- }
- }
- }
-
- return std::sqrt(sum) / bounds.w * bounds.h;
- }
-
- int main()
- {
- std::random_device rd;
- std::mt19937 x_gen(rd());
- std::mt19937 y_gen(rd());
- std::mt19937 dim_gen(rd());
-
- CImg<std::uint8_t> original("test.png");
- CImg<std::uint8_t> img(original.width(), original.height(), 1, 3, 255);
-
- std::uniform_int_distribution<int> x_distribution(0, original.width() - 16);
- std::uniform_int_distribution<int> y_distribution(0, original.height() - 16);
- std::uniform_int_distribution<int> dim_distribution(5, 15);
-
- auto x_rand = std::bind(x_distribution, x_gen);
- auto y_rand = std::bind(y_distribution, y_gen);
- auto dim_rand = std::bind(dim_distribution, dim_gen);
-
- std::uint8_t colour[3];
-
- CImgDisplay disp(img, "randompic");
-
- unsigned long long iterations = 0;
- while (!disp.is_closed()) {
- for (int i = 0; i < 100000; ++i) {
- iterations++;
- Rectangle rect {x_rand(), y_rand(), dim_rand(), dim_rand()};
- colour[0] = original(x_rand(), y_rand(), 0, 0);
- colour[1] = original(x_rand(), y_rand(), 0, 1);
- colour[2] = original(x_rand(), y_rand(), 0, 2);
-
- if (distance(original, img, rect) > distance(original, colour, rect)) {
- img.draw_rectangle(rect.x, rect.y, rect.x + rect.w - 1, rect.y + rect.h - 1, colour);
- }
- }
- disp.display(img);
- std::printf("%llu\n", iterations);
- }
-
- return 0;
- }
-