spacepaste

  1.  
  2. #include <cmath>
  3. #include <cstdint>
  4. #include <cstdio>
  5. #include <functional>
  6. #include <memory>
  7. #include <random>
  8. #include <CImg.h>
  9. using cimg_library::CImg;
  10. using cimg_library::CImgDisplay;
  11. struct Rectangle {
  12. int x, y, w, h;
  13. };
  14. static double distance(const CImg<std::uint8_t> &original, const CImg<std::uint8_t> &img,
  15. Rectangle bounds)
  16. {
  17. int sum = 0;
  18. for (int c = 0; c < 3; ++c) {
  19. for (int y = 0; y < bounds.h; ++y) {
  20. for (int x = 0; x < bounds.w; ++x) {
  21. std::uint8_t orig_val = original(x + bounds.x, y + bounds.y, 0, c);
  22. std::uint8_t img_val = img(x + bounds.x, y + bounds.y, 0, c);
  23. std::int16_t diff = img_val - orig_val;
  24. sum += diff * diff;
  25. }
  26. }
  27. }
  28. return std::sqrt(sum) / bounds.w * bounds.h;
  29. }
  30. static double distance(const CImg<std::uint8_t> &original, std::uint8_t *colour,
  31. Rectangle bounds)
  32. {
  33. int sum = 0;
  34. for (int c = 0; c < 3; ++c) {
  35. for (int y = 0; y < bounds.h; ++y) {
  36. for (int x = 0; x < bounds.w; ++x) {
  37. std::uint8_t orig_val = original(x + bounds.x, y + bounds.y, 0, c);
  38. std::uint8_t img_val = colour[c];
  39. std::int16_t diff = img_val - orig_val;
  40. sum += diff * diff;
  41. }
  42. }
  43. }
  44. return std::sqrt(sum) / bounds.w * bounds.h;
  45. }
  46. int main()
  47. {
  48. std::random_device rd;
  49. std::mt19937 x_gen(rd());
  50. std::mt19937 y_gen(rd());
  51. std::mt19937 dim_gen(rd());
  52. CImg<std::uint8_t> original("test.png");
  53. CImg<std::uint8_t> img(original.width(), original.height(), 1, 3, 255);
  54. std::uniform_int_distribution<int> x_distribution(0, original.width() - 16);
  55. std::uniform_int_distribution<int> y_distribution(0, original.height() - 16);
  56. std::uniform_int_distribution<int> dim_distribution(5, 15);
  57. auto x_rand = std::bind(x_distribution, x_gen);
  58. auto y_rand = std::bind(y_distribution, y_gen);
  59. auto dim_rand = std::bind(dim_distribution, dim_gen);
  60. std::uint8_t colour[3];
  61. CImgDisplay disp(img, "randompic");
  62. unsigned long long iterations = 0;
  63. while (!disp.is_closed()) {
  64. for (int i = 0; i < 100000; ++i) {
  65. iterations++;
  66. Rectangle rect {x_rand(), y_rand(), dim_rand(), dim_rand()};
  67. colour[0] = original(x_rand(), y_rand(), 0, 0);
  68. colour[1] = original(x_rand(), y_rand(), 0, 1);
  69. colour[2] = original(x_rand(), y_rand(), 0, 2);
  70. if (distance(original, img, rect) > distance(original, colour, rect)) {
  71. img.draw_rectangle(rect.x, rect.y, rect.x + rect.w - 1, rect.y + rect.h - 1, colour);
  72. }
  73. }
  74. disp.display(img);
  75. std::printf("%llu\n", iterations);
  76. }
  77. return 0;
  78. }
  79.