added simple local contrast tool
Borrowed from G'MIC
This commit is contained in:
@@ -115,6 +115,7 @@ set(RTENGINESOURCEFILES
|
||||
utils.cc
|
||||
rtlensfun.cc
|
||||
tmo_fattal02.cc
|
||||
iplocalcontrast.cc
|
||||
)
|
||||
|
||||
if(LENSFUN_HAS_LOAD_DIRECTORY)
|
||||
|
||||
@@ -3427,6 +3427,9 @@ void ImProcFunctions::rgbProc (Imagefloat* working, LabImage* lab, PipetteBuffer
|
||||
int tW;
|
||||
int tH;
|
||||
|
||||
// zero out the buffers
|
||||
memset(buffer, 0, 3 * sizeof (float) * TS * TS + 20 * 64 + 63);
|
||||
|
||||
// Allocating buffer for the PipetteBuffer
|
||||
float *editIFloatTmpR = nullptr, *editIFloatTmpG = nullptr, *editIFloatTmpB = nullptr, *editWhateverTmp = nullptr;
|
||||
|
||||
@@ -4965,6 +4968,11 @@ void ImProcFunctions::rgbProc (Imagefloat* working, LabImage* lab, PipetteBuffer
|
||||
if (vCurveEnabled) {
|
||||
delete vCurve;
|
||||
}
|
||||
|
||||
if (params->localContrast.enabled) {
|
||||
// Alberto's local contrast
|
||||
localContrast(lab);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -345,6 +345,8 @@ public:
|
||||
void BadpixelsLab (LabImage * src, LabImage * dst, double radius, int thresh, int mode, float skinprot, float chrom);
|
||||
|
||||
void ToneMapFattal02(Imagefloat *rgb);
|
||||
//void localContrast(float *r, float *g, float *b, int width, int height);
|
||||
void localContrast(LabImage *lab);
|
||||
|
||||
Image8* lab2rgb (LabImage* lab, int cx, int cy, int cw, int ch, const procparams::ColorManagementParams &icm);
|
||||
Image16* lab2rgb16 (LabImage* lab, int cx, int cy, int cw, int ch, const procparams::ColorManagementParams &icm, GammaValues *ga = nullptr);
|
||||
|
||||
67
rtengine/iplocalcontrast.cc
Normal file
67
rtengine/iplocalcontrast.cc
Normal file
@@ -0,0 +1,67 @@
|
||||
/* -*- C++ -*-
|
||||
*
|
||||
* This file is part of RawTherapee.
|
||||
*
|
||||
* Ported from G'MIC by Alberto Griggio <alberto.griggio@gmail.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/>.
|
||||
*/
|
||||
|
||||
#ifdef _OPENMP
|
||||
#include <omp.h>
|
||||
#endif
|
||||
|
||||
#include "improcfun.h"
|
||||
#include "settings.h"
|
||||
#include "gauss.h"
|
||||
#include "boxblur.h"
|
||||
#include "array2D.h"
|
||||
|
||||
namespace rtengine {
|
||||
|
||||
void ImProcFunctions::localContrast(LabImage *lab)
|
||||
{
|
||||
if (!params->localContrast.enabled) {
|
||||
return;
|
||||
}
|
||||
|
||||
const int width = lab->W;
|
||||
const int height = lab->H;
|
||||
const float a = -params->localContrast.amount;
|
||||
const float half = 0.5f;
|
||||
const float dark = params->localContrast.darkness;
|
||||
const float light = params->localContrast.lightness;
|
||||
array2D<float> buf(width, height);
|
||||
const float sigma = params->localContrast.radius / scale;
|
||||
|
||||
gaussianBlur(lab->L, buf, width, height, sigma);
|
||||
|
||||
#ifdef _OPENMP
|
||||
#pragma omp parallel for
|
||||
#endif
|
||||
for (int y = 0; y < height; ++y) {
|
||||
for (int x = 0; x < width; ++x) {
|
||||
buf[y][x] -= lab->L[y][x];
|
||||
buf[y][x] *= a;
|
||||
|
||||
if (dark != 1 || light != 1) {
|
||||
buf[y][x] = max(buf[y][x], half) * light + min(buf[y][x], half) * dark;
|
||||
}
|
||||
|
||||
lab->L[y][x] += buf[y][x];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace rtengine
|
||||
@@ -520,6 +520,11 @@ enum ProcEvent {
|
||||
EvWBEnabled = 490,
|
||||
EvRGBEnabled = 491,
|
||||
EvLEnabled = 492,
|
||||
EvLocalContrastEnabled = 493,
|
||||
EvLocalContrastRadius = 494,
|
||||
EvLocalContrastAmount = 495,
|
||||
EvLocalContrastDarkness = 496,
|
||||
EvLocalContrastLightness = 497,
|
||||
|
||||
NUMOFEVENTS
|
||||
|
||||
|
||||
@@ -590,6 +590,34 @@ bool RGBCurvesParams::operator !=(const RGBCurvesParams& other) const
|
||||
return !(*this == other);
|
||||
}
|
||||
|
||||
|
||||
LocalContrastParams::LocalContrastParams():
|
||||
enabled(false),
|
||||
radius(80),
|
||||
amount(0.2),
|
||||
darkness(1.0),
|
||||
lightness(1.0)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
bool LocalContrastParams::operator==(const LocalContrastParams &other) const
|
||||
{
|
||||
return
|
||||
enabled == other.enabled
|
||||
&& radius == other.radius
|
||||
&& amount == other.amount
|
||||
&& darkness == other.darkness
|
||||
&& lightness == other.lightness;
|
||||
}
|
||||
|
||||
|
||||
bool LocalContrastParams::operator!=(const LocalContrastParams &other) const
|
||||
{
|
||||
return !(*this == other);
|
||||
}
|
||||
|
||||
|
||||
ColorToningParams::ColorToningParams() :
|
||||
enabled(false),
|
||||
autosat(true),
|
||||
@@ -2588,6 +2616,8 @@ void ProcParams::setDefaults ()
|
||||
|
||||
rgbCurves = RGBCurvesParams();
|
||||
|
||||
localContrast = LocalContrastParams();
|
||||
|
||||
colorToning = ColorToningParams();
|
||||
|
||||
sharpenEdge = SharpenEdgeParams();
|
||||
@@ -2755,6 +2785,14 @@ int ProcParams::save(const Glib::ustring& fname, const Glib::ustring& fname2, bo
|
||||
saveToKeyfile(!pedited || pedited->retinex.transmissionCurve, "Retinex", "TransmissionCurve", retinex.transmissionCurve, keyFile);
|
||||
saveToKeyfile(!pedited || pedited->retinex.gaintransmissionCurve, "Retinex", "GainTransmissionCurve", retinex.gaintransmissionCurve, keyFile);
|
||||
|
||||
// Local contrast
|
||||
saveToKeyfile(!pedited || pedited->localContrast.enabled, "Local Contrast", "Enabled", localContrast.enabled, keyFile);
|
||||
saveToKeyfile(!pedited || pedited->localContrast.radius, "Local Contrast", "Radius", localContrast.radius, keyFile);
|
||||
saveToKeyfile(!pedited || pedited->localContrast.amount, "Local Contrast", "Amount", localContrast.amount, keyFile);
|
||||
saveToKeyfile(!pedited || pedited->localContrast.darkness, "Local Contrast", "Darkness", localContrast.darkness, keyFile);
|
||||
saveToKeyfile(!pedited || pedited->localContrast.lightness, "Local Contrast", "Lightness", localContrast.lightness, keyFile);
|
||||
|
||||
|
||||
// Channel mixer
|
||||
saveToKeyfile(!pedited || pedited->chmixer.enabled, "Channel Mixer", "Enabled", chmixer.enabled, keyFile);
|
||||
if (!pedited || pedited->chmixer.red[0] || pedited->chmixer.red[1] || pedited->chmixer.red[2]) {
|
||||
@@ -3590,6 +3628,14 @@ int ProcParams::load(const Glib::ustring& fname, ParamsEdited* pedited)
|
||||
assignFromKeyfile(keyFile, "Retinex", "GainTransmissionCurve", pedited, retinex.gaintransmissionCurve, pedited->retinex.gaintransmissionCurve);
|
||||
}
|
||||
|
||||
if (keyFile.has_group("Local Contrast")) {
|
||||
assignFromKeyfile(keyFile, "Local Contrast", "Enabled", pedited, localContrast.enabled, pedited->localContrast.enabled);
|
||||
assignFromKeyfile(keyFile, "Local Contrast", "Radius", pedited, localContrast.radius, pedited->localContrast.radius);
|
||||
assignFromKeyfile(keyFile, "Local Contrast", "Amount", pedited, localContrast.amount, pedited->localContrast.amount);
|
||||
assignFromKeyfile(keyFile, "Local Contrast", "Darkness", pedited, localContrast.darkness, pedited->localContrast.darkness);
|
||||
assignFromKeyfile(keyFile, "Local Contrast", "Lightness", pedited, localContrast.lightness, pedited->localContrast.lightness);
|
||||
}
|
||||
|
||||
if (keyFile.has_group ("Luminance Curve")) {
|
||||
if (ppVersion >= 329) {
|
||||
assignFromKeyfile(keyFile, "Luminance Curve", "Enabled", pedited, labCurve.enabled, pedited->labCurve.enabled);
|
||||
@@ -4716,6 +4762,7 @@ bool ProcParams::operator ==(const ProcParams& other) const
|
||||
return
|
||||
toneCurve == other.toneCurve
|
||||
&& retinex == other.retinex
|
||||
&& localContrast == other.localContrast
|
||||
&& labCurve == other.labCurve
|
||||
&& sharpenEdge == other.sharpenEdge
|
||||
&& sharpenMicro == other.sharpenMicro
|
||||
|
||||
@@ -364,6 +364,24 @@ struct LCurveParams
|
||||
bool operator !=(const LCurveParams& other) const;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Parameters for local contrast
|
||||
*/
|
||||
struct LocalContrastParams {
|
||||
bool enabled;
|
||||
int radius;
|
||||
double amount;
|
||||
double darkness;
|
||||
double lightness;
|
||||
|
||||
LocalContrastParams();
|
||||
|
||||
bool operator==(const LocalContrastParams &other) const;
|
||||
bool operator!=(const LocalContrastParams &other) const;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Parameters of the RGB curves
|
||||
*/
|
||||
@@ -1340,6 +1358,7 @@ public:
|
||||
ToneCurveParams toneCurve; ///< Tone curve parameters
|
||||
LCurveParams labCurve; ///< CIELAB luminance curve parameters
|
||||
RetinexParams retinex; ///< Retinex parameters
|
||||
LocalContrastParams localContrast; ////< Local contrast parameters
|
||||
RGBCurvesParams rgbCurves; ///< RGB curves parameters
|
||||
ColorToningParams colorToning; ///< Color Toning parameters
|
||||
SharpeningParams sharpening; ///< Sharpening parameters
|
||||
|
||||
@@ -519,6 +519,11 @@ int refreshmap[rtengine::NUMOFEVENTS] = {
|
||||
HDR, // EvTMFattalAmount
|
||||
ALLNORAW, // EvWBEnabled
|
||||
RGBCURVE, // EvRGBEnabled
|
||||
LUMINANCECURVE // EvLEnabled
|
||||
LUMINANCECURVE, // EvLEnabled
|
||||
RGBCURVE, // EvLocalContastEnabled
|
||||
RGBCURVE, // EvLocalContrastRadius
|
||||
RGBCURVE, // EvLocalContrastAmount
|
||||
RGBCURVE, // EvLocalContrastDarkness
|
||||
RGBCURVE // EvLocalContrastLightness
|
||||
};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user