Edge-preserving decomposition and tone-mapping tool. Committed on behalf of Ben_pcc.

This commit is contained in:
Emil Martinec
2011-11-28 14:29:26 -06:00
parent ba7dddd663
commit 6595bf18d1
25 changed files with 1059 additions and 29 deletions

View File

@@ -7,7 +7,7 @@ set (BASESOURCEFILES
clipboard.cc thumbimageupdater.cc bqentryupdater.cc lensgeom.cc
coarsepanel.cc cacorrection.cc hlrec.cc chmixer.cc
resize.cc icmpanel.cc crop.cc shadowshighlights.cc
impulsedenoise.cc dirpyrdenoise.cc
impulsedenoise.cc dirpyrdenoise.cc epd.cc
exifpanel.cc toolpanel.cc
sharpening.cc vibrance.cc
whitebalance.cc vignetting.cc rotate.cc distortion.cc

163
rtgui/epd.cc Normal file
View File

@@ -0,0 +1,163 @@
/*
* This file is part of RawTherapee.
*
* Copyright (c) 2004-2010 Gabor Horvath <hgabor@rawtherapee.com>
*
* RawTherapee 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.
*
* RawTherapee 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 RawTherapee. If not, see <http://www.gnu.org/licenses/>.
*/
#include <epd.h>
#include <iomanip>
#include <math.h>
using namespace rtengine;
using namespace rtengine::procparams;
EdgePreservingDecompositionUI::EdgePreservingDecompositionUI () : Gtk::VBox(), FoldableToolPanel(this){
enabled = Gtk::manage (new Gtk::CheckButton (M("GENERAL_ENABLED")));
enabled->set_active (false);
enabled->show ();
pack_start (*enabled);
Gtk::HSeparator *hsep1 = Gtk::manage (new Gtk::HSeparator());
hsep1->show ();
pack_start (*hsep1);
enaConn = enabled->signal_toggled().connect( sigc::mem_fun(*this, &EdgePreservingDecompositionUI::enabledChanged) );
Strength = Gtk::manage(new Adjuster (M("TP_EPD_STRENGTH"), -2.0, 2.0, 0.01, 0.25));
EdgeStopping = Gtk::manage(new Adjuster (M("TP_EPD_EDGESTOPPING"), 0.1, 4.0, 0.01, 1.4));
Scale = Gtk::manage(new Adjuster (M("TP_EPD_SCALE"), 0.1, 10.0, 0.01, 1.0));
ReweightingIterates = Gtk::manage(new Adjuster (M("TP_EPD_REWEIGHTINGITERATES"), 0, 9, 1, 0));
Strength->setAdjusterListener(this);
EdgeStopping->setAdjusterListener(this);
Scale->setAdjusterListener(this);
ReweightingIterates->setAdjusterListener(this);
Strength->show();
EdgeStopping->show();
Scale->show();
ReweightingIterates->show();
pack_start(*Strength);
pack_start(*EdgeStopping);
pack_start(*Scale);
pack_start(*ReweightingIterates);
}
void EdgePreservingDecompositionUI::read(const ProcParams *pp, const ParamsEdited *pedited){
disableListener();
if(pedited){
Strength->setEditedState(pedited->edgePreservingDecompositionUI.Strength ? Edited : UnEdited);
EdgeStopping->setEditedState(pedited->edgePreservingDecompositionUI.EdgeStopping ? Edited : UnEdited);
Scale->setEditedState(pedited->edgePreservingDecompositionUI.Scale ? Edited : UnEdited);
ReweightingIterates->setEditedState(pedited->edgePreservingDecompositionUI.ReweightingIterates ? Edited : UnEdited);
enabled->set_inconsistent(!pedited->edgePreservingDecompositionUI.enabled);
}
enaConn.block(true);
enabled->set_active(pp->edgePreservingDecompositionUI.enabled);
enaConn.block (false);
lastEnabled = pp->edgePreservingDecompositionUI.enabled;
Strength->setValue(pp->edgePreservingDecompositionUI.Strength);
EdgeStopping->setValue(pp->edgePreservingDecompositionUI.EdgeStopping);
Scale->setValue(pp->edgePreservingDecompositionUI.Scale);
ReweightingIterates->setValue(pp->edgePreservingDecompositionUI.ReweightingIterates);
enableListener();
}
void EdgePreservingDecompositionUI::write(ProcParams *pp, ParamsEdited *pedited){
pp->edgePreservingDecompositionUI.Strength = Strength->getValue();
pp->edgePreservingDecompositionUI.EdgeStopping = EdgeStopping->getValue();
pp->edgePreservingDecompositionUI.Scale = Scale->getValue();
pp->edgePreservingDecompositionUI.ReweightingIterates = ReweightingIterates->getValue();
pp->edgePreservingDecompositionUI.enabled = enabled->get_active();
if(pedited){
pedited->edgePreservingDecompositionUI.Strength = Strength->getEditedState();
pedited->edgePreservingDecompositionUI.EdgeStopping = EdgeStopping->getEditedState();
pedited->edgePreservingDecompositionUI.Scale = Scale->getEditedState();
pedited->edgePreservingDecompositionUI.ReweightingIterates = ReweightingIterates->getEditedState();
pedited->edgePreservingDecompositionUI.enabled = !enabled->get_inconsistent();
}
}
void EdgePreservingDecompositionUI::setDefaults(const ProcParams *defParams, const ParamsEdited *pedited){
Strength->setDefault(defParams->edgePreservingDecompositionUI.Strength);
EdgeStopping->setDefault(defParams->edgePreservingDecompositionUI.EdgeStopping);
Scale->setDefault(defParams->edgePreservingDecompositionUI.Scale);
ReweightingIterates->setDefault(defParams->edgePreservingDecompositionUI.ReweightingIterates);
if(pedited){
Strength->setDefaultEditedState(pedited->edgePreservingDecompositionUI.Strength ? Edited : UnEdited);
EdgeStopping->setDefaultEditedState(pedited->edgePreservingDecompositionUI.EdgeStopping ? Edited : UnEdited);
Scale->setDefaultEditedState(pedited->edgePreservingDecompositionUI.Scale ? Edited : UnEdited);
ReweightingIterates->setDefaultEditedState(pedited->edgePreservingDecompositionUI.ReweightingIterates ? Edited : UnEdited);
}else{
Strength->setDefaultEditedState(Irrelevant);
EdgeStopping->setDefaultEditedState(Irrelevant);
Scale->setDefaultEditedState(Irrelevant);
ReweightingIterates->setDefaultEditedState(Irrelevant);
}
}
void EdgePreservingDecompositionUI::adjusterChanged(Adjuster* a, double newval){
if(listener && enabled->get_active()){
if(a == Strength)
listener->panelChanged(EvEPDStrength, Glib::ustring::format(std::setw(2), std::fixed, std::setprecision(2), a->getValue()));
else if(a == EdgeStopping)
listener->panelChanged(EvEPDEdgeStopping, Glib::ustring::format(std::setw(2), std::fixed, std::setprecision(2), a->getValue()));
else if(a == Scale)
listener->panelChanged(EvEPDScale, Glib::ustring::format(std::setw(2), std::fixed, std::setprecision(2), a->getValue()));
else if(a == ReweightingIterates)
listener->panelChanged(EvEPDReweightingIterates, Glib::ustring::format((int)a->getValue()));
}
}
void EdgePreservingDecompositionUI::enabledChanged(){
if(batchMode){
if(enabled->get_inconsistent()){
enabled->set_inconsistent (false);
enaConn.block (true);
enabled->set_active (false);
enaConn.block (false);
}
else if(lastEnabled)
enabled->set_inconsistent (true);
lastEnabled = enabled->get_active ();
}
if(listener){
if(enabled->get_active ())
listener->panelChanged (EvEPDEnabled, M("GENERAL_ENABLED"));
else
listener->panelChanged (EvEPDEnabled, M("GENERAL_DISABLED"));
}
}
void EdgePreservingDecompositionUI::setBatchMode(bool batchMode){
ToolPanel::setBatchMode(batchMode);
Strength->showEditedCB();
EdgeStopping->showEditedCB();
Scale->showEditedCB();
ReweightingIterates->showEditedCB();
}

50
rtgui/epd.h Normal file
View File

@@ -0,0 +1,50 @@
/*
* This file is part of RawTherapee.
*
* Copyright (c) 2004-2010 Gabor Horvath <hgabor@rawtherapee.com>
*
* RawTherapee 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.
*
* RawTherapee 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 RawTherapee. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef _EPD_H_
#define _EPD_H_
#include <gtkmm.h>
#include <adjuster.h>
#include <toolpanel.h>
class EdgePreservingDecompositionUI : public Gtk::VBox, public AdjusterListener, public FoldableToolPanel {
protected:
Adjuster *Strength;
Adjuster *EdgeStopping;
Adjuster *Scale;
Adjuster *ReweightingIterates;
Gtk::CheckButton* enabled;
bool lastEnabled;
sigc::connection enaConn;
public:
EdgePreservingDecompositionUI();
void read (const rtengine::procparams::ProcParams* pp, const ParamsEdited* pedited=NULL);
void write (rtengine::procparams::ProcParams* pp, ParamsEdited* pedited=NULL);
void setDefaults (const rtengine::procparams::ProcParams* defParams, const ParamsEdited* pedited=NULL);
void setBatchMode (bool batchMode);
void adjusterChanged (Adjuster* a, double newval);
void enabledChanged ();
};
#endif

View File

@@ -100,6 +100,11 @@ void ParamsEdited::set (bool v) {
dirpyrDenoise.luma = v;
dirpyrDenoise.chroma = v;
dirpyrDenoise.gamma = v;
edgePreservingDecompositionUI.enabled = v;
edgePreservingDecompositionUI.Strength = v;
edgePreservingDecompositionUI.EdgeStopping = v;
edgePreservingDecompositionUI.Scale = v;
edgePreservingDecompositionUI.ReweightingIterates = v;
sh.enabled = v;
sh.hq = v;
sh.highlights = v;
@@ -282,6 +287,12 @@ void ParamsEdited::initFrom (const std::vector<rtengine::procparams::ProcParams>
dirpyrDenoise.chroma = dirpyrDenoise.chroma && p.dirpyrDenoise.chroma == other.dirpyrDenoise.chroma;
dirpyrDenoise.gamma = dirpyrDenoise.gamma && p.dirpyrDenoise.gamma == other.dirpyrDenoise.gamma;
edgePreservingDecompositionUI.enabled = edgePreservingDecompositionUI.enabled && p.edgePreservingDecompositionUI.enabled == other.edgePreservingDecompositionUI.enabled;
edgePreservingDecompositionUI.Strength = edgePreservingDecompositionUI.Strength && p.edgePreservingDecompositionUI.Strength == other.edgePreservingDecompositionUI.Strength;
edgePreservingDecompositionUI.EdgeStopping = edgePreservingDecompositionUI.EdgeStopping && p.edgePreservingDecompositionUI.EdgeStopping == other.edgePreservingDecompositionUI.EdgeStopping;
edgePreservingDecompositionUI.Scale = edgePreservingDecompositionUI.Scale && p.edgePreservingDecompositionUI.Scale == other.edgePreservingDecompositionUI.Scale;
edgePreservingDecompositionUI.ReweightingIterates = edgePreservingDecompositionUI.ReweightingIterates && p.edgePreservingDecompositionUI.ReweightingIterates == other.edgePreservingDecompositionUI.ReweightingIterates;
sh.enabled = sh.enabled && p.sh.enabled == other.sh.enabled;
sh.hq = sh.hq && p.sh.hq == other.sh.hq;
sh.highlights = sh.highlights && p.sh.highlights == other.sh.highlights;
@@ -463,6 +474,12 @@ void ParamsEdited::combine (rtengine::procparams::ProcParams& toEdit, const rten
if (dirpyrDenoise.chroma) toEdit.dirpyrDenoise.chroma = dontforceSet && options.baBehav[ADDSET_DIRPYRDN_CHLUM] ? toEdit.dirpyrDenoise.chroma + mods.dirpyrDenoise.chroma : mods.dirpyrDenoise.chroma;
if (dirpyrDenoise.gamma) toEdit.dirpyrDenoise.gamma = dontforceSet && options.baBehav[ADDSET_DIRPYRDN_GAMMA] ? toEdit.dirpyrDenoise.gamma + mods.dirpyrDenoise.gamma : mods.dirpyrDenoise.gamma;
if (edgePreservingDecompositionUI.enabled) toEdit.edgePreservingDecompositionUI.enabled = mods.edgePreservingDecompositionUI.enabled;
if (edgePreservingDecompositionUI.Strength) toEdit.edgePreservingDecompositionUI.Strength = mods.edgePreservingDecompositionUI.Strength;
if (edgePreservingDecompositionUI.EdgeStopping) toEdit.edgePreservingDecompositionUI.EdgeStopping = mods.edgePreservingDecompositionUI.EdgeStopping;
if (edgePreservingDecompositionUI.Scale) toEdit.edgePreservingDecompositionUI.Scale = mods.edgePreservingDecompositionUI.Scale;
if (edgePreservingDecompositionUI.ReweightingIterates) toEdit.edgePreservingDecompositionUI.ReweightingIterates = mods.edgePreservingDecompositionUI.ReweightingIterates;
if (sh.enabled) toEdit.sh.enabled = mods.sh.enabled;
if (sh.hq) toEdit.sh.hq = mods.sh.hq;
if (sh.highlights) toEdit.sh.highlights = dontforceSet && options.baBehav[ADDSET_SH_HIGHLIGHTS] ? toEdit.sh.highlights + mods.sh.highlights : mods.sh.highlights;

View File

@@ -167,6 +167,16 @@ public:
bool gamma;
};
class EPDParamsEdited{
public:
bool enabled;
bool Strength;
bool EdgeStopping;
bool Scale;
bool ReweightingIterates;
};
class SHParamsEdited {
public:
@@ -362,6 +372,7 @@ class ParamsEdited {
ColorDenoiseParamsEdited colorDenoise;
DefringeParamsEdited defringe;
DirPyrDenoiseParamsEdited dirpyrDenoise;
EPDParamsEdited edgePreservingDecompositionUI;
ImpulseDenoiseParamsEdited impulseDenoise;
SHParamsEdited sh;
CropParamsEdited crop;

View File

@@ -56,6 +56,7 @@ PartialPasteDlg::PartialPasteDlg () {
impden = Gtk::manage (new Gtk::CheckButton (M("PARTIALPASTE_IMPULSEDENOISE")));
dirpyreq = Gtk::manage (new Gtk::CheckButton (M("PARTIALPASTE_DIRPYREQUALIZER")));
defringe = Gtk::manage (new Gtk::CheckButton (M("PARTIALPASTE_DEFRINGE")));
edgePreservingDecompositionUI = Gtk::manage (new Gtk::CheckButton (M("PARTIALPASTE_EPD")));
// options in color:
vibrance = Gtk::manage (new Gtk::CheckButton (M("PARTIALPASTE_VIBRANCE")));
@@ -130,6 +131,7 @@ PartialPasteDlg::PartialPasteDlg () {
vboxes[1]->pack_start (*impden, Gtk::PACK_SHRINK, 2);
vboxes[1]->pack_start (*dirpyrden, Gtk::PACK_SHRINK, 2);
vboxes[1]->pack_start (*defringe, Gtk::PACK_SHRINK, 2);
vboxes[1]->pack_start (*edgePreservingDecompositionUI, Gtk::PACK_SHRINK, 2);
vboxes[1]->pack_start (*dirpyreq, Gtk::PACK_SHRINK, 2);
//vboxes[1]->pack_start (*waveq, Gtk::PACK_SHRINK, 2);
@@ -245,6 +247,7 @@ PartialPasteDlg::PartialPasteDlg () {
dirpyreqConn = dirpyreq->signal_toggled().connect (sigc::bind (sigc::mem_fun(*detail, &Gtk::CheckButton::set_inconsistent), true));
//waveqConn = waveq->signal_toggled().connect (sigc::bind (sigc::mem_fun(*detail, &Gtk::CheckButton::set_inconsistent), true));
defringeConn = defringe->signal_toggled().connect (sigc::bind (sigc::mem_fun(*detail, &Gtk::CheckButton::set_inconsistent), true));
edgePreservingDecompositionUIConn = edgePreservingDecompositionUI->signal_toggled().connect (sigc::bind (sigc::mem_fun(*detail, &Gtk::CheckButton::set_inconsistent), true));
vibranceConn = vibrance->signal_toggled().connect (sigc::bind (sigc::mem_fun(*color, &Gtk::CheckButton::set_inconsistent), true));
chmixerConn = chmixer->signal_toggled().connect (sigc::bind (sigc::mem_fun(*color, &Gtk::CheckButton::set_inconsistent), true));
@@ -433,6 +436,7 @@ void PartialPasteDlg::detailToggled () {
impdenConn.block (true);
dirpyrdenConn.block (true);
defringeConn.block (true);
edgePreservingDecompositionUIConn.block(true);
dirpyreqConn.block (true);
//waveqConn.block (true);
@@ -453,6 +457,7 @@ void PartialPasteDlg::detailToggled () {
impdenConn.block (false);
dirpyrdenConn.block (false);
defringeConn.block (false);
edgePreservingDecompositionUIConn.block (false);
dirpyreqConn.block (false);
//waveqConn.block (false);
}

View File

@@ -52,6 +52,7 @@ class PartialPasteDlg : public Gtk::Dialog {
Gtk::CheckButton* waveq;
Gtk::CheckButton* dirpyrden;
Gtk::CheckButton* defringe;
Gtk::CheckButton* edgePreservingDecompositionUI;
Gtk::CheckButton* dirpyreq;
// options in color:
@@ -105,7 +106,7 @@ class PartialPasteDlg : public Gtk::Dialog {
sigc::connection everythingConn, basicConn, detailConn, colorConn, lensConn, compositionConn, metaicmConn, rawConn;;
sigc::connection wbConn, exposureConn, hlrecConn, shConn, labcurveConn;
sigc::connection sharpenConn, gradsharpenConn, microcontrastConn, impdenConn, dirpyrdenConn, waveqConn, defringeConn, dirpyreqConn;
sigc::connection sharpenConn, gradsharpenConn, microcontrastConn, impdenConn, dirpyrdenConn, waveqConn, defringeConn, edgePreservingDecompositionUIConn, dirpyreqConn;
sigc::connection vibranceConn, chmixerConn, hsveqConn;
sigc::connection distortionConn, cacorrConn, vignettingConn;
sigc::connection coarserotConn, finerotConn, cropConn, resizeConn, perspectiveConn, commonTransConn;

View File

@@ -45,6 +45,7 @@ ToolPanelCoordinator::ToolPanelCoordinator () : ipc(NULL) {
impulsedenoise = Gtk::manage (new ImpulseDenoise ());
defringe = Gtk::manage (new Defringe ());
dirpyrdenoise = Gtk::manage (new DirPyrDenoise ());
edgePreservingDecompositionUI = Gtk::manage (new EdgePreservingDecompositionUI ());
sharpening = Gtk::manage (new Sharpening ());
sharpenEdge = Gtk::manage (new SharpenEdge ());
sharpenMicro = Gtk::manage (new SharpenMicro ());
@@ -83,6 +84,7 @@ ToolPanelCoordinator::ToolPanelCoordinator () : ipc(NULL) {
addPanel (detailsPanel, sharpenEdge, M("TP_SHARPENEDGE_LABEL")); toolPanels.push_back (sharpenEdge);
addPanel (detailsPanel, sharpenMicro, M("TP_SHARPENMICRO_LABEL")); toolPanels.push_back (sharpenMicro);
addPanel (colorPanel, hsvequalizer, M("TP_HSVEQUALIZER_LABEL")); toolPanels.push_back (hsvequalizer);
addPanel (exposurePanel, edgePreservingDecompositionUI, M("TP_EPD_LABEL")); toolPanels.push_back (edgePreservingDecompositionUI);
addPanel (exposurePanel, lcurve, M("TP_LABCURVE_LABEL")); toolPanels.push_back (lcurve);
addPanel (detailsPanel, impulsedenoise, M("TP_IMPULSEDENOISE_LABEL")); toolPanels.push_back (impulsedenoise);
addPanel (detailsPanel, dirpyrdenoise, M("TP_DIRPYRDENOISE_LABEL")); toolPanels.push_back (dirpyrdenoise);

View File

@@ -34,6 +34,7 @@
#include <impulsedenoise.h>
#include <defringe.h>
#include <dirpyrdenoise.h>
#include <epd.h>
#include <sharpening.h>
#include <labcurve.h>
#include <exifpanel.h>
@@ -95,6 +96,7 @@ class ToolPanelCoordinator : public ToolPanelListener,
Defringe* defringe;
ImpulseDenoise* impulsedenoise;
DirPyrDenoise* dirpyrdenoise;
EdgePreservingDecompositionUI *edgePreservingDecompositionUI;
Sharpening* sharpening;
SharpenEdge* sharpenEdge;
SharpenMicro* sharpenMicro;