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);
}
}
}