void demosaicEdgeAware()

in source/isp/CameraIsp.h [160:224]


  void demosaicEdgeAware(cv::Mat_<float>& red, cv::Mat_<float>& green, cv::Mat_<float>& blue)
      const {
    // Horizontal and vertical green values
    cv::Mat_<float> gV(height, width);
    cv::Mat_<float> gH(height, width);

    // And their first and second order derivatives
    cv::Mat_<float> dV(height, width);
    cv::Mat_<float> dH(height, width);

    // Compute green gradients
    for (int i = 0; i < height; ++i) {
      const int i_1 = math_util::reflect(i - 1, height);
      const int i1 = math_util::reflect(i + 1, height);
      const int i_2 = math_util::reflect(i - 2, height);
      const int i2 = math_util::reflect(i + 2, height);

      for (int j = 0; j < width; ++j) {
        const int j_1 = math_util::reflect(j - 1, width);
        const int j1 = math_util::reflect(j + 1, width);
        const int j_2 = math_util::reflect(j - 2, width);
        const int j2 = math_util::reflect(j + 2, width);
        if (greenPixel(i, j)) {
          gV(i, j) = green(i, j);
          gH(i, j) = green(i, j);

          dV(i, j) =
              (fabsf(green(i2, j) - green(i, j)) + fabsf(green(i, j) - green(i_2, j))) / 2.0f;

          dH(i, j) =
              (fabsf(green(i, j2) - green(i, j)) + fabsf(green(i, j) - green(i, j_2))) / 2.0f;
        } else {
          gV(i, j) = (green(i_1, j) + green(i1, j)) / 2.0f;
          gH(i, j) = (green(i, j_1) + green(i, j1)) / 2.0f;
          dV(i, j) = (fabsf(green(i_1, j) - green(i1, j))) / 2.0f;
          dH(i, j) = (fabsf(green(i, j_1) - green(i, j1))) / 2.0f;

          cv::Mat_<float>& ch = redPixel(i, j) ? red : blue;
          gV(i, j) += (2.0f * ch(i, j) - ch(i_2, j) - ch(i2, j)) / 4.0f;
          gH(i, j) += (2.0f * ch(i, j) - ch(i, j_2) - ch(i, j2)) / 4.0f;
          dV(i, j) += fabsf(-2.0f * ch(i, j) + ch(i_2, j) + ch(i2, j)) / 2.0f;
          dH(i, j) += fabsf(-2.0f * ch(i, j) + ch(i, j_2) + ch(i, j2)) / 2.0f;
        }
      }
    }
    const int w = 4;
    const int diameter = 2 * w + 1;
    const int diameterSquared = math_util::square(diameter);

    for (int i = 0; i < height; ++i) {
      for (int j = 0; j < width; ++j) {
        // Homogenity test
        int hCount = 0;
        for (int l = -w; l <= w; ++l) {
          const int il = math_util::reflect(i + l, height);
          for (int k = -w; k <= w; ++k) {
            const int jk = math_util::reflect(j + k, width);
            hCount += (dH(il, jk) <= dV(il, jk));
          }
        }
        green(i, j) = math_util::lerp(gV(i, j), gH(i, j), float(hCount) / diameterSquared);
      }
    }
    demosaicChromaSuppressed(red, green, blue);
  }