From 5162484517b9711dc4e274f8bae8f514bc617f0b Mon Sep 17 00:00:00 2001 From: heckflosse Date: Sat, 8 Dec 2018 21:57:56 +0100 Subject: [PATCH] First quick&dirty version of flat region blur, #5075 --- rtdata/languages/default | 2 ++ rtengine/ipsharpen.cc | 42 ++++++++++++++++++++++++++++++++++++++-- rtengine/procparams.cc | 4 ++++ rtengine/procparams.h | 1 + rtgui/paramsedited.cc | 6 ++++++ rtgui/paramsedited.h | 1 + rtgui/sharpening.cc | 20 +++++++++++++++++-- rtgui/sharpening.h | 2 ++ 8 files changed, 74 insertions(+), 4 deletions(-) diff --git a/rtdata/languages/default b/rtdata/languages/default index da79ec3ac..ae75bc343 100644 --- a/rtdata/languages/default +++ b/rtdata/languages/default @@ -774,6 +774,7 @@ HISTORY_MSG_RAWCACORR_AUTOIT;Raw CA Correction - Iterations HISTORY_MSG_RAWCACORR_COLORSHIFT;Raw CA Correction - Avoid color shift HISTORY_MSG_RAW_BORDER;Raw border HISTORY_MSG_RESIZE_ALLOWUPSCALING;Resize - Allow upscaling +HISTORY_MSG_SHARPENING_BLUR;Sharpening - Blur radius HISTORY_MSG_SHARPENING_CONTRAST;Sharpening - Contrast threshold HISTORY_MSG_SH_COLORSPACE;S/H - Colorspace HISTORY_MSG_SOFTLIGHT_ENABLED;Soft light @@ -2034,6 +2035,7 @@ TP_SHARPENEDGE_LABEL;Edges TP_SHARPENEDGE_PASSES;Iterations TP_SHARPENEDGE_THREE;Luminance only TP_SHARPENING_AMOUNT;Amount +TP_SHARPENING_BLUR;Blur radius TP_SHARPENING_CONTRAST;Contrast threshold TP_SHARPENING_EDRADIUS;Radius TP_SHARPENING_EDTOLERANCE;Edge tolerance diff --git a/rtengine/ipsharpen.cc b/rtengine/ipsharpen.cc index 321dd635f..002337b2f 100644 --- a/rtengine/ipsharpen.cc +++ b/rtengine/ipsharpen.cc @@ -159,7 +159,7 @@ extern const Settings* settings; void ImProcFunctions::deconvsharpening (float** luminance, float** tmp, int W, int H, const SharpeningParams &sharpenParam) { - if (sharpenParam.deconvamount < 1) { + if (sharpenParam.deconvamount == 0) { return; } BENCHFUN @@ -178,7 +178,14 @@ BENCHFUN JaggedArray blend(W, H); float contrast = sharpenParam.contrast / 100.f; buildBlendMask(luminance, blend, W, H, contrast, sharpenParam.deconvamount / 100.f); + JaggedArray blur(W, H); + if(sharpenParam.blurradius > 0) { + #pragma omp parallel + { + gaussianBlur(tmpI, blur, W, H, sharpenParam.blurradius); + } + } const float damping = sharpenParam.deconvdamping / 5.0; const bool needdamp = sharpenParam.deconvdamping > 0; const double sigma = sharpenParam.deconvradius / scale; @@ -208,6 +215,17 @@ BENCHFUN luminance[i][j] = intp(blend[i][j], max(tmpI[i][j], 0.0f), luminance[i][j]); } } + + if(sharpenParam.blurradius > 0) { +#ifdef _OPENMP + #pragma omp for +#endif + for (int i = 0; i < H; ++i) { + for (int j = 0; j < W; ++j) { + luminance[i][j] = intp(blend[i][j], luminance[i][j], max(blur[i][j], 0.0f)); + } + } + } } // end parallel } @@ -224,7 +242,7 @@ void ImProcFunctions::sharpening (LabImage* lab, const SharpeningParams &sharpen // calculate contrast based blend factors to reduce sharpening in regions with low contrast JaggedArray blend(W, H); float contrast = sharpenParam.contrast / 100.f; - buildBlendMask(lab->L, blend, W, H, contrast, sharpenParam.method == "rld" ? sharpenParam.deconvamount / 100.f : 1.f); + buildBlendMask(lab->L, blend, W, H, contrast, sharpenParam.method == "rld" ? 1.f : 1.f); #ifdef _OPENMP #pragma omp parallel for #endif @@ -256,6 +274,15 @@ BENCHFUN } } + JaggedArray blur(W, H); + + if(sharpenParam.blurradius > 0) { + #pragma omp parallel + { + gaussianBlur(lab->L, blur, W, H, sharpenParam.blurradius); + } + } + // calculate contrast based blend factors to reduce sharpening in regions with low contrast JaggedArray blend(W, H); float contrast = sharpenParam.contrast / 100.f; @@ -322,6 +349,17 @@ BENCHFUN delete [] b3; } + if(sharpenParam.blurradius > 0) { +#ifdef _OPENMP + #pragma omp parallel for +#endif + for (int i = 0; i < H; ++i) { + for (int j = 0; j < W; ++j) { + lab->L[i][j] = intp(blend[i][j], lab->L[i][j], max(blur[i][j], 0.0f)); + } + } + } + } // To the extent possible under law, Manuel Llorens diff --git a/rtengine/procparams.cc b/rtengine/procparams.cc index 9addfdce9..7ce7b8608 100644 --- a/rtengine/procparams.cc +++ b/rtengine/procparams.cc @@ -1079,6 +1079,7 @@ void ColorToningParams::getCurves(ColorGradientCurve& colorCurveLUT, OpacityCurv SharpeningParams::SharpeningParams() : enabled(false), contrast(20.0), + blurradius(0.2), radius(0.5), amount(200), threshold(20, 80, 2000, 1200, false), @@ -1100,6 +1101,7 @@ bool SharpeningParams::operator ==(const SharpeningParams& other) const return enabled == other.enabled && contrast == other.contrast + && blurradius == other.blurradius && radius == other.radius && amount == other.amount && threshold == other.threshold @@ -3022,6 +3024,7 @@ int ProcParams::save(const Glib::ustring& fname, const Glib::ustring& fname2, bo saveToKeyfile(!pedited || pedited->sharpening.contrast, "Sharpening", "Contrast", sharpening.contrast, keyFile); saveToKeyfile(!pedited || pedited->sharpening.method, "Sharpening", "Method", sharpening.method, keyFile); saveToKeyfile(!pedited || pedited->sharpening.radius, "Sharpening", "Radius", sharpening.radius, keyFile); + saveToKeyfile(!pedited || pedited->sharpening.blurradius, "Sharpening", "BlurRadius", sharpening.blurradius, keyFile); saveToKeyfile(!pedited || pedited->sharpening.amount, "Sharpening", "Amount", sharpening.amount, keyFile); saveToKeyfile(!pedited || pedited->sharpening.threshold, "Sharpening", "Threshold", sharpening.threshold.toVector(), keyFile); saveToKeyfile(!pedited || pedited->sharpening.edgesonly, "Sharpening", "OnlyEdges", sharpening.edgesonly, keyFile); @@ -3908,6 +3911,7 @@ int ProcParams::load(const Glib::ustring& fname, ParamsEdited* pedited) } } assignFromKeyfile(keyFile, "Sharpening", "Radius", pedited, sharpening.radius, pedited->sharpening.radius); + assignFromKeyfile(keyFile, "Sharpening", "BlurRadius", pedited, sharpening.blurradius, pedited->sharpening.blurradius); assignFromKeyfile(keyFile, "Sharpening", "Amount", pedited, sharpening.amount, pedited->sharpening.amount); if (keyFile.has_key("Sharpening", "Threshold")) { diff --git a/rtengine/procparams.h b/rtengine/procparams.h index 79f3fc7ec..d1b70b9c2 100644 --- a/rtengine/procparams.h +++ b/rtengine/procparams.h @@ -493,6 +493,7 @@ struct ColorToningParams { struct SharpeningParams { bool enabled; double contrast; + double blurradius; double radius; int amount; Threshold threshold; diff --git a/rtgui/paramsedited.cc b/rtgui/paramsedited.cc index 27b06c4f7..7f44c7738 100644 --- a/rtgui/paramsedited.cc +++ b/rtgui/paramsedited.cc @@ -147,6 +147,7 @@ void ParamsEdited::set(bool v) sharpening.enabled = v; sharpening.contrast = v; sharpening.radius = v; + sharpening.blurradius = v; sharpening.amount = v; sharpening.threshold = v; sharpening.edgesonly = v; @@ -719,6 +720,7 @@ void ParamsEdited::initFrom(const std::vector& sharpening.enabled = sharpening.enabled && p.sharpening.enabled == other.sharpening.enabled; sharpening.contrast = sharpening.contrast && p.sharpening.contrast == other.sharpening.contrast; sharpening.radius = sharpening.radius && p.sharpening.radius == other.sharpening.radius; + sharpening.blurradius = sharpening.blurradius && p.sharpening.blurradius == other.sharpening.blurradius; sharpening.amount = sharpening.amount && p.sharpening.amount == other.sharpening.amount; sharpening.threshold = sharpening.threshold && p.sharpening.threshold == other.sharpening.threshold; sharpening.edgesonly = sharpening.edgesonly && p.sharpening.edgesonly == other.sharpening.edgesonly; @@ -1639,6 +1641,10 @@ void ParamsEdited::combine(rtengine::procparams::ProcParams& toEdit, const rteng toEdit.sharpening.radius = dontforceSet && options.baBehav[ADDSET_SHARP_RADIUS] ? toEdit.sharpening.radius + mods.sharpening.radius : mods.sharpening.radius; } + if (sharpening.blurradius) { + toEdit.sharpening.blurradius = dontforceSet && options.baBehav[ADDSET_SHARP_RADIUS] ? toEdit.sharpening.blurradius + mods.sharpening.blurradius : mods.sharpening.blurradius; + } + if (sharpening.amount) { toEdit.sharpening.amount = dontforceSet && options.baBehav[ADDSET_SHARP_AMOUNT] ? toEdit.sharpening.amount + mods.sharpening.amount : mods.sharpening.amount; } diff --git a/rtgui/paramsedited.h b/rtgui/paramsedited.h index 7b4b9c061..3e77fcf56 100644 --- a/rtgui/paramsedited.h +++ b/rtgui/paramsedited.h @@ -209,6 +209,7 @@ class SharpeningParamsEdited public: bool enabled; bool contrast; + bool blurradius; bool radius; bool amount; bool threshold; diff --git a/rtgui/sharpening.cc b/rtgui/sharpening.cc index 3614594ea..8a7b8e591 100644 --- a/rtgui/sharpening.cc +++ b/rtgui/sharpening.cc @@ -27,6 +27,7 @@ Sharpening::Sharpening () : FoldableToolPanel(this, "sharpening", M("TP_SHARPENI { auto m = ProcEventMapper::getInstance(); EvSharpenContrast = m->newEvent(SHARPENING, "HISTORY_MSG_SHARPENING_CONTRAST"); + EvSharpenBlur = m->newEvent(SHARPENING, "HISTORY_MSG_SHARPENING_BLUR"); Gtk::HBox* hb = Gtk::manage (new Gtk::HBox ()); hb->show (); @@ -34,6 +35,10 @@ Sharpening::Sharpening () : FoldableToolPanel(this, "sharpening", M("TP_SHARPENI contrast->setAdjusterListener (this); pack_start(*contrast); contrast->show(); + blur = Gtk::manage(new Adjuster (M("TP_SHARPENING_BLUR"), 0.2, 2.0, 0.05, 0.2)); + blur->setAdjusterListener (this); + pack_start(*blur); + blur->show(); Gtk::Label* ml = Gtk::manage (new Gtk::Label (M("TP_SHARPENING_METHOD") + ":")); ml->show (); @@ -152,7 +157,8 @@ void Sharpening::read (const ProcParams* pp, const ParamsEdited* pedited) disableListener (); if (pedited) { - contrast->setEditedState (pedited->sharpening.contrast ? Edited : UnEdited); + contrast->setEditedState (pedited->sharpening.contrast ? Edited : UnEdited); + blur->setEditedState (pedited->sharpening.blurradius ? Edited : UnEdited); amount->setEditedState (pedited->sharpening.amount ? Edited : UnEdited); radius->setEditedState (pedited->sharpening.radius ? Edited : UnEdited); threshold->setEditedState (pedited->sharpening.threshold ? Edited : UnEdited); @@ -182,6 +188,7 @@ void Sharpening::read (const ProcParams* pp, const ParamsEdited* pedited) lastHaloControl = pp->sharpening.halocontrol; contrast->setValue (pp->sharpening.contrast); + blur->setValue (pp->sharpening.blurradius); amount->setValue (pp->sharpening.amount); radius->setValue (pp->sharpening.radius); threshold->setValue(pp->sharpening.threshold); @@ -224,6 +231,7 @@ void Sharpening::write (ProcParams* pp, ParamsEdited* pedited) { pp->sharpening.contrast = contrast->getValue (); + pp->sharpening.blurradius = blur->getValue (); pp->sharpening.amount = (int)amount->getValue(); pp->sharpening.enabled = getEnabled (); pp->sharpening.radius = radius->getValue (); @@ -246,6 +254,7 @@ void Sharpening::write (ProcParams* pp, ParamsEdited* pedited) if (pedited) { pedited->sharpening.contrast = contrast->getEditedState (); + pedited->sharpening.blurradius = blur->getEditedState (); pedited->sharpening.amount = amount->getEditedState (); pedited->sharpening.radius = radius->getEditedState (); pedited->sharpening.threshold = threshold->getEditedState (); @@ -266,6 +275,7 @@ void Sharpening::write (ProcParams* pp, ParamsEdited* pedited) void Sharpening::setDefaults (const ProcParams* defParams, const ParamsEdited* pedited) { contrast->setDefault (defParams->sharpening.contrast); + blur->setDefault (defParams->sharpening.blurradius); amount->setDefault (defParams->sharpening.amount); radius->setDefault (defParams->sharpening.radius); threshold->setDefault (defParams->sharpening.threshold); @@ -279,6 +289,7 @@ void Sharpening::setDefaults (const ProcParams* defParams, const ParamsEdited* p if (pedited) { contrast->setDefaultEditedState (pedited->sharpening.contrast ? Edited : UnEdited); + blur->setDefaultEditedState (pedited->sharpening.blurradius ? Edited : UnEdited); amount->setDefaultEditedState (pedited->sharpening.amount ? Edited : UnEdited); radius->setDefaultEditedState (pedited->sharpening.radius ? Edited : UnEdited); threshold->setDefaultEditedState (pedited->sharpening.threshold ? Edited : UnEdited); @@ -291,6 +302,7 @@ void Sharpening::setDefaults (const ProcParams* defParams, const ParamsEdited* p ddamping->setDefaultEditedState (pedited->sharpening.deconvdamping ? Edited : UnEdited); } else { contrast->setDefaultEditedState (Irrelevant); + blur->setDefaultEditedState (Irrelevant); amount->setDefaultEditedState (Irrelevant); radius->setDefaultEditedState (Irrelevant); threshold->setDefaultEditedState (Irrelevant); @@ -310,7 +322,7 @@ void Sharpening::adjusterChanged(Adjuster* a, double newval) Glib::ustring costr; - if (a == radius || a == dradius) { + if (a == radius || a == dradius || a == blur) { costr = Glib::ustring::format (std::setw(3), std::fixed, std::setprecision(2), a->getValue()); } else if (a == eradius) { costr = Glib::ustring::format (std::setw(2), std::fixed, std::setprecision(1), a->getValue()); @@ -324,6 +336,8 @@ void Sharpening::adjusterChanged(Adjuster* a, double newval) listener->panelChanged (EvShrAmount, costr); } else if (a == radius) { listener->panelChanged (EvShrRadius, costr); + } else if (a == blur) { + listener->panelChanged (EvSharpenBlur, costr); } else if (a == eradius) { listener->panelChanged (EvShrEdgeRadius, costr); } else if (a == etolerance) { @@ -487,6 +501,7 @@ void Sharpening::setBatchMode (bool batchMode) pack_start (*rld); contrast->showEditedCB (); + blur->showEditedCB (); radius->showEditedCB (); amount->showEditedCB (); threshold->showEditedCB (); @@ -518,6 +533,7 @@ void Sharpening::setAdjusterBehavior (bool contrastadd, bool radiusadd, bool amo void Sharpening::trimValues (rtengine::procparams::ProcParams* pp) { contrast->trimValue(pp->sharpening.contrast); + blur->trimValue(pp->sharpening.blurradius); radius->trimValue(pp->sharpening.radius); dradius->trimValue(pp->sharpening.deconvradius); amount->trimValue(pp->sharpening.amount); diff --git a/rtgui/sharpening.h b/rtgui/sharpening.h index fa5c956da..75ea083c9 100644 --- a/rtgui/sharpening.h +++ b/rtgui/sharpening.h @@ -29,6 +29,7 @@ class Sharpening : public ToolParamBlock, public ThresholdAdjusterListener, publ protected: Adjuster* contrast; + Adjuster* blur; MyComboBoxText* method; Adjuster* dradius; Adjuster* damount; @@ -55,6 +56,7 @@ protected: sigc::connection hcConn; rtengine::ProcEvent EvSharpenContrast; + rtengine::ProcEvent EvSharpenBlur; public: Sharpening ();