2-pass dual-demosaic-contrast-threshold detection if 1-pass does not find a flat area, #4866

This commit is contained in:
heckflosse 2018-10-18 22:09:35 +02:00
parent bb0743898b
commit 0da47b0da3
4 changed files with 70 additions and 81 deletions

View File

@ -36,7 +36,7 @@ using namespace std;
namespace rtengine
{
void RawImageSource::dual_demosaic_RT(bool isBayer, const RAWParams &raw, int winw, int winh, const array2D<float> &rawData, array2D<float> &red, array2D<float> &green, array2D<float> &blue, double &contrast, bool autoContrast, int autoX, int autoY)
void RawImageSource::dual_demosaic_RT(bool isBayer, const RAWParams &raw, int winw, int winh, const array2D<float> &rawData, array2D<float> &red, array2D<float> &green, array2D<float> &blue, double &contrast, bool autoContrast)
{
BENCHFUN
@ -91,24 +91,6 @@ void RawImageSource::dual_demosaic_RT(bool isBayer, const RAWParams &raw, int wi
{ 0.019334, 0.119193, 0.950227 }
};
if (autoContrast && autoX >= 0 && autoY >= 0) {
constexpr int rectSize = 40;
const int autoWidth = min(rectSize, winw - autoX);
const int autoHeight = min(rectSize, winh - autoY);
if (std::min(autoWidth, autoHeight) > 20) {
array2D<float> autoL(autoWidth, autoHeight);
for(int i = 0; i < autoHeight; ++i) {
Color::RGB2L(red[i + autoY] + autoX, green[i + autoY] + autoX, blue[i + autoY] + autoX, autoL[i], xyz_rgb, autoWidth);
}
// calculate contrast based blend factors to use vng4 in regions with low contrast
JaggedArray<float> blend(autoWidth - 2, autoHeight - 2);
int c = calcContrastThreshold(autoL, blend, autoWidth, autoHeight);
if(c < 100) {
contrast = c; // alternative : contrast = c - 1
}
}
}
#pragma omp parallel
{
#pragma omp for

View File

@ -2074,7 +2074,7 @@ void RawImageSource::demosaic(const RAWParams &raw, bool autoContrast, double &c
double threshold = raw.bayersensor.dualDemosaicContrast;
dual_demosaic_RT (true, raw, W, H, rawData, red, green, blue, threshold, false);
} else {
dual_demosaic_RT (true, raw, W, H, rawData, red, green, blue, contrastThreshold, true, 0, 0);
dual_demosaic_RT (true, raw, W, H, rawData, red, green, blue, contrastThreshold, true);
}
} else if (raw.bayersensor.method == RAWParams::BayerSensor::getMethodString(RAWParams::BayerSensor::Method::PIXELSHIFT) ) {
pixelshift(0, 0, W, H, raw, currFrame, ri->get_maker(), ri->get_model(), raw.expos);
@ -2107,7 +2107,7 @@ void RawImageSource::demosaic(const RAWParams &raw, bool autoContrast, double &c
double threshold = raw.xtranssensor.dualDemosaicContrast;
dual_demosaic_RT (false, raw, W, H, rawData, red, green, blue, threshold, false);
} else {
dual_demosaic_RT (false, raw, W, H, rawData, red, green, blue, contrastThreshold, true, 0, 0);
dual_demosaic_RT (false, raw, W, H, rawData, red, green, blue, contrastThreshold, true);
}
} else if(raw.xtranssensor.method == RAWParams::XTransSensor::getMethodString(RAWParams::XTransSensor::Method::MONO) ) {
nodemosaic(true);

View File

@ -274,7 +274,7 @@ protected:
void igv_interpolate(int winw, int winh);
void lmmse_interpolate_omp(int winw, int winh, array2D<float> &rawData, array2D<float> &red, array2D<float> &green, array2D<float> &blue, int iterations);
void amaze_demosaic_RT(int winx, int winy, int winw, int winh, const array2D<float> &rawData, array2D<float> &red, array2D<float> &green, array2D<float> &blue);//Emil's code for AMaZE
void dual_demosaic_RT(bool isBayer, const RAWParams &raw, int winw, int winh, const array2D<float> &rawData, array2D<float> &red, array2D<float> &green, array2D<float> &blue, double &contrast, bool autoContrast = false, int autoX = -1, int autoY = -1);
void dual_demosaic_RT(bool isBayer, const RAWParams &raw, int winw, int winh, const array2D<float> &rawData, array2D<float> &red, array2D<float> &green, array2D<float> &blue, double &contrast, bool autoContrast = false);
void fast_demosaic();//Emil's code for fast demosaicing
void dcb_demosaic(int iterations, bool dcb_enhance);
void ahd_demosaic();

View File

@ -204,7 +204,8 @@ void buildBlendMask(float** luminance, float **blend, int W, int H, float contra
constexpr float scale = 0.0625f / 327.68f;
if (autoContrast) {
StopWatch StopC("calculate dual demosaic auto contrast threshold");
constexpr int tilesize = 80;
for (int pass = 0; pass < 2; ++pass) {
const int tilesize = 80 / (pass + 1);
const int numTilesW = W / tilesize;
const int numTilesH = H / tilesize;
std::vector<std::vector<std::pair<float, float>>> variances(numTilesH, std::vector<std::pair<float, float>>(numTilesW));
@ -255,20 +256,23 @@ void buildBlendMask(float** luminance, float **blend, int W, int H, float contra
}
float minvar = RT_INFINITY_F;
int minY = 0, minX = 0;
int minI = 0, minJ = 0;
for (int i = 0; i < numTilesH; ++i) {
for (int j = 0; j < numTilesW; ++j) {
if (variances[i][j].first < minvar && variances[i][j].second > 2000.f && variances[i][j].second < 20000.f) {
minvar = variances[i][j].first;
minY = tilesize * i;
minX = tilesize * j;
minI = i;
minJ = j;
}
}
}
// std::cout << "minY : " << minY << std::endl;
// std::cout << "minX : " << minX << std::endl;
// std::cout << "minvar : " << minvar << std::endl;
const int minY = tilesize * minI;
const int minX = tilesize * minJ;
std::cout << "minvar : " << minvar << std::endl;
// if (minvar <= 1.f || pass == 1) {
// a variance <= 1 means we already found a flat region and can skip second pass
JaggedArray<float> Lum(tilesize, tilesize);
JaggedArray<float> Blend(tilesize, tilesize);
for (int i = 0; i < tilesize; ++i) {
@ -277,7 +281,10 @@ void buildBlendMask(float** luminance, float **blend, int W, int H, float contra
}
}
calcContrastThreshold(Lum, Blend, tilesize, tilesize);
/*contrastThreshold = */calcContrastThreshold(Lum, Blend, tilesize, tilesize);// / 100.f;
// break;
// }
}
}
#ifdef _OPENMP
@ -368,7 +375,7 @@ int calcContrastThreshold(float** luminance, float **blend, int W, int H) {
}
}
const float limit = (W - 2) * (H - 2) / 100.f;
const float limit = (W - 4) * (H - 4) / 100.f;
int c;
for (c = 1; c < 100; ++c) {