Advertisement
dan-masek

Untitled

Sep 12th, 2023
4,494
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 3.26 KB | None | 0 0
  1. #include <algorithm>
  2. #include <chrono>
  3. #include <functional>
  4. #include <iostream>
  5. #include <string>
  6. #include <tuple>
  7. #include <vector>
  8.  
  9. constexpr double one_third = 1.0 / 3.0;
  10. constexpr double two_third = 2.0 / 3.0;
  11. using std::tuple;
  12. using std::vector;
  13.  
  14.  
  15. struct image {
  16.     using data_type = double;
  17.  
  18.     image(size_t rows, size_t cols)
  19.         : rows(rows)
  20.         , cols(cols)
  21.     {
  22.         buffer.resize(rows * cols * channels);
  23.     }
  24.  
  25.     data_type* at(size_t row, size_t col)
  26.     {
  27.         return &buffer[row * cols * channels + col * channels];
  28.     }
  29.  
  30.     data_type const* at(size_t row, size_t col) const
  31.     {
  32.         return &buffer[row * cols * channels + col * channels];
  33.     }
  34.  
  35.     std::vector<data_type> buffer;
  36.     size_t rows;
  37.     size_t cols;
  38.     size_t channels{ 3 };
  39. };
  40.  
  41.  
  42. using std::chrono::steady_clock;
  43. using std::chrono::duration;
  44. using std::chrono::microseconds;
  45.  
  46.  
  47.  
  48. double wrap(double d)
  49. {
  50.     d = fmod(d, 1.0);
  51.     return d < 0 ? d + 1.0 : d;
  52. }
  53.  
  54. void fill(image& img, size_t row, size_t col)
  55. {
  56.     auto* p = img.at(row, col);
  57.     p[0] = double(rand()) / RAND_MAX;
  58.     p[1] = double(rand()) / RAND_MAX;
  59.     p[2] = double(rand()) / RAND_MAX;
  60. }
  61.  
  62. image random_image(size_t height, size_t width) {
  63.     image image(height, width);
  64.     for (size_t y = 0; y < height; y++) {
  65.         for (size_t x = 0; x < width; x++) {
  66.             fill(image, y, x);
  67.         }
  68.     }
  69.     return image;
  70. }
  71.  
  72. tuple<int, double, double> extrema(double a, double b, double c) {
  73.     int i = 2;
  74.     if (b > c) {
  75.         std::swap(b, c);
  76.         i = 1;
  77.     }
  78.     if (a > b) {
  79.         std::swap(a, b);
  80.     }
  81.     if (b > c) {
  82.         std::swap(b, c);
  83.         i = 0;
  84.     }
  85.     return { i, a, c };
  86. }
  87.  
  88. double hue(double b, double g, double r, double d, double i)
  89. {
  90.     if (i == 2) {
  91.         return wrap((g - b) / (6 * d));
  92.     }
  93.     if (i == 1) {
  94.         return wrap(one_third + (b - r) / (6 * d));
  95.     }
  96.     return wrap(two_third + (r - g) / (6 * d));
  97. }
  98.  
  99. void set_HSL_pixel(double* p, double b, double g, double r)
  100. {
  101.     auto const [i, x, z] = extrema(b, g, r);
  102.     double const s = x + z;
  103.     double const d = z - x;
  104.     double const avg = s / 2;
  105.     if (d != 0.0) {
  106.         p[0] = hue(b, g, r, d, i);
  107.         p[1] = d / (1 - abs(s - 1));
  108.         p[2] = avg;
  109.     } else {
  110.         p[0] = 0.0;
  111.         p[1] = 0.0;
  112.         p[2] = avg;
  113.     }
  114. }
  115.  
  116. image BGR_to_HSL(image const& img)
  117. {
  118.     image out(img.rows, img.cols);
  119.     for (size_t y = 0; y < img.rows; ++y) {
  120.         for (size_t x = 0; x < img.cols; ++x) {
  121.             double const* px = img.at(y, x);
  122.             set_HSL_pixel(out.at(y, x), px[0], px[1], px[2]);
  123.         }
  124.     }
  125.     return out;
  126. }
  127.  
  128.  
  129. double timeit(std::function<image(image const&)> func
  130.     , image img
  131.     , int runs = 256)
  132. {
  133.     auto const start = steady_clock::now();
  134.     for (int64_t i = 0; i < runs; i++) {
  135.         func(img);
  136.     }
  137.     auto const end = steady_clock::now();
  138.     duration<double, std::nano> time = end - start;
  139.     return time.count() / runs / 1000.0;
  140. }
  141.  
  142. int main()
  143. {
  144.     image img = random_image(1080, 1920);
  145.     double once = timeit(BGR_to_HSL, img, 16);
  146.     std::cout << "converting 1920x1080 BGR image to HSL vector: " + std::to_string(once) + " microseconds\n";
  147. }
  148.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement