add threshold detail denoise - thanks to Alberto

This commit is contained in:
Desmis 2019-10-12 18:14:39 +02:00
parent 82a590b439
commit fe10587741
12 changed files with 393 additions and 225 deletions

View File

@ -1002,6 +1002,7 @@ HISTORY_MSG_761;Local - SH Laplacian mask
HISTORY_MSG_762;Local - cbdl Laplacian mask
HISTORY_MSG_763;Local - Blur Laplacian mask
HISTORY_MSG_764;Local - Solve PDE Laplacian mask
HISTORY_MSG_765;Local - deNoise Detail threshold
HISTORY_MSG_CLAMPOOG;Clip out-of-gamut colors
HISTORY_MSG_COLORTONING_LABGRID_VALUE;CT - Color correction
HISTORY_MSG_COLORTONING_LABREGION_AB;CT - Color correction
@ -2182,11 +2183,12 @@ TP_LOCALLAB_NOISELUMFINE;Luminance fine 1 (Wav)
TP_LOCALLAB_NOISELUMFINEZERO;Luminance fine 0 (Wav)
TP_LOCALLAB_NOISELUMFINETWO;Luminance fine 2 (Wav)
TP_LOCALLAB_NOISELUMCOARSE;Luminance coarse (Wav)
TP_LOCALLAB_NOISELUMDETAIL;Luminance detail (DCT)
TP_LOCALLAB_NOISELUMDETAIL;Luminance detail recovery(DCT)
TP_LOCALLAB_NOISELEQUAL;Equalizer white-black
TP_LOCALLAB_NOISECHROFINE;Chroma fine (Wav)
TP_LOCALLAB_NOISECHROCOARSE;Chroma coarse (Wav)
TP_LOCALLAB_NOISECHRODETAIL;Chroma detail (DCT)
TP_LOCALLAB_NOISECHRODETAIL;Chroma detail recovery(DCT)
TP_LOCALLAB_DETAILTHR;Detail threshold Luminance Chroma (DCT)
TP_LOCALLAB_NOISECHROC_TOOLTIP;If superior to zero, high quality algorithm is enabled.\nCoarse is for slider >=2
TP_LOCALLAB_PREVIEWSEL;Preview selection deltaE
TP_LOCALLAB_PDEFRA;PDE IPOL - Contrast attenuator

View File

@ -30,6 +30,8 @@
#include "color.h"
#include "rt_math.h"
#include "jaggedarray.h"
#include "rt_algo.h"
#ifdef _OPENMP
#include <omp.h>
#endif
@ -298,6 +300,7 @@ struct local_params {
float noiself0;
float noiself2;
float noiseldetail;
int detailthr;
int noiselequal;
float noisechrodetail;
float bilat;
@ -593,6 +596,7 @@ static void calcLocalParams(int sp, int oW, int oH, const LocallabParams& locall
int local_noiselequal = locallab.spots.at(sp).noiselequal;
float local_noisechrodetail = (float)locallab.spots.at(sp).noisechrodetail;
int local_sensiden = locallab.spots.at(sp).sensiden;
float local_detailthr = (float)locallab.spots.at(sp).detailthr;
float local_noisecf = ((float)locallab.spots.at(sp).noisechrof) / 10.f;
float local_noisecc = ((float)locallab.spots.at(sp).noisechroc) / 10.f;
@ -832,6 +836,7 @@ static void calcLocalParams(int sp, int oW, int oH, const LocallabParams& locall
lp.noiself0 = local_noiself0;
lp.noiself2 = local_noiself2;
lp.noiseldetail = local_noiseldetail;
lp.detailthr = local_detailthr;
lp.noiselequal = local_noiselequal;
lp.noisechrodetail = local_noisechrodetail;
lp.noiselc = local_noiselc;
@ -5256,6 +5261,7 @@ void ImProcFunctions::fftw_denoise(int GW, int GH, int max_numblox_W, int min_nu
float *Lbloxtmp = reinterpret_cast<float*>(fftwf_malloc(max_numblox_W * TS * TS * sizeof(float)));
float *fLbloxtmp = reinterpret_cast<float*>(fftwf_malloc(max_numblox_W * TS * TS * sizeof(float)));
float params_Ldetail = 0.f;
int nfwd[2] = {TS, TS};
@ -5393,7 +5399,7 @@ void ImProcFunctions::fftw_denoise(int GW, int GH, int max_numblox_W, int min_nu
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
// now process the vblk row of blocks for noise reduction
float params_Ldetail = 0.f;
// float params_Ldetail = 0.f;
float noisevar_Ldetail = 1.f;
if (chrom == 0) {
@ -5434,6 +5440,34 @@ void ImProcFunctions::fftw_denoise(int GW, int GH, int max_numblox_W, int min_nu
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
}
//Threshold DCT from Alberto Grigio
const int detail_thresh = lp.detailthr;
array2D<float> mask;
float scalea = 1.f;
if (detail_thresh > 0) {
mask(GW, GH);
float thr = log2lin(float(detail_thresh) / 200.f, 100.f);
buildBlendMask(tmp1, mask, GW, GH, thr);
float r = 20.f / scalea;
if (r > 0) {
float **m = mask;
gaussianBlur(m, m, GW, GH, r);
}
array2D<float> m2(GW, GH);
const float alfa = 0.856f;
const float beta = 1.f + std::sqrt(log2lin(thr, 100.f));
buildGradientsMask(GW, GH, tmp1, m2, params_Ldetail / 100.f, 7, 3, alfa, beta, multiThread);
for (int i = 0; i < GH; ++i) {
for (int j = 0; j < GW; ++j) {
mask[i][j] *= m2[i][j];
}
}
}
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
#ifdef _OPENMP
@ -5442,11 +5476,20 @@ void ImProcFunctions::fftw_denoise(int GW, int GH, int max_numblox_W, int min_nu
for (int i = 0; i < GH; ++i) {
for (int j = 0; j < GW; ++j) {
float d = Ldetail[i][j] / totwt[i][j];
if (detail_thresh > 0) {
d *= mask[i][j];
}
//may want to include masking threshold for large hipass data to preserve edges/detail
tmp1[i][j] += Ldetail[i][j] / totwt[i][j]; //note that labdn initially stores the denoised hipass data
tmp1[i][j] += d;
}
}
mask.free();
//end Threshold DCT
delete Lin;

View File

@ -791,6 +791,7 @@ enum ProcEventCode {
Evlocallablapmaskcb = 761,
Evlocallablapmaskbl = 762,
Evlocallablaplac = 763,
Evlocallabdetailthr = 764,
NUMOFEVENTS
};

View File

@ -2670,14 +2670,15 @@ LocallabParams::LocallabSpot::LocallabSpot() :
noiselumf0(0),
noiselumf2(0),
noiselumc(0),
noiselumdetail(80),
noiselumdetail(0),
noiselequal(7),
noisechrof(0),
noisechroc(0),
noisechrodetail(80),
noisechrodetail(0),
adjblur(0),
bilateral(0),
sensiden(20)
sensiden(20),
detailthr(0)
{
}
@ -2963,7 +2964,8 @@ bool LocallabParams::LocallabSpot::operator ==(const LocallabSpot& other) const
&& noisechrodetail == other.noisechrodetail
&& adjblur == other.adjblur
&& bilateral == other.bilateral
&& sensiden == other.sensiden;
&& sensiden == other.sensiden
&& detailthr == other.detailthr;
}
bool LocallabParams::LocallabSpot::operator !=(const LocallabSpot& other) const
@ -4222,6 +4224,7 @@ int ProcParams::save(const Glib::ustring& fname, const Glib::ustring& fname2, bo
saveToKeyfile(!pedited || pedited->locallab.spots.at(i).adjblur, "Locallab", "Adjblur_" + std::to_string(i), spot.adjblur, keyFile);
saveToKeyfile(!pedited || pedited->locallab.spots.at(i).bilateral, "Locallab", "Bilateral_" + std::to_string(i), spot.bilateral, keyFile);
saveToKeyfile(!pedited || pedited->locallab.spots.at(i).sensiden, "Locallab", "Sensiden_" + std::to_string(i), spot.sensiden, keyFile);
saveToKeyfile(!pedited || pedited->locallab.spots.at(i).detailthr, "Locallab", "Detailthr_" + std::to_string(i), spot.detailthr, keyFile);
}
}
@ -5612,6 +5615,7 @@ int ProcParams::load(const Glib::ustring& fname, ParamsEdited* pedited)
assignFromKeyfile(keyFile, "Locallab", "Adjblur_" + std::to_string(i), pedited, spot.adjblur, spotEdited.adjblur);
assignFromKeyfile(keyFile, "Locallab", "Bilateral_" + std::to_string(i), pedited, spot.bilateral, spotEdited.bilateral);
assignFromKeyfile(keyFile, "Locallab", "Sensiden_" + std::to_string(i), pedited, spot.sensiden, spotEdited.sensiden);
assignFromKeyfile(keyFile, "Locallab", "Detailthr_" + std::to_string(i), pedited, spot.detailthr, spotEdited.detailthr);
locallab.spots.at(i) = spot;

View File

@ -1227,6 +1227,7 @@ struct LocallabParams {
int adjblur;
int bilateral;
int sensiden;
int detailthr;
LocallabSpot();

View File

@ -790,7 +790,8 @@ int refreshmap[rtengine::NUMOFEVENTS] = {
LUMINANCECURVE, //EvlocallablapmaskSH
LUMINANCECURVE, //Evlocallablapmaskcb
LUMINANCECURVE, //Evlocallablapmaskbl
LUMINANCECURVE //Evlocallablaplac
LUMINANCECURVE, //Evlocallablaplac
LUMINANCECURVE //Evlocallabdetailthr
};
namespace rtengine

View File

@ -25,4 +25,8 @@ namespace rtengine
{
void findMinMaxPercentile(const float* data, size_t size, float minPrct, float& minOut, float maxPrct, float& maxOut, bool multiThread = true);
void buildBlendMask(const float* const * luminance, float **blend, int W, int H, float &contrastThreshold, float amount = 1.f, bool autoContrast = false, float ** clipmask = nullptr);
// implemented in tmo_fattal02
void buildGradientsMask(int W, int H, float **luminance, float **out,
float amount, int nlevels, int detail_level,
float alfa, float beta, bool multithread);
}

View File

@ -97,6 +97,8 @@ class Array2Df: public array2D<float>
public:
Array2Df(): Super() {}
Array2Df(int w, int h): Super(w, h) {}
Array2Df(int w, int h, float **data):
Super(w, h, data, ARRAY2D_BYREFERENCE) {}
float &operator()(int w, int h)
{
@ -364,6 +366,7 @@ void calculateFiMatrix (Array2Df* FI, Array2Df* gradients[],
#ifdef _OPENMP
#pragma omp parallel for shared(fi) if(multithread)
#endif
for (int k = 0 ; k < width * height ; k++) {
(*fi[nlevels - 1])(k) = 1.0f;
}
@ -378,6 +381,7 @@ void calculateFiMatrix (Array2Df* FI, Array2Df* gradients[],
#ifdef _OPENMP
#pragma omp parallel for shared(fi,avgGrad) if(multithread)
#endif
for (int y = 0; y < height; y++) {
for (int x = 0; x < width; x++) {
float grad = ((*gradients[k])(x, y) < 1e-4f) ? 1e-4 : (*gradients[k])(x, y);
@ -555,9 +559,11 @@ void tmo_fattal02 (size_t width,
for (int k = 0 ; k < nlevels ; k++) {
gradients[k] = new Array2Df(pyramids[k]->getCols(), pyramids[k]->getRows());
avgGrad[k] = calculateGradients(pyramids[k], gradients[k], k, multithread);
if(k != 0) // pyramids[0] is H. Will be deleted later
if (k != 0) { // pyramids[0] is H. Will be deleted later
delete pyramids[k];
}
}
// calculate fi matrix
@ -1044,6 +1050,8 @@ inline int find_fast_dim (int dim)
return dim;
}
} // namespace
@ -1052,6 +1060,7 @@ void ImProcFunctions::ToneMapFattal02 (Imagefloat *rgb, const FattalToneMappingP
if (!fatParams.enabled) {
return;
}
BENCHFUN
// const int detail_level = 3;
@ -1084,6 +1093,7 @@ void ImProcFunctions::ToneMapFattal02 (Imagefloat *rgb, const FattalToneMappingP
#ifdef _OPENMP
#pragma omp parallel for if(multiThread)
#endif
for (int y = 0; y < h; y++) {
for (int x = 0; x < w; x++) {
Yr(x, y) = std::max(luminance(rgb->r(y, x), rgb->g(y, x), rgb->b(y, x), ws), min_luminance); // clip really black pixels
@ -1126,6 +1136,7 @@ void ImProcFunctions::ToneMapFattal02 (Imagefloat *rgb, const FattalToneMappingP
std::cout << "ToneMapFattal02: alpha = " << alpha << ", beta = " << beta
<< ", detail_level = " << detail_level << std::endl;
}
rescale_nearest(Yr, L, multiThread);
tmo_fattal02(w2, h2, L, L, alpha, beta, noise, detail_level, multiThread);
@ -1140,6 +1151,7 @@ void ImProcFunctions::ToneMapFattal02 (Imagefloat *rgb, const FattalToneMappingP
#ifdef _OPENMP
#pragma omp parallel for schedule(dynamic,16) if(multiThread)
#endif
for (int y = 0; y < h; y++) {
int yy = y * hr + 1;
@ -1160,5 +1172,77 @@ void ImProcFunctions::ToneMapFattal02 (Imagefloat *rgb, const FattalToneMappingP
}
void buildGradientsMask(int W, int H, float **luminance, float **out,
float amount, int nlevels, int detail_level,
float alfa, float beta, bool multithread)
{
Array2Df Y(W, H, luminance);
const float noise = alfa * 0.01f;
Array2Df *pyramids[nlevels];
pyramids[0] = &Y;
createGaussianPyramids(pyramids, nlevels, multithread);
// calculate gradients and its average values on pyramid levels
Array2Df *gradients[nlevels];
float avgGrad[nlevels];
for (int k = 0 ; k < nlevels ; k++) {
gradients[k] = new Array2Df(pyramids[k]->getCols(), pyramids[k]->getRows());
avgGrad[k] = calculateGradients(pyramids[k], gradients[k], k, multithread);
if (k != 0) { // pyramids[0] is Y
delete pyramids[k];
}
}
// calculate fi matrix
Array2Df FI(W, H, out);
calculateFiMatrix(&FI, gradients, avgGrad, nlevels, detail_level, alfa, beta, noise, multithread);
for (int i = 0 ; i < nlevels ; i++) {
delete gradients[i];
}
// rescale the mask
float m = out[0][0];
#ifdef _OPENMP
# pragma omp parallel for reduction(max:m) if (multithread)
#endif
for (int y = 0; y < H; ++y) {
for (int x = 0; x < W; ++x) {
float v = std::abs(out[y][x]);
out[y][x] = v;
m = std::max(v, m);
}
}
if (m > 0.f) {
const float f = amount / m;
#ifdef _OPENMP
# pragma omp parallel for reduction(max:m) if (multithread)
#endif
for (int y = 0; y < H; ++y) {
for (int x = 0; x < W; ++x) {
out[y][x] *= f;
}
}
}
// {
// Imagefloat tmp(W, H);
// for (int y = 0; y < H; ++y) {
// for (int x = 0; x < W; ++x) {
// tmp.r(y, x) = tmp.g(y, x) = tmp.b(y, x) = out[y][x] * 65535.f;
// }
// }
// std::ostringstream name;
// name << "/tmp/FI-" << W << "x" << H << ".tif";
// tmp.saveAsTIFF(name.str(), 16);
// }
}
} // namespace rtengine

View File

@ -331,14 +331,15 @@ Locallab::Locallab():
noiselumf0(Gtk::manage(new Adjuster(M("TP_LOCALLAB_NOISELUMFINEZERO"), MINCHRO, MAXCHRO, 1, 0))),
noiselumf2(Gtk::manage(new Adjuster(M("TP_LOCALLAB_NOISELUMFINETWO"), MINCHRO, MAXCHRO, 1, 0))),
noiselumc(Gtk::manage(new Adjuster(M("TP_LOCALLAB_NOISELUMCOARSE"), MINCHRO, MAXCHROCC, 1, 0))),
noiselumdetail(Gtk::manage(new Adjuster(M("TP_LOCALLAB_NOISELUMDETAIL"), 0, 100, 1, 80))),
noiselumdetail(Gtk::manage(new Adjuster(M("TP_LOCALLAB_NOISELUMDETAIL"), 0, 100, 1, 0))),
noiselequal(Gtk::manage(new Adjuster(M("TP_LOCALLAB_NOISELEQUAL"), -2, 10, 1, 7, Gtk::manage(new RTImage("circle-white-small.png")), Gtk::manage(new RTImage("circle-black-small.png"))))),
noisechrof(Gtk::manage(new Adjuster(M("TP_LOCALLAB_NOISECHROFINE"), MINCHRO, MAXCHRO, 1, 0))),
noisechroc(Gtk::manage(new Adjuster(M("TP_LOCALLAB_NOISECHROCOARSE"), MINCHRO, MAXCHROCC, 1, 0))),
noisechrodetail(Gtk::manage(new Adjuster(M("TP_LOCALLAB_NOISECHRODETAIL"), 0, 100, 1, 80))),
noisechrodetail(Gtk::manage(new Adjuster(M("TP_LOCALLAB_NOISECHRODETAIL"), 0, 100, 1, 0))),
adjblur(Gtk::manage(new Adjuster(M("TP_LOCALLAB_ADJ"), -100., 100., 1., 0., Gtk::manage(new RTImage("circle-blue-small.png")), Gtk::manage(new RTImage("circle-red-small.png"))))),
bilateral(Gtk::manage(new Adjuster(M("TP_LOCALLAB_BILATERAL"), 0, 100, 1, 0))),
sensiden(Gtk::manage(new Adjuster(M("TP_LOCALLAB_SENSIDEN"), 0, 100, 1, 20))),
detailthr(Gtk::manage(new Adjuster(M("TP_LOCALLAB_DETAILTHR"), 0, 100, 1, 0))),
// ButtonCheck widgets
// Color & Light
@ -2122,7 +2123,7 @@ Locallab::Locallab():
noiselumdetail->setAdjusterListener(this);
if (showtooltip) {
noiselumdetail->set_tooltip_text(M("TP_LOCALLAB_NOISEDETAIL_TOOLTIP"));
// noiselumdetail->set_tooltip_text(M("TP_LOCALLAB_NOISEDETAIL_TOOLTIP"));
}
noiselequal->setAdjusterListener(this);
@ -2138,7 +2139,7 @@ Locallab::Locallab():
noisechrodetail->setAdjusterListener(this);
if (showtooltip) {
noisechrodetail->set_tooltip_text(M("TP_LOCALLAB_NOISEDETAIL_TOOLTIP"));
// noisechrodetail->set_tooltip_text(M("TP_LOCALLAB_NOISEDETAIL_TOOLTIP"));
}
adjblur->setAdjusterListener(this);
@ -2146,6 +2147,7 @@ Locallab::Locallab():
bilateral->setAdjusterListener(this);
sensiden->setAdjusterListener(this);
detailthr->setAdjusterListener(this);
ToolParamBlock* const denoisBox = Gtk::manage(new ToolParamBlock());
Gtk::Frame* const wavFrame = Gtk::manage(new Gtk::Frame());
@ -2158,7 +2160,8 @@ Locallab::Locallab():
wavBox->pack_start(*noiselequal);
wavBox->pack_start(*noisechrof);
wavBox->pack_start(*noisechroc);
wavBox->pack_start(*noisechrodetail); // Uncomment this line to use the noisechrodetail adjuster
wavBox->pack_start(*noisechrodetail);
wavBox->pack_start(*detailthr);
wavBox->pack_start(*adjblur);
wavFrame->add(*wavBox);
denoisBox->pack_start(*wavFrame);
@ -3387,6 +3390,7 @@ void Locallab::write(ProcParams* pp, ParamsEdited* pedited)
pp->locallab.spots.at(pp->locallab.selspot).adjblur = adjblur->getIntValue();
pp->locallab.spots.at(pp->locallab.selspot).bilateral = bilateral->getIntValue();
pp->locallab.spots.at(pp->locallab.selspot).sensiden = sensiden->getIntValue();
pp->locallab.spots.at(pp->locallab.selspot).detailthr = detailthr->getIntValue();
}
ControlSpotPanel::SpotEdited* const se = expsettings->getEditedStates();
@ -3666,6 +3670,7 @@ void Locallab::write(ProcParams* pp, ParamsEdited* pedited)
pe->locallab.spots.at(pp->locallab.selspot).adjblur = pe->locallab.spots.at(pp->locallab.selspot).adjblur || adjblur->getEditedState();
pe->locallab.spots.at(pp->locallab.selspot).bilateral = pe->locallab.spots.at(pp->locallab.selspot).bilateral || bilateral->getEditedState();
pe->locallab.spots.at(pp->locallab.selspot).sensiden = pe->locallab.spots.at(pp->locallab.selspot).sensiden || sensiden->getEditedState();
pe->locallab.spots.at(pp->locallab.selspot).detailthr = pe->locallab.spots.at(pp->locallab.selspot).detailthr || detailthr->getEditedState();
}
}
@ -3948,6 +3953,7 @@ void Locallab::write(ProcParams* pp, ParamsEdited* pedited)
pedited->locallab.spots.at(pp->locallab.selspot).adjblur = pedited->locallab.spots.at(pp->locallab.selspot).adjblur || adjblur->getEditedState();
pedited->locallab.spots.at(pp->locallab.selspot).bilateral = pedited->locallab.spots.at(pp->locallab.selspot).bilateral || bilateral->getEditedState();
pedited->locallab.spots.at(pp->locallab.selspot).sensiden = pedited->locallab.spots.at(pp->locallab.selspot).sensiden || sensiden->getEditedState();
pedited->locallab.spots.at(pp->locallab.selspot).detailthr = pedited->locallab.spots.at(pp->locallab.selspot).detailthr || detailthr->getEditedState();
}
}
}
@ -5742,6 +5748,7 @@ void Locallab::setDefaults(const ProcParams * defParams, const ParamsEdited * pe
adjblur->setDefault((double)defSpot->adjblur);
bilateral->setDefault((double)defSpot->bilateral);
sensiden->setDefault((double)defSpot->sensiden);
detailthr->setDefault((double)defSpot->detailthr);
// Set default edited states for adjusters and threshold adjusters
if (!pedited) {
@ -5914,6 +5921,7 @@ void Locallab::setDefaults(const ProcParams * defParams, const ParamsEdited * pe
adjblur->setDefaultEditedState(Irrelevant);
bilateral->setDefaultEditedState(Irrelevant);
sensiden->setDefaultEditedState(Irrelevant);
detailthr->setDefaultEditedState(Irrelevant);
} else {
const LocallabParamsEdited::LocallabSpotEdited* defSpotState = new LocallabParamsEdited::LocallabSpotEdited(true);
@ -6091,6 +6099,7 @@ void Locallab::setDefaults(const ProcParams * defParams, const ParamsEdited * pe
adjblur->setDefaultEditedState(defSpotState->adjblur ? Edited : UnEdited);
bilateral->setDefaultEditedState(defSpotState->bilateral ? Edited : UnEdited);
sensiden->setDefaultEditedState(defSpotState->sensiden ? Edited : UnEdited);
detailthr->setDefaultEditedState(defSpotState->detailthr ? Edited : UnEdited);
}
}
@ -7130,6 +7139,13 @@ void Locallab::adjusterChanged(Adjuster * a, double newval)
listener->panelChanged(Evlocallabsensiden, sensiden->getTextValue());
}
}
if (a == detailthr) {
if (listener) {
listener->panelChanged(Evlocallabdetailthr, detailthr->getTextValue());
}
}
}
}
@ -7327,6 +7343,7 @@ void Locallab::setBatchMode(bool batchMode)
adjblur->showEditedCB();
bilateral->showEditedCB();
sensiden->showEditedCB();
detailthr->showEditedCB();
// Set batch mode for comboBoxText
// Color & Light
@ -7997,6 +8014,7 @@ void Locallab::updateLocallabGUI(const rtengine::procparams::ProcParams* pp, con
adjblur->setValue(pp->locallab.spots.at(index).adjblur);
bilateral->setValue(pp->locallab.spots.at(index).bilateral);
sensiden->setValue(pp->locallab.spots.at(index).sensiden);
detailthr->setValue(pp->locallab.spots.at(index).detailthr);
if (pedited) {
if (index < (int)pedited->locallab.spots.size()) {
@ -8329,6 +8347,7 @@ void Locallab::updateLocallabGUI(const rtengine::procparams::ProcParams* pp, con
adjblur->setEditedState(spotState->adjblur ? Edited : UnEdited);
bilateral->setEditedState(spotState->bilateral ? Edited : UnEdited);
sensiden->setEditedState(spotState->sensiden ? Edited : UnEdited);
detailthr->setEditedState(spotState->detailthr ? Edited : UnEdited);
}
}
}

View File

@ -291,6 +291,7 @@ private:
Adjuster* const adjblur;
Adjuster* const bilateral;
Adjuster* const sensiden;
Adjuster* const detailthr;
// ButtonCheck widgets
// Color & Light

View File

@ -1223,6 +1223,7 @@ void ParamsEdited::initFrom(const std::vector<rtengine::procparams::ProcParams>&
locallab.spots.at(j).adjblur = locallab.spots.at(j).adjblur && pSpot.adjblur == otherSpot.adjblur;
locallab.spots.at(j).bilateral = locallab.spots.at(j).bilateral && pSpot.bilateral == otherSpot.bilateral;
locallab.spots.at(j).sensiden = locallab.spots.at(j).sensiden && pSpot.sensiden == otherSpot.sensiden;
locallab.spots.at(j).detailthr = locallab.spots.at(j).detailthr && pSpot.detailthr == otherSpot.detailthr;
}
}
@ -3724,6 +3725,10 @@ void ParamsEdited::combine(rtengine::procparams::ProcParams& toEdit, const rteng
if (locallab.spots.at(i).sensiden) {
toEdit.locallab.spots.at(i).sensiden = mods.locallab.spots.at(i).sensiden;
}
if (locallab.spots.at(i).detailthr) {
toEdit.locallab.spots.at(i).detailthr = mods.locallab.spots.at(i).detailthr;
}
}
@ -4961,7 +4966,8 @@ LocallabParamsEdited::LocallabSpotEdited::LocallabSpotEdited(bool v) :
noisechrodetail(v),
adjblur(v),
bilateral(v),
sensiden(v)
sensiden(v),
detailthr(v)
{
}
@ -5240,6 +5246,7 @@ void LocallabParamsEdited::LocallabSpotEdited::set(bool v)
adjblur = v;
bilateral = v;
sensiden = v;
detailthr = v;
}
bool CaptureSharpeningParamsEdited::isUnchanged() const

View File

@ -638,6 +638,7 @@ public:
bool adjblur;
bool bilateral;
bool sensiden;
bool detailthr;
LocallabSpotEdited(bool v);