void demosaic()

in source/isp/CameraIsp.h [1114:1174]


  void demosaic() {
    uint32_t h2 = demosaicFilter == DemosaicFilter::FREQUENCY ? nextPowerOf2(height) : height;
    uint32_t w2 = demosaicFilter == DemosaicFilter::FREQUENCY ? nextPowerOf2(width) : width;
    cv::Mat_<float> r(h2, w2, 0.0f);
    cv::Mat_<float> g(h2, w2, 0.0f);
    cv::Mat_<float> b(h2, w2, 0.0f);

    // Break out each plane into a separate image so we can demosaicFilter
    // them separately and then recombine them.
    for (int i = 0; i < height; ++i) {
      for (int j = 0; j < width; j++) {
        if (redPixel(i, j)) {
          r(i, j) = rawImage(i, j);
        } else if (greenPixel(i, j)) {
          g(i, j) = rawImage(i, j);
        } else {
          b(i, j) = rawImage(i, j);
        }
      }
    }

    if (demosaicFilter == DemosaicFilter::FREQUENCY) {
      // Move into the frequency domain
      std::thread t1([&] { dct(r, r); });
      std::thread t2([&] { dct(g, g); });
      std::thread t3([&] { dct(b, b); });

      t1.join();
      t2.join();
      t3.join();

      // Filter including sharpnning in the DCT domain
      demosaicFrequencyFilter(r, g, b);
#undef DEBUG_DCT
#ifndef DEBUG_DCT
      // Move back into the spatial domain
      std::thread t4([&] { idct(r, r); });
      std::thread t5([&] { idct(g, g); });
      std::thread t6([&] { idct(b, b); });

      t4.join();
      t5.join();
      t6.join();
#endif
    } else if (demosaicFilter == DemosaicFilter::BILINEAR) {
      demosaicBilinearFilter(r, g, b);
    } else if (demosaicFilter == DemosaicFilter::CHROMA_SUPRESSED_BILINEAR) {
      demosaicGreenBilinear(r, g, b);
    } else {
      demosaicEdgeAware(r, g, b);
    }

    demosaicedImage = cv::Mat::zeros(height, width, CV_32F);
    for (int i = 0; i < height; ++i) {
      for (int j = 0; j < width; j++) {
        demosaicedImage(i, j)[0] = r(i, j);
        demosaicedImage(i, j)[1] = g(i, j);
        demosaicedImage(i, j)[2] = b(i, j);
      }
    }
  }