Add checkbox for disabling NR gain

Option to disable noise reduction automatic gain for consistency between
photographs.
Fix automatic gain not being recalculated after changing the white level
correction.
This commit is contained in:
Lawrence Lee 2023-07-15 17:47:26 -07:00
parent 1d9225dfc3
commit 473d50a0a3
No known key found for this signature in database
GPG Key ID: 048FF2B76A63895F
9 changed files with 44 additions and 3 deletions

View File

@ -1405,6 +1405,7 @@ HISTORY_MSG_DEHAZE_ENABLED;Haze Removal
HISTORY_MSG_DEHAZE_SATURATION;Dehaze - Saturation HISTORY_MSG_DEHAZE_SATURATION;Dehaze - Saturation
HISTORY_MSG_DEHAZE_SHOW_DEPTH_MAP;Dehaze - Show depth map HISTORY_MSG_DEHAZE_SHOW_DEPTH_MAP;Dehaze - Show depth map
HISTORY_MSG_DEHAZE_STRENGTH;Dehaze - Strength HISTORY_MSG_DEHAZE_STRENGTH;Dehaze - Strength
HISTORY_MSG_DIRPYRDENOISE_GAIN;NR - Compensate for lightness
HISTORY_MSG_DUALDEMOSAIC_AUTO_CONTRAST;Dual demosaic - Auto threshold HISTORY_MSG_DUALDEMOSAIC_AUTO_CONTRAST;Dual demosaic - Auto threshold
HISTORY_MSG_DUALDEMOSAIC_CONTRAST;Dual demosaic - Contrast threshold HISTORY_MSG_DUALDEMOSAIC_CONTRAST;Dual demosaic - Contrast threshold
HISTORY_MSG_EDGEFFECT;Edge Attenuation response HISTORY_MSG_EDGEFFECT;Edge Attenuation response
@ -2405,6 +2406,8 @@ TP_DIRPYRDENOISE_LUMINANCE_CURVE;Luminance curve
TP_DIRPYRDENOISE_LUMINANCE_DETAIL;Detail recovery TP_DIRPYRDENOISE_LUMINANCE_DETAIL;Detail recovery
TP_DIRPYRDENOISE_LUMINANCE_FRAME;Luminance TP_DIRPYRDENOISE_LUMINANCE_FRAME;Luminance
TP_DIRPYRDENOISE_LUMINANCE_SMOOTHING;Luminance TP_DIRPYRDENOISE_LUMINANCE_SMOOTHING;Luminance
TP_DIRPYRDENOISE_MAIN_AUTO_GAIN;Compensate for lightness
TP_DIRPYRDENOISE_MAIN_AUTO_GAIN_TOOLTIP;Alter the noise reduction strength based on the image lightness. Strength is reduced for dark images and increased for bright images.
TP_DIRPYRDENOISE_MAIN_COLORSPACE;Color space TP_DIRPYRDENOISE_MAIN_COLORSPACE;Color space
TP_DIRPYRDENOISE_MAIN_COLORSPACE_LAB;L*a*b* TP_DIRPYRDENOISE_MAIN_COLORSPACE_LAB;L*a*b*
TP_DIRPYRDENOISE_MAIN_COLORSPACE_RGB;RGB TP_DIRPYRDENOISE_MAIN_COLORSPACE_RGB;RGB

View File

@ -665,7 +665,7 @@ BENCHFUN
Color::gammanf2lut(igamcurve, igam, 32768.f, 65535.f); Color::gammanf2lut(igamcurve, igam, 32768.f, 65535.f);
} }
const float gain = std::pow(2.0, expcomp); const float gain = dnparams.autoGain ? static_cast<float>(std::pow(2.0, expcomp)) : 1.f;
const double params_Ldetail = std::min(dnparams.Ldetail, 99.9); // max out to avoid div by zero when using noisevar_Ldetail as divisor const double params_Ldetail = std::min(dnparams.Ldetail, 99.9); // max out to avoid div by zero when using noisevar_Ldetail as divisor
const float noisevar_Ldetail = SQR((SQR(100. - params_Ldetail) + 50.0 * (100.0 - params_Ldetail)) * TS * 0.5); const float noisevar_Ldetail = SQR((SQR(100. - params_Ldetail) + 50.0 * (100.0 - params_Ldetail)) * TS * 0.5);
@ -3287,7 +3287,7 @@ void ImProcFunctions::RGB_denoise_info(Imagefloat * src, Imagefloat * provicalc,
bool denoiseMethodRgb = (dnparams.dmethod == "RGB"); bool denoiseMethodRgb = (dnparams.dmethod == "RGB");
const float gain = pow(2.0f, float(expcomp)); const float gain = dnparams.autoGain ? pow(2.0f, float(expcomp)) : 1.f;
int tilesize = 0; int tilesize = 0;
int overlap = 0; int overlap = 0;

View File

@ -1699,6 +1699,7 @@ DirPyrDenoiseParams::DirPyrDenoiseParams() :
chroma(15), chroma(15),
redchro(0), redchro(0),
bluechro(0), bluechro(0),
autoGain(true),
gamma(1.7), gamma(1.7),
dmethod("Lab"), dmethod("Lab"),
Lmethod("SLI"), Lmethod("SLI"),
@ -1726,6 +1727,7 @@ bool DirPyrDenoiseParams::operator ==(const DirPyrDenoiseParams& other) const
&& chroma == other.chroma && chroma == other.chroma
&& redchro == other.redchro && redchro == other.redchro
&& bluechro == other.bluechro && bluechro == other.bluechro
&& autoGain == other.autoGain
&& gamma == other.gamma && gamma == other.gamma
&& dmethod == other.dmethod && dmethod == other.dmethod
&& Lmethod == other.Lmethod && Lmethod == other.Lmethod
@ -6334,6 +6336,7 @@ int ProcParams::save(const Glib::ustring& fname, const Glib::ustring& fname2, bo
saveToKeyfile(!pedited || pedited->dirpyrDenoise.methodmed, "Directional Pyramid Denoising", "MethodMed", dirpyrDenoise.methodmed, keyFile); saveToKeyfile(!pedited || pedited->dirpyrDenoise.methodmed, "Directional Pyramid Denoising", "MethodMed", dirpyrDenoise.methodmed, keyFile);
saveToKeyfile(!pedited || pedited->dirpyrDenoise.redchro, "Directional Pyramid Denoising", "Redchro", dirpyrDenoise.redchro, keyFile); saveToKeyfile(!pedited || pedited->dirpyrDenoise.redchro, "Directional Pyramid Denoising", "Redchro", dirpyrDenoise.redchro, keyFile);
saveToKeyfile(!pedited || pedited->dirpyrDenoise.bluechro, "Directional Pyramid Denoising", "Bluechro", dirpyrDenoise.bluechro, keyFile); saveToKeyfile(!pedited || pedited->dirpyrDenoise.bluechro, "Directional Pyramid Denoising", "Bluechro", dirpyrDenoise.bluechro, keyFile);
saveToKeyfile(!pedited || pedited->dirpyrDenoise.gain, "Directional Pyramid Denoising", "AutoGain", dirpyrDenoise.autoGain, keyFile);
saveToKeyfile(!pedited || pedited->dirpyrDenoise.gamma, "Directional Pyramid Denoising", "Gamma", dirpyrDenoise.gamma, keyFile); saveToKeyfile(!pedited || pedited->dirpyrDenoise.gamma, "Directional Pyramid Denoising", "Gamma", dirpyrDenoise.gamma, keyFile);
saveToKeyfile(!pedited || pedited->dirpyrDenoise.passes, "Directional Pyramid Denoising", "Passes", dirpyrDenoise.passes, keyFile); saveToKeyfile(!pedited || pedited->dirpyrDenoise.passes, "Directional Pyramid Denoising", "Passes", dirpyrDenoise.passes, keyFile);
saveToKeyfile(!pedited || pedited->dirpyrDenoise.lcurve, "Directional Pyramid Denoising", "LCurve", dirpyrDenoise.lcurve, keyFile); saveToKeyfile(!pedited || pedited->dirpyrDenoise.lcurve, "Directional Pyramid Denoising", "LCurve", dirpyrDenoise.lcurve, keyFile);
@ -8354,6 +8357,7 @@ int ProcParams::load(const Glib::ustring& fname, ParamsEdited* pedited)
assignFromKeyfile(keyFile, "Directional Pyramid Denoising", "Redchro", pedited, dirpyrDenoise.redchro, pedited->dirpyrDenoise.redchro); assignFromKeyfile(keyFile, "Directional Pyramid Denoising", "Redchro", pedited, dirpyrDenoise.redchro, pedited->dirpyrDenoise.redchro);
assignFromKeyfile(keyFile, "Directional Pyramid Denoising", "Bluechro", pedited, dirpyrDenoise.bluechro, pedited->dirpyrDenoise.bluechro); assignFromKeyfile(keyFile, "Directional Pyramid Denoising", "Bluechro", pedited, dirpyrDenoise.bluechro, pedited->dirpyrDenoise.bluechro);
assignFromKeyfile(keyFile, "Directional Pyramid Denoising", "AutoGain", pedited, dirpyrDenoise.autoGain, pedited->dirpyrDenoise.gain);
assignFromKeyfile(keyFile, "Directional Pyramid Denoising", "Gamma", pedited, dirpyrDenoise.gamma, pedited->dirpyrDenoise.gamma); assignFromKeyfile(keyFile, "Directional Pyramid Denoising", "Gamma", pedited, dirpyrDenoise.gamma, pedited->dirpyrDenoise.gamma);
assignFromKeyfile(keyFile, "Directional Pyramid Denoising", "Passes", pedited, dirpyrDenoise.passes, pedited->dirpyrDenoise.passes); assignFromKeyfile(keyFile, "Directional Pyramid Denoising", "Passes", pedited, dirpyrDenoise.passes, pedited->dirpyrDenoise.passes);
} }

View File

@ -776,6 +776,7 @@ struct DirPyrDenoiseParams {
double chroma; double chroma;
double redchro; double redchro;
double bluechro; double bluechro;
bool autoGain;
double gamma; double gamma;
Glib::ustring dmethod; Glib::ustring dmethod;
Glib::ustring Lmethod; Glib::ustring Lmethod;

View File

@ -1683,7 +1683,7 @@ void RawImageSource::preprocess (const RAWParams &raw, const LensProfParams &le
} }
} }
if (prepareDenoise && dirpyrdenoiseExpComp == RT_INFINITY) { if (prepareDenoise) {
LUTu aehist; LUTu aehist;
int aehistcompr; int aehistcompr;
double clip = 0; double clip = 0;

View File

@ -26,9 +26,11 @@
#include "editbuffer.h" #include "editbuffer.h"
#include "guiutils.h" #include "guiutils.h"
#include "options.h" #include "options.h"
#include "eventmapper.h"
#include "../rtengine/color.h" #include "../rtengine/color.h"
#include "../rtengine/procparams.h" #include "../rtengine/procparams.h"
#include "../rtengine/refreshmap.h"
using namespace rtengine; using namespace rtengine;
using namespace rtengine::procparams; using namespace rtengine::procparams;
@ -37,6 +39,9 @@ const Glib::ustring DirPyrDenoise::TOOL_NAME = "dirpyrdenoise";
DirPyrDenoise::DirPyrDenoise () : FoldableToolPanel(this, TOOL_NAME, M("TP_DIRPYRDENOISE_LABEL"), true, true), lastmedian(false) DirPyrDenoise::DirPyrDenoise () : FoldableToolPanel(this, TOOL_NAME, M("TP_DIRPYRDENOISE_LABEL"), true, true), lastmedian(false)
{ {
const auto procEventMapper = ProcEventMapper::getInstance();
EvDPDNGain = procEventMapper->newEvent(ALLNORAW, "HISTORY_MSG_DIRPYRDENOISE_GAIN");
std::vector<GradientMilestone> milestones; std::vector<GradientMilestone> milestones;
CurveListener::setMulti(true); CurveListener::setMulti(true);
nextnresid = 0.; nextnresid = 0.;
@ -229,6 +234,11 @@ DirPyrDenoise::DirPyrDenoise () : FoldableToolPanel(this, TOOL_NAME, M("TP_DIRPY
pack_start( *hb11, Gtk::PACK_SHRINK, 1); pack_start( *hb11, Gtk::PACK_SHRINK, 1);
smethodconn = smethod->signal_changed().connect ( sigc::mem_fun(*this, &DirPyrDenoise::smethodChanged) ); smethodconn = smethod->signal_changed().connect ( sigc::mem_fun(*this, &DirPyrDenoise::smethodChanged) );
autoGain = Gtk::manage(new CheckBox(M("TP_DIRPYRDENOISE_MAIN_AUTO_GAIN"), multiImage));
autoGain->set_tooltip_text(M("TP_DIRPYRDENOISE_MAIN_AUTO_GAIN_TOOLTIP"));
autoGain->setCheckBoxListener(this);
pack_start(*autoGain, Gtk::PACK_SHRINK, 0);
gamma = Gtk::manage (new Adjuster (M("TP_DIRPYRDENOISE_MAIN_GAMMA"), 1.0, 3.0, 0.01, 1.7)); gamma = Gtk::manage (new Adjuster (M("TP_DIRPYRDENOISE_MAIN_GAMMA"), 1.0, 3.0, 0.01, 1.7));
gamma->set_tooltip_text (M("TP_DIRPYRDENOISE_MAIN_GAMMA_TOOLTIP")); gamma->set_tooltip_text (M("TP_DIRPYRDENOISE_MAIN_GAMMA_TOOLTIP"));
gamma->setAdjusterListener (this); gamma->setAdjusterListener (this);
@ -570,6 +580,7 @@ void DirPyrDenoise::read (const ProcParams* pp, const ParamsEdited* pedited)
redchro->setEditedState (pedited->dirpyrDenoise.redchro ? Edited : UnEdited); redchro->setEditedState (pedited->dirpyrDenoise.redchro ? Edited : UnEdited);
bluechro->setEditedState (pedited->dirpyrDenoise.bluechro ? Edited : UnEdited); bluechro->setEditedState (pedited->dirpyrDenoise.bluechro ? Edited : UnEdited);
autoGain->set_inconsistent(!pedited->dirpyrDenoise.gain);
gamma->setEditedState (pedited->dirpyrDenoise.gamma ? Edited : UnEdited); gamma->setEditedState (pedited->dirpyrDenoise.gamma ? Edited : UnEdited);
passes->setEditedState (pedited->dirpyrDenoise.passes ? Edited : UnEdited); passes->setEditedState (pedited->dirpyrDenoise.passes ? Edited : UnEdited);
set_inconsistent (multiImage && !pedited->dirpyrDenoise.enabled); set_inconsistent (multiImage && !pedited->dirpyrDenoise.enabled);
@ -593,6 +604,7 @@ void DirPyrDenoise::read (const ProcParams* pp, const ParamsEdited* pedited)
redchro->setValue (pp->dirpyrDenoise.redchro); redchro->setValue (pp->dirpyrDenoise.redchro);
bluechro->setValue (pp->dirpyrDenoise.bluechro); bluechro->setValue (pp->dirpyrDenoise.bluechro);
autoGain->setValue(pp->dirpyrDenoise.autoGain);
gamma->setValue (pp->dirpyrDenoise.gamma); gamma->setValue (pp->dirpyrDenoise.gamma);
passes->setValue (pp->dirpyrDenoise.passes); passes->setValue (pp->dirpyrDenoise.passes);
lshape->setCurve (pp->dirpyrDenoise.lcurve); lshape->setCurve (pp->dirpyrDenoise.lcurve);
@ -631,6 +643,7 @@ void DirPyrDenoise::write (ProcParams* pp, ParamsEdited* pedited)
pp->dirpyrDenoise.chroma = chroma->getValue (); pp->dirpyrDenoise.chroma = chroma->getValue ();
pp->dirpyrDenoise.redchro = redchro->getValue (); pp->dirpyrDenoise.redchro = redchro->getValue ();
pp->dirpyrDenoise.bluechro = bluechro->getValue (); pp->dirpyrDenoise.bluechro = bluechro->getValue ();
pp->dirpyrDenoise.autoGain = autoGain->get_active();
pp->dirpyrDenoise.gamma = gamma->getValue (); pp->dirpyrDenoise.gamma = gamma->getValue ();
pp->dirpyrDenoise.passes = passes->getValue (); pp->dirpyrDenoise.passes = passes->getValue ();
pp->dirpyrDenoise.enabled = getEnabled(); pp->dirpyrDenoise.enabled = getEnabled();
@ -653,6 +666,7 @@ void DirPyrDenoise::write (ProcParams* pp, ParamsEdited* pedited)
pedited->dirpyrDenoise.chroma = chroma->getEditedState (); pedited->dirpyrDenoise.chroma = chroma->getEditedState ();
pedited->dirpyrDenoise.redchro = redchro->getEditedState (); pedited->dirpyrDenoise.redchro = redchro->getEditedState ();
pedited->dirpyrDenoise.bluechro = bluechro->getEditedState (); pedited->dirpyrDenoise.bluechro = bluechro->getEditedState ();
pedited->dirpyrDenoise.gain = !autoGain->get_inconsistent();
pedited->dirpyrDenoise.gamma = gamma->getEditedState (); pedited->dirpyrDenoise.gamma = gamma->getEditedState ();
pedited->dirpyrDenoise.passes = passes->getEditedState (); pedited->dirpyrDenoise.passes = passes->getEditedState ();
pedited->dirpyrDenoise.enabled = !get_inconsistent(); pedited->dirpyrDenoise.enabled = !get_inconsistent();
@ -992,6 +1006,13 @@ void DirPyrDenoise::adjusterChanged(Adjuster* a, double newval)
} }
} }
void DirPyrDenoise::checkBoxToggled(CheckBox* c, CheckValue newval)
{
if (c == autoGain) {
listener->panelChanged(EvDPDNGain, c->getValueAsStr());
}
}
void DirPyrDenoise::enabledChanged () void DirPyrDenoise::enabledChanged ()
{ {

View File

@ -21,6 +21,7 @@
#include <gtkmm.h> #include <gtkmm.h>
#include "adjuster.h" #include "adjuster.h"
#include "checkbox.h"
#include "colorprovider.h" #include "colorprovider.h"
#include "curvelistener.h" #include "curvelistener.h"
#include "guiutils.h" #include "guiutils.h"
@ -34,6 +35,7 @@ class EditDataProvider;
class DirPyrDenoise final : class DirPyrDenoise final :
public ToolParamBlock, public ToolParamBlock,
public AdjusterListener, public AdjusterListener,
public CheckBoxListener,
public FoldableToolPanel, public FoldableToolPanel,
public rtengine::AutoChromaListener, public rtengine::AutoChromaListener,
public CurveListener, public CurveListener,
@ -54,6 +56,7 @@ public:
void autoOpenCurve () override; void autoOpenCurve () override;
void adjusterChanged (Adjuster* a, double newval) override; void adjusterChanged (Adjuster* a, double newval) override;
void checkBoxToggled(CheckBox* c, CheckValue newval) override;
void enabledChanged () override; void enabledChanged () override;
void medianChanged (); void medianChanged ();
void chromaChanged (double autchroma, double autred, double autblue) override; void chromaChanged (double autchroma, double autred, double autblue) override;
@ -83,6 +86,7 @@ public:
Glib::ustring getSettingString (); Glib::ustring getSettingString ();
private: private:
rtengine::ProcEvent EvDPDNGain;
CurveEditorGroup* NoiscurveEditorG; CurveEditorGroup* NoiscurveEditorG;
CurveEditorGroup* CCcurveEditorG; CurveEditorGroup* CCcurveEditorG;
Adjuster* luma; Adjuster* luma;
@ -90,6 +94,7 @@ private:
Adjuster* chroma; Adjuster* chroma;
Adjuster* redchro; Adjuster* redchro;
Adjuster* bluechro; Adjuster* bluechro;
CheckBox* autoGain;
Adjuster* gamma; Adjuster* gamma;
Adjuster* passes; Adjuster* passes;
FlatCurveEditor* lshape; FlatCurveEditor* lshape;

View File

@ -301,6 +301,7 @@ void ParamsEdited::set(bool v)
dirpyrDenoise.chroma = v; dirpyrDenoise.chroma = v;
dirpyrDenoise.redchro = v; dirpyrDenoise.redchro = v;
dirpyrDenoise.bluechro = v; dirpyrDenoise.bluechro = v;
dirpyrDenoise.gain = v;
dirpyrDenoise.gamma = v; dirpyrDenoise.gamma = v;
dirpyrDenoise.passes = v; dirpyrDenoise.passes = v;
dirpyrDenoise.dmethod = v; dirpyrDenoise.dmethod = v;
@ -1020,6 +1021,7 @@ void ParamsEdited::initFrom(const std::vector<rtengine::procparams::ProcParams>&
dirpyrDenoise.chroma = dirpyrDenoise.chroma && p.dirpyrDenoise.chroma == other.dirpyrDenoise.chroma; dirpyrDenoise.chroma = dirpyrDenoise.chroma && p.dirpyrDenoise.chroma == other.dirpyrDenoise.chroma;
dirpyrDenoise.redchro = dirpyrDenoise.redchro && p.dirpyrDenoise.redchro == other.dirpyrDenoise.redchro; dirpyrDenoise.redchro = dirpyrDenoise.redchro && p.dirpyrDenoise.redchro == other.dirpyrDenoise.redchro;
dirpyrDenoise.bluechro = dirpyrDenoise.bluechro && p.dirpyrDenoise.bluechro == other.dirpyrDenoise.bluechro; dirpyrDenoise.bluechro = dirpyrDenoise.bluechro && p.dirpyrDenoise.bluechro == other.dirpyrDenoise.bluechro;
dirpyrDenoise.gain = dirpyrDenoise.gain && p.dirpyrDenoise.autoGain == other.dirpyrDenoise.autoGain;
dirpyrDenoise.gamma = dirpyrDenoise.gamma && p.dirpyrDenoise.gamma == other.dirpyrDenoise.gamma; dirpyrDenoise.gamma = dirpyrDenoise.gamma && p.dirpyrDenoise.gamma == other.dirpyrDenoise.gamma;
dirpyrDenoise.passes = dirpyrDenoise.passes && p.dirpyrDenoise.passes == other.dirpyrDenoise.passes; dirpyrDenoise.passes = dirpyrDenoise.passes && p.dirpyrDenoise.passes == other.dirpyrDenoise.passes;
dirpyrDenoise.dmethod = dirpyrDenoise.dmethod && p.dirpyrDenoise.dmethod == other.dirpyrDenoise.dmethod; dirpyrDenoise.dmethod = dirpyrDenoise.dmethod && p.dirpyrDenoise.dmethod == other.dirpyrDenoise.dmethod;
@ -3167,6 +3169,10 @@ void ParamsEdited::combine(rtengine::procparams::ProcParams& toEdit, const rteng
toEdit.dirpyrDenoise.bluechro = dontforceSet && options.baBehav[ADDSET_DIRPYRDN_CHROMABLUE] ? toEdit.dirpyrDenoise.bluechro + mods.dirpyrDenoise.bluechro : mods.dirpyrDenoise.bluechro; toEdit.dirpyrDenoise.bluechro = dontforceSet && options.baBehav[ADDSET_DIRPYRDN_CHROMABLUE] ? toEdit.dirpyrDenoise.bluechro + mods.dirpyrDenoise.bluechro : mods.dirpyrDenoise.bluechro;
} }
if (dirpyrDenoise.gain) {
toEdit.dirpyrDenoise.autoGain = mods.dirpyrDenoise.autoGain;
}
if (dirpyrDenoise.gamma) { if (dirpyrDenoise.gamma) {
toEdit.dirpyrDenoise.gamma = dontforceSet && options.baBehav[ADDSET_DIRPYRDN_GAMMA] ? toEdit.dirpyrDenoise.gamma + mods.dirpyrDenoise.gamma : mods.dirpyrDenoise.gamma; toEdit.dirpyrDenoise.gamma = dontforceSet && options.baBehav[ADDSET_DIRPYRDN_GAMMA] ? toEdit.dirpyrDenoise.gamma + mods.dirpyrDenoise.gamma : mods.dirpyrDenoise.gamma;
} }

View File

@ -330,6 +330,7 @@ struct DirPyrDenoiseParamsEdited {
bool chroma; bool chroma;
bool redchro; bool redchro;
bool bluechro; bool bluechro;
bool gain;
bool gamma; bool gamma;
bool lcurve; bool lcurve;
bool cccurve; bool cccurve;