Loading

median_linear and median_

  1. Image median_linear(Image src_image, int radius) {
  2.     // for convinience, let's make it the same size and crop at the end
  3.     Image res(src_image.n_rows, src_image.n_cols);
  4.     unsigned long long r[256], g[256], b[256];
  5.     unsigned long long total = radius * 2 + 1;
  6.     total *= total;
  7.     for (uint row = radius; row + radius < src_image.n_rows; row++) {
  8.         // rebuild the matrix
  9.         for (uint i = 0; i < 256; i++) {
  10.             r[i] = g[i] = b[i] = 0;
  11.         }
  12.         for (uint row2 = row - radius; row2 < row + radius + 1; row2++) {
  13.             for (uint col2 = 0; int(col2) < radius * 2 + 1; col2++) {
  14.                 auto pixel = src_image(row2, col2);
  15.                 r[get<0>(pixel)]++;
  16.                 g[get<1>(pixel)]++;
  17.                 b[get<2>(pixel)]++;
  18.             }
  19.         }
  20.         res(row, radius) = make_tuple(
  21.             median_helper(r, total),
  22.             median_helper(g, total),
  23.             median_helper(b, total)
  24.         );
  25.         for (uint col = radius + 1; col + radius < src_image.n_cols; col++) {
  26.             for (uint row2 = row - radius; row2 < row + radius + 1; row2++) {
  27.                 auto pixel = src_image(row2, col - radius - 1);
  28.                 r[get<0>(pixel)]--;
  29.                 g[get<1>(pixel)]--;
  30.                 b[get<2>(pixel)]--;
  31.                 pixel = src_image(row2, col + radius);
  32.                 r[get<0>(pixel)]++;
  33.                 g[get<1>(pixel)]++;
  34.                 b[get<2>(pixel)]++;
  35.             }
  36.             res(row, col) = make_tuple(
  37.                 median_helper(r, total),
  38.                 median_helper(g, total),
  39.                 median_helper(b, total)
  40.             );
  41.         }
  42.     }
  43.     return res.submatrix(radius, radius,
  44.         src_image.n_rows - 2 * radius,
  45.         src_image.n_cols - 2 * radius
  46.     );
  47. }
  48.  
  49. Image median_const(Image src_image, int radius) {
  50.     // for convinience, let's make it the same size and crop at the end
  51.     Image res(src_image.n_rows, src_image.n_cols);
  52.     unsigned long long r[256], g[256], b[256];
  53.     unsigned long long total = radius * 2 + 1;
  54.     total *= total;
  55.     unsigned long long
  56.         r_c[src_image.n_cols][256],
  57.         g_c[src_image.n_cols][256],
  58.         b_c[src_image.n_cols][256];
  59.     for (uint i = 0; i < 256; i++) {
  60.         r[i] = g[i] = b[i] = 0;
  61.     }
  62.     for (uint col = 0; int(col) < radius * 2 + 1; col++) {
  63.         for (uint i = 0; i < 256; i++) {
  64.             r_c[col][i] = g_c[col][i] = b_c[col][i] = 0;
  65.         }
  66.         for (uint row = 0; int(row) < radius * 2 + 1; row++) {
  67.             auto pixel = src_image(row, col);
  68.             r[get<0>(pixel)]++;
  69.             g[get<1>(pixel)]++;
  70.             b[get<2>(pixel)]++;
  71.             r_c[col][get<0>(pixel)]++;
  72.             g_c[col][get<1>(pixel)]++;
  73.             b_c[col][get<2>(pixel)]++;
  74.         }
  75.     }
  76.     res(radius, radius) = make_tuple(
  77.         median_helper(r, total),
  78.         median_helper(g, total),
  79.         median_helper(b, total)
  80.     );
  81.     for (uint col = radius + 1; col + radius < src_image.n_cols; col++) {
  82.         for (uint i = 0; i < 256; i++) {
  83.             r_c[col + radius][i] =
  84.             g_c[col + radius][i] =
  85.             b_c[col + radius][i] = 0;
  86.         }
  87.         for (uint row = 0; int(row) < radius * 2 + 1; row++) {
  88.             auto pixel = src_image(row, col - radius - 1);
  89.             r[get<0>(pixel)]--;
  90.             g[get<1>(pixel)]--;
  91.             b[get<2>(pixel)]--;
  92.             pixel = src_image(row, col + radius);
  93.             r[get<0>(pixel)]++;
  94.             g[get<1>(pixel)]++;
  95.             b[get<2>(pixel)]++;
  96.             r_c[col + radius][get<0>(pixel)]++;
  97.             g_c[col + radius][get<1>(pixel)]++;
  98.             b_c[col + radius][get<2>(pixel)]++;
  99.         }
  100.         res(radius, col) = make_tuple(
  101.             median_helper(r, total),
  102.             median_helper(g, total),
  103.             median_helper(b, total)
  104.         );
  105.     }
  106.     for (uint row = radius + 1; row + radius < src_image.n_rows; row++) {
  107.         // rebuild the matrix
  108.         for (uint i = 0; i < 256; i++) {
  109.             r[i] = g[i] = b[i] = 0;
  110.         }
  111.         for (uint col = 0; int(col) < radius * 2 + 1; col++) {
  112.             auto pixel = src_image(row - radius - 1, col);
  113.             r_c[col][get<0>(pixel)]--;
  114.             g_c[col][get<1>(pixel)]--;
  115.             b_c[col][get<2>(pixel)]--;
  116.  
  117.             pixel = src_image(row + radius, col);
  118.             r_c[col][get<0>(pixel)]++;
  119.             g_c[col][get<1>(pixel)]++;
  120.             b_c[col][get<2>(pixel)]++;
  121.  
  122.             for (uint j = 0; j < 256; j++) {
  123.                 r[j] += r_c[col][j];
  124.                 g[j] += g_c[col][j];
  125.                 b[j] += b_c[col][j];
  126.             }
  127.         }
  128.         res(row, radius) = make_tuple(
  129.             median_helper(r, total),
  130.             median_helper(g, total),
  131.             median_helper(b, total)
  132.         );
  133.         for (uint col = radius + 1; col + radius < src_image.n_cols; col++) {
  134.             auto pixel = src_image(row - radius - 1, col + radius);
  135.             r_c[col + radius][get<0>(pixel)]--;
  136.             g_c[col + radius][get<1>(pixel)]--;
  137.             b_c[col + radius][get<2>(pixel)]--;
  138.  
  139.             pixel = src_image(row + radius, col + radius);
  140.             r_c[col + radius][get<0>(pixel)]++;
  141.             g_c[col + radius][get<1>(pixel)]++;
  142.             b_c[col + radius][get<2>(pixel)]++;
  143.  
  144.             for (uint j = 0; j < 256; j++) {
  145.                 r[j] -= r_c[col - radius - 1][j];
  146.                 g[j] -= g_c[col - radius - 1][j];
  147.                 b[j] -= b_c[col - radius - 1][j];
  148.  
  149.                 r[j] += r_c[col + radius][j];
  150.                 g[j] += g_c[col + radius][j];
  151.                 b[j] += b_c[col + radius][j];
  152.             }
  153.             res(row, col) = make_tuple(
  154.                 median_helper(r, total),
  155.                 median_helper(g, total),
  156.                 median_helper(b, total)
  157.             );
  158.         }
  159.     }
  160.     return res.submatrix(radius, radius,
  161.         src_image.n_rows - 2 * radius,
  162.         src_image.n_cols - 2 * radius
  163.     );
  164. }