dual_demosaic: added Amaze+bilinear and Vng4+biliner, also made a small speedup, #5748

This commit is contained in:
Ingo Weyrich
2020-05-24 19:28:56 +02:00
parent 3ee5f0473a
commit bf30ca6c05
5 changed files with 34 additions and 37 deletions

View File

@@ -1909,11 +1909,13 @@ TP_RAW_3PASSBEST;3-pass (Markesteijn)
TP_RAW_4PASS;3-pass+fast TP_RAW_4PASS;3-pass+fast
TP_RAW_AHD;AHD TP_RAW_AHD;AHD
TP_RAW_AMAZE;AMaZE TP_RAW_AMAZE;AMaZE
TP_RAW_AMAZEBILINEAR;AMaZE+Bilinear
TP_RAW_AMAZEVNG4;AMaZE+VNG4 TP_RAW_AMAZEVNG4;AMaZE+VNG4
TP_RAW_BORDER;Border TP_RAW_BORDER;Border
TP_RAW_DCB;DCB TP_RAW_DCB;DCB
TP_RAW_DCBENHANCE;DCB enhancement TP_RAW_DCBENHANCE;DCB enhancement
TP_RAW_DCBITERATIONS;Number of DCB iterations TP_RAW_DCBITERATIONS;Number of DCB iterations
TP_RAW_DCBBILINEAR;DCB+Bilinear
TP_RAW_DCBVNG4;DCB+VNG4 TP_RAW_DCBVNG4;DCB+VNG4
TP_RAW_DMETHOD;Method TP_RAW_DMETHOD;Method
TP_RAW_DMETHOD_PROGRESSBAR;%1 demosaicing... TP_RAW_DMETHOD_PROGRESSBAR;%1 demosaicing...

View File

@@ -48,17 +48,18 @@ void RawImageSource::dual_demosaic_RT(bool isBayer, const procparams::RAWParams
if (contrast == 0.0 && !autoContrast) { if (contrast == 0.0 && !autoContrast) {
// contrast == 0.0 means only first demosaicer will be used // contrast == 0.0 means only first demosaicer will be used
if(isBayer) { if(isBayer) {
if (raw.bayersensor.method == procparams::RAWParams::BayerSensor::getMethodString(procparams::RAWParams::BayerSensor::Method::AMAZEVNG4) ) { if (raw.bayersensor.method == procparams::RAWParams::BayerSensor::getMethodString(procparams::RAWParams::BayerSensor::Method::AMAZEBILINEAR) ||
raw.bayersensor.method == procparams::RAWParams::BayerSensor::getMethodString(procparams::RAWParams::BayerSensor::Method::AMAZEVNG4)) {
amaze_demosaic_RT(0, 0, winw, winh, rawData, red, green, blue, options.chunkSizeAMAZE, options.measure); amaze_demosaic_RT(0, 0, winw, winh, rawData, red, green, blue, options.chunkSizeAMAZE, options.measure);
} else if (raw.bayersensor.method == procparams::RAWParams::BayerSensor::getMethodString(procparams::RAWParams::BayerSensor::Method::DCBVNG4) ) { } else if (raw.bayersensor.method == procparams::RAWParams::BayerSensor::getMethodString(procparams::RAWParams::BayerSensor::Method::DCBBILINEAR) ||
raw.bayersensor.method == procparams::RAWParams::BayerSensor::getMethodString(procparams::RAWParams::BayerSensor::Method::DCBVNG4)) {
dcb_demosaic(raw.bayersensor.dcb_iterations, raw.bayersensor.dcb_enhance); dcb_demosaic(raw.bayersensor.dcb_iterations, raw.bayersensor.dcb_enhance);
} else if (raw.bayersensor.method == procparams::RAWParams::BayerSensor::getMethodString(procparams::RAWParams::BayerSensor::Method::RCDBILINEAR) ) { } else if (raw.bayersensor.method == procparams::RAWParams::BayerSensor::getMethodString(procparams::RAWParams::BayerSensor::Method::RCDBILINEAR) ||
rcd_demosaic(options.chunkSizeRCD, options.measure); raw.bayersensor.method == procparams::RAWParams::BayerSensor::getMethodString(procparams::RAWParams::BayerSensor::Method::RCDVNG4)) {
} else if (raw.bayersensor.method == procparams::RAWParams::BayerSensor::getMethodString(procparams::RAWParams::BayerSensor::Method::RCDVNG4) ) {
rcd_demosaic(options.chunkSizeRCD, options.measure); rcd_demosaic(options.chunkSizeRCD, options.measure);
} }
} else { } else {
if (raw.xtranssensor.method == procparams::RAWParams::XTransSensor::getMethodString(procparams::RAWParams::XTransSensor::Method::FOUR_PASS) ) { if (raw.xtranssensor.method == procparams::RAWParams::XTransSensor::getMethodString(procparams::RAWParams::XTransSensor::Method::FOUR_PASS)) {
xtrans_interpolate (3, true, options.chunkSizeXT, options.measure); xtrans_interpolate (3, true, options.chunkSizeXT, options.measure);
} else { } else {
xtrans_interpolate (1, false, options.chunkSizeXT, options.measure); xtrans_interpolate (1, false, options.chunkSizeXT, options.measure);
@@ -71,17 +72,19 @@ void RawImageSource::dual_demosaic_RT(bool isBayer, const procparams::RAWParams
array2D<float> L(winw, winh); array2D<float> L(winw, winh);
if (isBayer) { if (isBayer) {
if (raw.bayersensor.method == procparams::RAWParams::BayerSensor::getMethodString(procparams::RAWParams::BayerSensor::Method::AMAZEVNG4) || raw.bayersensor.method == procparams::RAWParams::BayerSensor::getMethodString(procparams::RAWParams::BayerSensor::Method::PIXELSHIFT)) { if (raw.bayersensor.method == procparams::RAWParams::BayerSensor::getMethodString(procparams::RAWParams::BayerSensor::Method::AMAZEBILINEAR) ||
raw.bayersensor.method == procparams::RAWParams::BayerSensor::getMethodString(procparams::RAWParams::BayerSensor::Method::AMAZEVNG4) ||
raw.bayersensor.method == procparams::RAWParams::BayerSensor::getMethodString(procparams::RAWParams::BayerSensor::Method::PIXELSHIFT)) {
amaze_demosaic_RT(0, 0, winw, winh, rawData, red, green, blue, options.chunkSizeAMAZE, options.measure); amaze_demosaic_RT(0, 0, winw, winh, rawData, red, green, blue, options.chunkSizeAMAZE, options.measure);
} else if (raw.bayersensor.method == procparams::RAWParams::BayerSensor::getMethodString(procparams::RAWParams::BayerSensor::Method::DCBVNG4) ) { } else if (raw.bayersensor.method == procparams::RAWParams::BayerSensor::getMethodString(procparams::RAWParams::BayerSensor::Method::DCBBILINEAR) ||
raw.bayersensor.method == procparams::RAWParams::BayerSensor::getMethodString(procparams::RAWParams::BayerSensor::Method::DCBVNG4)) {
dcb_demosaic(raw.bayersensor.dcb_iterations, raw.bayersensor.dcb_enhance); dcb_demosaic(raw.bayersensor.dcb_iterations, raw.bayersensor.dcb_enhance);
} else if (raw.bayersensor.method == procparams::RAWParams::BayerSensor::getMethodString(procparams::RAWParams::BayerSensor::Method::RCDBILINEAR) ) { } else if (raw.bayersensor.method == procparams::RAWParams::BayerSensor::getMethodString(procparams::RAWParams::BayerSensor::Method::RCDBILINEAR) ||
rcd_demosaic(options.chunkSizeRCD, options.measure); raw.bayersensor.method == procparams::RAWParams::BayerSensor::getMethodString(procparams::RAWParams::BayerSensor::Method::RCDVNG4)) {
} else if (raw.bayersensor.method == procparams::RAWParams::BayerSensor::getMethodString(procparams::RAWParams::BayerSensor::Method::RCDVNG4) ) {
rcd_demosaic(options.chunkSizeRCD, options.measure); rcd_demosaic(options.chunkSizeRCD, options.measure);
} }
} else { } else {
if (raw.xtranssensor.method == procparams::RAWParams::XTransSensor::getMethodString(procparams::RAWParams::XTransSensor::Method::FOUR_PASS) ) { if (raw.xtranssensor.method == procparams::RAWParams::XTransSensor::getMethodString(procparams::RAWParams::XTransSensor::Method::FOUR_PASS)) {
xtrans_interpolate (3, true, options.chunkSizeXT, options.measure); xtrans_interpolate (3, true, options.chunkSizeXT, options.measure);
} else { } else {
xtrans_interpolate (1, false, options.chunkSizeXT, options.measure); xtrans_interpolate (1, false, options.chunkSizeXT, options.measure);
@@ -95,17 +98,13 @@ void RawImageSource::dual_demosaic_RT(bool isBayer, const procparams::RAWParams
}; };
#ifdef _OPENMP #ifdef _OPENMP
#pragma omp parallel #pragma omp parallel for schedule(dynamic,16)
#endif #endif
{ for(int i = 0; i < winh; ++i) {
#ifdef _OPENMP Color::RGB2L(red[i], green[i], blue[i], L[i], xyz_rgb, winw);
#pragma omp for
#endif
for(int i = 0; i < winh; ++i) {
Color::RGB2L(red[i], green[i], blue[i], L[i], xyz_rgb, winw);
}
} }
// calculate contrast based blend factors to use vng4 in regions with low contrast
// calculate contrast based blend factors to use flat demosaicer in regions with low contrast
JaggedArray<float> blend(winw, winh); JaggedArray<float> blend(winw, winh);
float contrastf = contrast / 100.0; float contrastf = contrast / 100.0;
@@ -117,7 +116,9 @@ void RawImageSource::dual_demosaic_RT(bool isBayer, const procparams::RAWParams
array2D<float> blueTmp(winw, winh); array2D<float> blueTmp(winw, winh);
if (isBayer) { if (isBayer) {
if (raw.bayersensor.method == procparams::RAWParams::BayerSensor::getMethodString(procparams::RAWParams::BayerSensor::Method::RCDBILINEAR) ) { if (raw.bayersensor.method == procparams::RAWParams::BayerSensor::getMethodString(procparams::RAWParams::BayerSensor::Method::AMAZEBILINEAR) ||
raw.bayersensor.method == procparams::RAWParams::BayerSensor::getMethodString(procparams::RAWParams::BayerSensor::Method::RCDBILINEAR) ||
raw.bayersensor.method == procparams::RAWParams::BayerSensor::getMethodString(procparams::RAWParams::BayerSensor::Method::DCBBILINEAR)) {
bayer_bilinear_demosaic(rawData, redTmp, greenTmp, blueTmp); bayer_bilinear_demosaic(rawData, redTmp, greenTmp, blueTmp);
} else { } else {
vng4_demosaic(rawData, redTmp, greenTmp, blueTmp); vng4_demosaic(rawData, redTmp, greenTmp, blueTmp);
@@ -126,32 +127,20 @@ void RawImageSource::dual_demosaic_RT(bool isBayer, const procparams::RAWParams
fast_xtrans_interpolate(rawData, redTmp, greenTmp, blueTmp); fast_xtrans_interpolate(rawData, redTmp, greenTmp, blueTmp);
} }
// the following is split into 3 loops intentionally to avoid cache conflicts on CPUs with only 4-way cache
#ifdef _OPENMP #ifdef _OPENMP
#pragma omp parallel for #pragma omp parallel for schedule(dynamic,16)
#endif #endif
for(int i = 0; i < winh; ++i) { for(int i = 0; i < winh; ++i) {
// the following is split into 3 loops intentionally to avoid cache conflicts on CPUs with only 4-way cache
for(int j = 0; j < winw; ++j) { for(int j = 0; j < winw; ++j) {
red[i][j] = intp(blend[i][j], red[i][j], redTmp[i][j]); red[i][j] = intp(blend[i][j], red[i][j], redTmp[i][j]);
} }
}
#ifdef _OPENMP
#pragma omp parallel for
#endif
for(int i = 0; i < winh; ++i) {
for(int j = 0; j < winw; ++j) { for(int j = 0; j < winw; ++j) {
green[i][j] = intp(blend[i][j], green[i][j], greenTmp[i][j]); green[i][j] = intp(blend[i][j], green[i][j], greenTmp[i][j]);
} }
}
#ifdef _OPENMP
#pragma omp parallel for
#endif
for(int i = 0; i < winh; ++i) {
for(int j = 0; j < winw; ++j) { for(int j = 0; j < winw; ++j) {
blue[i][j] = intp(blend[i][j], blue[i][j], blueTmp[i][j]); blue[i][j] = intp(blend[i][j], blue[i][j], blueTmp[i][j]);
} }
} }
} }
} }

View File

@@ -2764,11 +2764,13 @@ const std::vector<const char*>& RAWParams::BayerSensor::getMethodStrings()
{ {
static const std::vector<const char*> method_strings { static const std::vector<const char*> method_strings {
"amaze", "amaze",
"amazebilinear",
"amazevng4", "amazevng4",
"rcd", "rcd",
"rcdbilinear", "rcdbilinear",
"rcdvng4", "rcdvng4",
"dcb", "dcb",
"dcbbilinear",
"dcbvng4", "dcbvng4",
"lmmse", "lmmse",
"igv", "igv",

View File

@@ -1408,11 +1408,13 @@ struct RAWParams {
struct BayerSensor { struct BayerSensor {
enum class Method { enum class Method {
AMAZE, AMAZE,
AMAZEBILINEAR,
AMAZEVNG4, AMAZEVNG4,
RCD, RCD,
RCDBILINEAR, RCDBILINEAR,
RCDVNG4, RCDVNG4,
DCB, DCB,
DCBBILINEAR,
DCBVNG4, DCBVNG4,
LMMSE, LMMSE,
IGV, IGV,

View File

@@ -1578,7 +1578,9 @@ void RawImageSource::demosaic(const RAWParams &raw, bool autoContrast, double &c
ahd_demosaic (); ahd_demosaic ();
} else if (raw.bayersensor.method == RAWParams::BayerSensor::getMethodString(RAWParams::BayerSensor::Method::AMAZE)) { } else if (raw.bayersensor.method == RAWParams::BayerSensor::getMethodString(RAWParams::BayerSensor::Method::AMAZE)) {
amaze_demosaic_RT (0, 0, W, H, rawData, red, green, blue, options.chunkSizeAMAZE, options.measure); amaze_demosaic_RT (0, 0, W, H, rawData, red, green, blue, options.chunkSizeAMAZE, options.measure);
} else if (raw.bayersensor.method == RAWParams::BayerSensor::getMethodString(RAWParams::BayerSensor::Method::AMAZEVNG4) } else if (raw.bayersensor.method == RAWParams::BayerSensor::getMethodString(RAWParams::BayerSensor::Method::AMAZEBILINEAR)
|| raw.bayersensor.method == RAWParams::BayerSensor::getMethodString(RAWParams::BayerSensor::Method::AMAZEVNG4)
|| raw.bayersensor.method == RAWParams::BayerSensor::getMethodString(RAWParams::BayerSensor::Method::DCBBILINEAR)
|| raw.bayersensor.method == RAWParams::BayerSensor::getMethodString(RAWParams::BayerSensor::Method::DCBVNG4) || raw.bayersensor.method == RAWParams::BayerSensor::getMethodString(RAWParams::BayerSensor::Method::DCBVNG4)
|| raw.bayersensor.method == RAWParams::BayerSensor::getMethodString(RAWParams::BayerSensor::Method::RCDBILINEAR) || raw.bayersensor.method == RAWParams::BayerSensor::getMethodString(RAWParams::BayerSensor::Method::RCDBILINEAR)
|| raw.bayersensor.method == RAWParams::BayerSensor::getMethodString(RAWParams::BayerSensor::Method::RCDVNG4)) { || raw.bayersensor.method == RAWParams::BayerSensor::getMethodString(RAWParams::BayerSensor::Method::RCDVNG4)) {