From acc2b3d3081bfd1c8abc25c9dc6f98a5a71d1d51 Mon Sep 17 00:00:00 2001 From: Ingo Weyrich Date: Sun, 10 May 2020 12:16:48 +0200 Subject: [PATCH 1/4] Add RCD+Bilinear demosaic for Bayer sensors, #5748 --- rtdata/languages/default | 1 + rtengine/CMakeLists.txt | 1 + rtengine/bayer_bilinear_demosaic.cc | 58 +++++++++++++++++++++++++++++ rtengine/dual_demosaic_RT.cc | 12 +++++- rtengine/procparams.cc | 1 + rtengine/procparams.h | 1 + rtengine/rawimagesource.cc | 1 + rtengine/rawimagesource.h | 1 + rtgui/bayerprocess.cc | 3 +- 9 files changed, 76 insertions(+), 3 deletions(-) create mode 100644 rtengine/bayer_bilinear_demosaic.cc diff --git a/rtdata/languages/default b/rtdata/languages/default index f33608903..8b03dd439 100644 --- a/rtdata/languages/default +++ b/rtdata/languages/default @@ -1954,6 +1954,7 @@ TP_RAW_PIXELSHIFTSIGMA_TOOLTIP;The default radius of 1.0 usually fits well for b TP_RAW_PIXELSHIFTSMOOTH;Smooth transitions TP_RAW_PIXELSHIFTSMOOTH_TOOLTIP;Smooth transitions between areas with motion and areas without.\nSet to 0 to disable transition smoothing.\nSet to 1 to either get the AMaZE/LMMSE result of the selected frame (depending on whether "Use LMMSE" is selected), or the median of all four frames if "Use median" is selected. TP_RAW_RCD;RCD +TP_RAW_RCDBILINEAR;RCD+Bilinear TP_RAW_RCDVNG4;RCD+VNG4 TP_RAW_SENSOR_BAYER_LABEL;Sensor with Bayer Matrix TP_RAW_SENSOR_XTRANS_DMETHOD_TOOLTIP;3-pass gives best results (recommended for low ISO images).\n1-pass is almost undistinguishable from 3-pass for high ISO images and is faster.\n+fast gives less artifacts in flat areas diff --git a/rtengine/CMakeLists.txt b/rtengine/CMakeLists.txt index 3813c5708..0450ee29f 100644 --- a/rtengine/CMakeLists.txt +++ b/rtengine/CMakeLists.txt @@ -63,6 +63,7 @@ set(RTENGINESOURCEFILES ahd_demosaic_RT.cc amaze_demosaic_RT.cc badpixels.cc + bayer_bilinear_demosaic.cc boxblur.cc canon_cr3_decoder.cc CA_correct_RT.cc diff --git a/rtengine/bayer_bilinear_demosaic.cc b/rtengine/bayer_bilinear_demosaic.cc new file mode 100644 index 000000000..0125a21e7 --- /dev/null +++ b/rtengine/bayer_bilinear_demosaic.cc @@ -0,0 +1,58 @@ +//////////////////////////////////////////////////////////////// +// +// Bilinear bayer demosaic, optimized for speed, intended use is for flat regions of dual-demosaic +// +// copyright (c) 2020 Ingo Weyrich +// +// +// code dated: May 09, 2020 +// +// bayer_bilinear_demosaic.cc is free software: you can redistribute it and/or modify +// it under the terms of the GNU General Public License as published by +// the Free Software Foundation, either version 3 of the License, or +// (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program. If not, see . +// +//////////////////////////////////////////////////////////////// + +#include "rawimagesource.h" +#define BENCHMARK +#include "StopWatch.h" + +using namespace rtengine; + +void RawImageSource::bayer_bilinear_demosaic(const array2D &rawData, array2D &red, array2D &green, array2D &blue) +{ +BENCHFUN +#ifdef _OPENMP + #pragma omp parallel for +#endif + for (int i = 1; i < H - 1; ++i) { + float **nonGreen1 = red; + float **nonGreen2 = blue; + if (FC(i, 0) == 2 || FC(i, 1) == 2) { // blue row => swap pointers + std::swap(nonGreen1, nonGreen2); + } +#if defined(__clang__) + #pragma clang loop vectorize(assume_safety) +#elif defined(__GNUC__) + #pragma GCC ivdep +#endif + for (int j = 2 - (FC(i, 1) & 1); j < W - 2; j += 2) { // always begin with a green pixel + green[i][j] = rawData[i][j]; + nonGreen1[i][j] = (rawData[i][j - 1] + rawData[i][j + 1]) * 0.5f; + nonGreen2[i][j] = (rawData[i - 1][j] + rawData[i + 1][j]) * 0.5f; + green[i][j + 1] = ((rawData[i - 1][j + 1] + rawData[i][j]) + (rawData[i][j + 2] + rawData[i + 1][j + 1])) * 0.25f; + nonGreen1[i][j + 1] = rawData[i][j + 1]; + nonGreen2[i][j + 1] = ((rawData[i - 1][j] + rawData[i - 1][j + 2]) + (rawData[i + 1][j] + rawData[i + 1][j + 2])) * 0.25f; + } + } + border_interpolate(W, H, 2, rawData, red, green, blue); +} diff --git a/rtengine/dual_demosaic_RT.cc b/rtengine/dual_demosaic_RT.cc index 253468a76..bbf4e621a 100644 --- a/rtengine/dual_demosaic_RT.cc +++ b/rtengine/dual_demosaic_RT.cc @@ -33,7 +33,7 @@ #include "../rtgui/options.h" -//#define BENCHMARK +#define BENCHMARK #include "StopWatch.h" using namespace std; @@ -52,6 +52,8 @@ void RawImageSource::dual_demosaic_RT(bool isBayer, const procparams::RAWParams 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) ) { dcb_demosaic(raw.bayersensor.dcb_iterations, raw.bayersensor.dcb_enhance); + } else if (raw.bayersensor.method == procparams::RAWParams::BayerSensor::getMethodString(procparams::RAWParams::BayerSensor::Method::RCDBILINEAR) ) { + rcd_demosaic(options.chunkSizeRCD, options.measure); } else if (raw.bayersensor.method == procparams::RAWParams::BayerSensor::getMethodString(procparams::RAWParams::BayerSensor::Method::RCDVNG4) ) { rcd_demosaic(options.chunkSizeRCD, options.measure); } @@ -73,6 +75,8 @@ void RawImageSource::dual_demosaic_RT(bool isBayer, const procparams::RAWParams 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) ) { dcb_demosaic(raw.bayersensor.dcb_iterations, raw.bayersensor.dcb_enhance); + } else if (raw.bayersensor.method == procparams::RAWParams::BayerSensor::getMethodString(procparams::RAWParams::BayerSensor::Method::RCDBILINEAR) ) { + rcd_demosaic(options.chunkSizeRCD, options.measure); } else if (raw.bayersensor.method == procparams::RAWParams::BayerSensor::getMethodString(procparams::RAWParams::BayerSensor::Method::RCDVNG4) ) { rcd_demosaic(options.chunkSizeRCD, options.measure); } @@ -113,7 +117,11 @@ void RawImageSource::dual_demosaic_RT(bool isBayer, const procparams::RAWParams array2D blueTmp(winw, winh); if (isBayer) { - vng4_demosaic(rawData, redTmp, greenTmp, blueTmp); + if (raw.bayersensor.method == procparams::RAWParams::BayerSensor::getMethodString(procparams::RAWParams::BayerSensor::Method::RCDBILINEAR) ) { + bayer_bilinear_demosaic(rawData, redTmp, greenTmp, blueTmp); + } else { + vng4_demosaic(rawData, redTmp, greenTmp, blueTmp); + } } else { fast_xtrans_interpolate(rawData, redTmp, greenTmp, blueTmp); } diff --git a/rtengine/procparams.cc b/rtengine/procparams.cc index a198a6813..00a261056 100644 --- a/rtengine/procparams.cc +++ b/rtengine/procparams.cc @@ -2717,6 +2717,7 @@ const std::vector& RAWParams::BayerSensor::getMethodStrings() "amaze", "amazevng4", "rcd", + "rcdbilinear", "rcdvng4", "dcb", "dcbvng4", diff --git a/rtengine/procparams.h b/rtengine/procparams.h index f9710b01d..f33214d44 100644 --- a/rtengine/procparams.h +++ b/rtengine/procparams.h @@ -1395,6 +1395,7 @@ struct RAWParams { AMAZE, AMAZEVNG4, RCD, + RCDBILINEAR, RCDVNG4, DCB, DCBVNG4, diff --git a/rtengine/rawimagesource.cc b/rtengine/rawimagesource.cc index 75088a07c..a599f9a22 100644 --- a/rtengine/rawimagesource.cc +++ b/rtengine/rawimagesource.cc @@ -1575,6 +1575,7 @@ void RawImageSource::demosaic(const RAWParams &raw, bool autoContrast, double &c 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) || 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::RCDVNG4)) { if (!autoContrast) { double threshold = raw.bayersensor.dualDemosaicContrast; diff --git a/rtengine/rawimagesource.h b/rtengine/rawimagesource.h index 770c18ae3..861eb942a 100644 --- a/rtengine/rawimagesource.h +++ b/rtengine/rawimagesource.h @@ -300,6 +300,7 @@ protected: void xtrans_interpolate (const int passes, const bool useCieLab, size_t chunkSize = 1, bool measure = false); void fast_xtrans_interpolate (const array2D &rawData, array2D &red, array2D &green, array2D &blue); void pixelshift(int winx, int winy, int winw, int winh, const procparams::RAWParams &rawParams, unsigned int frame, const std::string &make, const std::string &model, float rawWpCorrection); + void bayer_bilinear_demosaic(const array2D &rawData, array2D &red, array2D &green, array2D &blue); void hflip (Imagefloat* im); void vflip (Imagefloat* im); void getRawValues(int x, int y, int rotate, int &R, int &G, int &B) override; diff --git a/rtgui/bayerprocess.cc b/rtgui/bayerprocess.cc index 5b5cfe9c4..9ba011c59 100644 --- a/rtgui/bayerprocess.cc +++ b/rtgui/bayerprocess.cc @@ -365,6 +365,7 @@ void BayerProcess::read(const rtengine::procparams::ProcParams* pp, const Params lmmseOptions->set_visible(pp->raw.bayersensor.method == procparams::RAWParams::BayerSensor::getMethodString(procparams::RAWParams::BayerSensor::Method::LMMSE)); dualDemosaicOptions->set_visible(pp->raw.bayersensor.method == procparams::RAWParams::BayerSensor::getMethodString(procparams::RAWParams::BayerSensor::Method::AMAZEVNG4) || pp->raw.bayersensor.method == procparams::RAWParams::BayerSensor::getMethodString(procparams::RAWParams::BayerSensor::Method::DCBVNG4) + || pp->raw.bayersensor.method == procparams::RAWParams::BayerSensor::getMethodString(procparams::RAWParams::BayerSensor::Method::RCDBILINEAR) || pp->raw.bayersensor.method == procparams::RAWParams::BayerSensor::getMethodString(procparams::RAWParams::BayerSensor::Method::RCDVNG4)); if (pp->raw.bayersensor.method == procparams::RAWParams::BayerSensor::getMethodString(procparams::RAWParams::BayerSensor::Method::PIXELSHIFT)) { pixelShiftOptions->set_visible(pp->raw.bayersensor.pixelShiftMotionCorrectionMethod == RAWParams::BayerSensor::PSMotionCorrectionMethod::CUSTOM); @@ -573,7 +574,7 @@ void BayerProcess::methodChanged () lmmseOptions->hide(); } - if (currentMethod == procparams::RAWParams::BayerSensor::Method::AMAZEVNG4 || currentMethod == procparams::RAWParams::BayerSensor::Method::DCBVNG4 || currentMethod == procparams::RAWParams::BayerSensor::Method::RCDVNG4) { + if (currentMethod == procparams::RAWParams::BayerSensor::Method::AMAZEVNG4 || currentMethod == procparams::RAWParams::BayerSensor::Method::DCBVNG4 || currentMethod == procparams::RAWParams::BayerSensor::Method::RCDVNG4 || currentMethod == procparams::RAWParams::BayerSensor::Method::RCDBILINEAR) { dualDemosaicOptions->show(); } else { dualDemosaicOptions->hide(); From bf30ca6c05ef134852b84013c6706bb10edd2479 Mon Sep 17 00:00:00 2001 From: Ingo Weyrich Date: Sun, 24 May 2020 19:28:56 +0200 Subject: [PATCH 2/4] dual_demosaic: added Amaze+bilinear and Vng4+biliner, also made a small speedup, #5748 --- rtdata/languages/default | 2 ++ rtengine/dual_demosaic_RT.cc | 61 +++++++++++++++--------------------- rtengine/procparams.cc | 2 ++ rtengine/procparams.h | 2 ++ rtengine/rawimagesource.cc | 4 ++- 5 files changed, 34 insertions(+), 37 deletions(-) diff --git a/rtdata/languages/default b/rtdata/languages/default index e4c3a3a08..b30e7dd32 100644 --- a/rtdata/languages/default +++ b/rtdata/languages/default @@ -1909,11 +1909,13 @@ TP_RAW_3PASSBEST;3-pass (Markesteijn) TP_RAW_4PASS;3-pass+fast TP_RAW_AHD;AHD TP_RAW_AMAZE;AMaZE +TP_RAW_AMAZEBILINEAR;AMaZE+Bilinear TP_RAW_AMAZEVNG4;AMaZE+VNG4 TP_RAW_BORDER;Border TP_RAW_DCB;DCB TP_RAW_DCBENHANCE;DCB enhancement TP_RAW_DCBITERATIONS;Number of DCB iterations +TP_RAW_DCBBILINEAR;DCB+Bilinear TP_RAW_DCBVNG4;DCB+VNG4 TP_RAW_DMETHOD;Method TP_RAW_DMETHOD_PROGRESSBAR;%1 demosaicing... diff --git a/rtengine/dual_demosaic_RT.cc b/rtengine/dual_demosaic_RT.cc index bbf4e621a..f7a403c16 100644 --- a/rtengine/dual_demosaic_RT.cc +++ b/rtengine/dual_demosaic_RT.cc @@ -48,17 +48,18 @@ void RawImageSource::dual_demosaic_RT(bool isBayer, const procparams::RAWParams if (contrast == 0.0 && !autoContrast) { // contrast == 0.0 means only first demosaicer will be used 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); - } 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); - } else if (raw.bayersensor.method == procparams::RAWParams::BayerSensor::getMethodString(procparams::RAWParams::BayerSensor::Method::RCDBILINEAR) ) { - rcd_demosaic(options.chunkSizeRCD, options.measure); - } else if (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::RCDBILINEAR) || + raw.bayersensor.method == procparams::RAWParams::BayerSensor::getMethodString(procparams::RAWParams::BayerSensor::Method::RCDVNG4)) { rcd_demosaic(options.chunkSizeRCD, options.measure); } } 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); } else { xtrans_interpolate (1, false, options.chunkSizeXT, options.measure); @@ -71,17 +72,19 @@ void RawImageSource::dual_demosaic_RT(bool isBayer, const procparams::RAWParams array2D L(winw, winh); 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); - } 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); - } else if (raw.bayersensor.method == procparams::RAWParams::BayerSensor::getMethodString(procparams::RAWParams::BayerSensor::Method::RCDBILINEAR) ) { - rcd_demosaic(options.chunkSizeRCD, options.measure); - } else if (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::RCDBILINEAR) || + raw.bayersensor.method == procparams::RAWParams::BayerSensor::getMethodString(procparams::RAWParams::BayerSensor::Method::RCDVNG4)) { rcd_demosaic(options.chunkSizeRCD, options.measure); } } 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); } else { xtrans_interpolate (1, false, options.chunkSizeXT, options.measure); @@ -95,17 +98,13 @@ void RawImageSource::dual_demosaic_RT(bool isBayer, const procparams::RAWParams }; #ifdef _OPENMP - #pragma omp parallel + #pragma omp parallel for schedule(dynamic,16) #endif - { -#ifdef _OPENMP - #pragma omp for -#endif - for(int i = 0; i < winh; ++i) { - Color::RGB2L(red[i], green[i], blue[i], L[i], xyz_rgb, winw); - } + 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 blend(winw, winh); float contrastf = contrast / 100.0; @@ -117,7 +116,9 @@ void RawImageSource::dual_demosaic_RT(bool isBayer, const procparams::RAWParams array2D blueTmp(winw, winh); 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); } else { 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); } - - // the following is split into 3 loops intentionally to avoid cache conflicts on CPUs with only 4-way cache #ifdef _OPENMP - #pragma omp parallel for + #pragma omp parallel for schedule(dynamic,16) #endif 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) { 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) { 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) { blue[i][j] = intp(blend[i][j], blue[i][j], blueTmp[i][j]); } } - } } diff --git a/rtengine/procparams.cc b/rtengine/procparams.cc index 56cccb4bb..57bcf604a 100644 --- a/rtengine/procparams.cc +++ b/rtengine/procparams.cc @@ -2764,11 +2764,13 @@ const std::vector& RAWParams::BayerSensor::getMethodStrings() { static const std::vector method_strings { "amaze", + "amazebilinear", "amazevng4", "rcd", "rcdbilinear", "rcdvng4", "dcb", + "dcbbilinear", "dcbvng4", "lmmse", "igv", diff --git a/rtengine/procparams.h b/rtengine/procparams.h index 4e7f6d3ff..0c0631624 100644 --- a/rtengine/procparams.h +++ b/rtengine/procparams.h @@ -1408,11 +1408,13 @@ struct RAWParams { struct BayerSensor { enum class Method { AMAZE, + AMAZEBILINEAR, AMAZEVNG4, RCD, RCDBILINEAR, RCDVNG4, DCB, + DCBBILINEAR, DCBVNG4, LMMSE, IGV, diff --git a/rtengine/rawimagesource.cc b/rtengine/rawimagesource.cc index 4f78dfbdb..7d3f5ab2c 100644 --- a/rtengine/rawimagesource.cc +++ b/rtengine/rawimagesource.cc @@ -1578,7 +1578,9 @@ void RawImageSource::demosaic(const RAWParams &raw, bool autoContrast, double &c ahd_demosaic (); } 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); - } 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::RCDBILINEAR) || raw.bayersensor.method == RAWParams::BayerSensor::getMethodString(RAWParams::BayerSensor::Method::RCDVNG4)) { From 1c11db3fc959e2403d63005ad40fd3f2c4832f6c Mon Sep 17 00:00:00 2001 From: Ingo Weyrich Date: Mon, 25 May 2020 16:28:04 +0200 Subject: [PATCH 3/4] Speedup for bilinear dual demosaicers, #5748 --- rtengine/bayer_bilinear_demosaic.cc | 16 ++++++++-------- rtengine/dual_demosaic_RT.cc | 11 ++++++++--- rtengine/rawimagesource.h | 2 +- 3 files changed, 17 insertions(+), 12 deletions(-) diff --git a/rtengine/bayer_bilinear_demosaic.cc b/rtengine/bayer_bilinear_demosaic.cc index 0125a21e7..2fa0812dc 100644 --- a/rtengine/bayer_bilinear_demosaic.cc +++ b/rtengine/bayer_bilinear_demosaic.cc @@ -23,12 +23,13 @@ //////////////////////////////////////////////////////////////// #include "rawimagesource.h" +#include "rt_math.h" #define BENCHMARK #include "StopWatch.h" using namespace rtengine; -void RawImageSource::bayer_bilinear_demosaic(const array2D &rawData, array2D &red, array2D &green, array2D &blue) +void RawImageSource::bayer_bilinear_demosaic(const float* const * blend, const array2D &rawData, array2D &red, array2D &green, array2D &blue) { BENCHFUN #ifdef _OPENMP @@ -46,13 +47,12 @@ BENCHFUN #pragma GCC ivdep #endif for (int j = 2 - (FC(i, 1) & 1); j < W - 2; j += 2) { // always begin with a green pixel - green[i][j] = rawData[i][j]; - nonGreen1[i][j] = (rawData[i][j - 1] + rawData[i][j + 1]) * 0.5f; - nonGreen2[i][j] = (rawData[i - 1][j] + rawData[i + 1][j]) * 0.5f; - green[i][j + 1] = ((rawData[i - 1][j + 1] + rawData[i][j]) + (rawData[i][j + 2] + rawData[i + 1][j + 1])) * 0.25f; - nonGreen1[i][j + 1] = rawData[i][j + 1]; - nonGreen2[i][j + 1] = ((rawData[i - 1][j] + rawData[i - 1][j + 2]) + (rawData[i + 1][j] + rawData[i + 1][j + 2])) * 0.25f; + green[i][j] = intp(blend[i][j], green[i][j], rawData[i][j]); + nonGreen1[i][j] = intp(blend[i][j], nonGreen1[i][j], (rawData[i][j - 1] + rawData[i][j + 1]) * 0.5f); + nonGreen2[i][j] = intp(blend[i][j], nonGreen2[i][j], (rawData[i - 1][j] + rawData[i + 1][j]) * 0.5f); + green[i][j + 1] = intp(blend[i][j + 1], green[i][j + 1], ((rawData[i - 1][j + 1] + rawData[i][j]) + (rawData[i][j + 2] + rawData[i + 1][j + 1])) * 0.25f); + nonGreen1[i][j + 1] = intp(blend[i][j + 1], nonGreen1[i][j + 1], rawData[i][j + 1]); + nonGreen2[i][j + 1] = intp(blend[i][j + 1], nonGreen2[i][j + 1], ((rawData[i - 1][j] + rawData[i - 1][j + 2]) + (rawData[i + 1][j] + rawData[i + 1][j + 2])) * 0.25f); } } - border_interpolate(W, H, 2, rawData, red, green, blue); } diff --git a/rtengine/dual_demosaic_RT.cc b/rtengine/dual_demosaic_RT.cc index f7a403c16..ad95776ce 100644 --- a/rtengine/dual_demosaic_RT.cc +++ b/rtengine/dual_demosaic_RT.cc @@ -112,18 +112,23 @@ void RawImageSource::dual_demosaic_RT(bool isBayer, const procparams::RAWParams contrast = contrastf * 100.f; array2D& redTmp = L; // L is not needed anymore => reuse it - array2D greenTmp(winw, winh); - array2D blueTmp(winw, winh); + array2D greenTmp; + array2D blueTmp; if (isBayer) { 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(blend, rawData, red, green, blue); + return; } else { + greenTmp(winw, winh); + blueTmp(winw, winh); vng4_demosaic(rawData, redTmp, greenTmp, blueTmp); } } else { + greenTmp(winw, winh); + blueTmp(winw, winh); fast_xtrans_interpolate(rawData, redTmp, greenTmp, blueTmp); } diff --git a/rtengine/rawimagesource.h b/rtengine/rawimagesource.h index 861eb942a..712ecb073 100644 --- a/rtengine/rawimagesource.h +++ b/rtengine/rawimagesource.h @@ -300,7 +300,7 @@ protected: void xtrans_interpolate (const int passes, const bool useCieLab, size_t chunkSize = 1, bool measure = false); void fast_xtrans_interpolate (const array2D &rawData, array2D &red, array2D &green, array2D &blue); void pixelshift(int winx, int winy, int winw, int winh, const procparams::RAWParams &rawParams, unsigned int frame, const std::string &make, const std::string &model, float rawWpCorrection); - void bayer_bilinear_demosaic(const array2D &rawData, array2D &red, array2D &green, array2D &blue); + void bayer_bilinear_demosaic(const float *const * blend, const array2D &rawData, array2D &red, array2D &green, array2D &blue); void hflip (Imagefloat* im); void vflip (Imagefloat* im); void getRawValues(int x, int y, int rotate, int &R, int &G, int &B) override; From a11d41b41a239afad56f9123b34e021b50e03e8f Mon Sep 17 00:00:00 2001 From: Ingo Weyrich Date: Sun, 16 Aug 2020 12:19:52 +0200 Subject: [PATCH 4/4] Enable dd contrast threshold adjuster for Amaze+bilinear and DCB+bilinear --- rtgui/bayerprocess.cc | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/rtgui/bayerprocess.cc b/rtgui/bayerprocess.cc index a1aa3f01e..f678c858b 100644 --- a/rtgui/bayerprocess.cc +++ b/rtgui/bayerprocess.cc @@ -366,7 +366,9 @@ void BayerProcess::read(const rtengine::procparams::ProcParams* pp, const Params dcbOptions->set_visible(pp->raw.bayersensor.method == procparams::RAWParams::BayerSensor::getMethodString(procparams::RAWParams::BayerSensor::Method::DCB) || pp->raw.bayersensor.method == procparams::RAWParams::BayerSensor::getMethodString(procparams::RAWParams::BayerSensor::Method::DCBVNG4)); lmmseOptions->set_visible(pp->raw.bayersensor.method == procparams::RAWParams::BayerSensor::getMethodString(procparams::RAWParams::BayerSensor::Method::LMMSE)); dualDemosaicOptions->set_visible(pp->raw.bayersensor.method == procparams::RAWParams::BayerSensor::getMethodString(procparams::RAWParams::BayerSensor::Method::AMAZEVNG4) + || pp->raw.bayersensor.method == procparams::RAWParams::BayerSensor::getMethodString(procparams::RAWParams::BayerSensor::Method::AMAZEBILINEAR) || pp->raw.bayersensor.method == procparams::RAWParams::BayerSensor::getMethodString(procparams::RAWParams::BayerSensor::Method::DCBVNG4) + || pp->raw.bayersensor.method == procparams::RAWParams::BayerSensor::getMethodString(procparams::RAWParams::BayerSensor::Method::DCBBILINEAR) || pp->raw.bayersensor.method == procparams::RAWParams::BayerSensor::getMethodString(procparams::RAWParams::BayerSensor::Method::RCDBILINEAR) || pp->raw.bayersensor.method == procparams::RAWParams::BayerSensor::getMethodString(procparams::RAWParams::BayerSensor::Method::RCDVNG4)); if (pp->raw.bayersensor.method == procparams::RAWParams::BayerSensor::getMethodString(procparams::RAWParams::BayerSensor::Method::PIXELSHIFT)) { @@ -576,7 +578,12 @@ void BayerProcess::methodChanged () lmmseOptions->hide(); } - if (currentMethod == procparams::RAWParams::BayerSensor::Method::AMAZEVNG4 || currentMethod == procparams::RAWParams::BayerSensor::Method::DCBVNG4 || currentMethod == procparams::RAWParams::BayerSensor::Method::RCDVNG4 || currentMethod == procparams::RAWParams::BayerSensor::Method::RCDBILINEAR) { + if (currentMethod == procparams::RAWParams::BayerSensor::Method::AMAZEVNG4 || + currentMethod == procparams::RAWParams::BayerSensor::Method::DCBVNG4 || + currentMethod == procparams::RAWParams::BayerSensor::Method::RCDVNG4 || + currentMethod == procparams::RAWParams::BayerSensor::Method::AMAZEBILINEAR || + currentMethod == procparams::RAWParams::BayerSensor::Method::DCBBILINEAR || + currentMethod == procparams::RAWParams::BayerSensor::Method::RCDBILINEAR) { dualDemosaicOptions->show(); } else { dualDemosaicOptions->hide();