Merge pull request #5275 from Beep6581/newlocallab-dedup-localcontrast
locallab: dedup localcontrast code
This commit is contained in:
commit
a72ea75580
@ -3693,7 +3693,7 @@ void ImProcFunctions::rgbProc(Imagefloat* working, LabImage* lab, PipetteBuffer
|
|||||||
|
|
||||||
if (params->localContrast.enabled) {
|
if (params->localContrast.enabled) {
|
||||||
// Alberto's local contrast
|
// Alberto's local contrast
|
||||||
localContrast(lab);
|
localContrast(lab, lab->L, params->localContrast, scale);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -46,6 +46,7 @@ class ProcParams;
|
|||||||
|
|
||||||
struct DehazeParams;
|
struct DehazeParams;
|
||||||
struct DirPyrDenoiseParams;
|
struct DirPyrDenoiseParams;
|
||||||
|
struct LocalContrastParams;
|
||||||
struct LocallabParams;
|
struct LocallabParams;
|
||||||
struct SharpeningParams;
|
struct SharpeningParams;
|
||||||
struct SoftLightParams;
|
struct SoftLightParams;
|
||||||
@ -404,8 +405,7 @@ public:
|
|||||||
|
|
||||||
void dehaze(Imagefloat *rgb, const DehazeParams &dehazeParams);
|
void dehaze(Imagefloat *rgb, const DehazeParams &dehazeParams);
|
||||||
void ToneMapFattal02(Imagefloat *rgb);
|
void ToneMapFattal02(Imagefloat *rgb);
|
||||||
void localContrast(LabImage *lab);
|
void localContrast(LabImage *lab, float **destination, const LocalContrastParams &localContrastParams, double scale);
|
||||||
void localContrastloc(LabImage *lab, int scale, int rad, float amo, float darkn, float lightn, float **loctemp);
|
|
||||||
void colorToningLabGrid(LabImage *lab, int xstart, int xend, int ystart, int yend, bool MultiThread);
|
void colorToningLabGrid(LabImage *lab, int xstart, int xend, int ystart, int yend, bool MultiThread);
|
||||||
// void shadowsHighlights(LabImage *lab);
|
// void shadowsHighlights(LabImage *lab);
|
||||||
void shadowsHighlights(LabImage *lab, bool ena, int labmode, int hightli, int shado, int rad, int scal, int hltonal, int shtonal);
|
void shadowsHighlights(LabImage *lab, bool ena, int labmode, int hightli, int shado, int rad, int scal, int hltonal, int shtonal);
|
||||||
|
@ -34,19 +34,19 @@
|
|||||||
namespace rtengine
|
namespace rtengine
|
||||||
{
|
{
|
||||||
|
|
||||||
void ImProcFunctions::localContrast(LabImage *lab)
|
void ImProcFunctions::localContrast(LabImage *lab, float **destination, const LocalContrastParams &localContrastParams, double scale)
|
||||||
{
|
{
|
||||||
if (!params->localContrast.enabled) {
|
if (!localContrastParams.enabled) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const int width = lab->W;
|
const int width = lab->W;
|
||||||
const int height = lab->H;
|
const int height = lab->H;
|
||||||
const float a = params->localContrast.amount;
|
const float a = localContrastParams.amount;
|
||||||
const float dark = params->localContrast.darkness;
|
const float dark = localContrastParams.darkness;
|
||||||
const float light = params->localContrast.lightness;
|
const float light = localContrastParams.lightness;
|
||||||
array2D<float> buf(width, height);
|
array2D<float> buf(width, height);
|
||||||
const float sigma = params->localContrast.radius / scale;
|
const float sigma = localContrastParams.radius / scale;
|
||||||
|
|
||||||
#ifdef _OPENMP
|
#ifdef _OPENMP
|
||||||
#pragma omp parallel if(multiThread)
|
#pragma omp parallel if(multiThread)
|
||||||
@ -65,41 +65,7 @@ void ImProcFunctions::localContrast(LabImage *lab)
|
|||||||
bufval *= (bufval > 0.f) ? light : dark;
|
bufval *= (bufval > 0.f) ? light : dark;
|
||||||
}
|
}
|
||||||
|
|
||||||
lab->L[y][x] = std::max(0.0001f, lab->L[y][x] + bufval);
|
destination[y][x] = std::max(0.0001f, lab->L[y][x] + bufval);
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void ImProcFunctions::localContrastloc(LabImage *lab, int scale, int rad, float amo, float darkn, float lightn, float **loctemp)
|
|
||||||
{
|
|
||||||
|
|
||||||
const int width = lab->W;
|
|
||||||
const int height = lab->H;
|
|
||||||
const float a = amo;
|
|
||||||
const float dark = darkn;
|
|
||||||
const float light = lightn;
|
|
||||||
array2D<float> buf(width, height);
|
|
||||||
const float sigma = (float)(rad) / scale;
|
|
||||||
|
|
||||||
#ifdef _OPENMP
|
|
||||||
#pragma omp parallel if(multiThread)
|
|
||||||
#endif
|
|
||||||
gaussianBlur(lab->L, buf, width, height, sigma);
|
|
||||||
|
|
||||||
#ifdef _OPENMP
|
|
||||||
#pragma omp parallel for if(multiThread)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
for (int y = 0; y < height; ++y) {
|
|
||||||
for (int x = 0; x < width; ++x) {
|
|
||||||
float bufval = (lab->L[y][x] - buf[y][x]) * a;
|
|
||||||
|
|
||||||
if (dark != 1 || light != 1) {
|
|
||||||
bufval *= (bufval > 0.f) ? light : dark;
|
|
||||||
}
|
|
||||||
|
|
||||||
loctemp[y][x] = std::max(0.0001f, lab->L[y][x] + bufval);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2064,47 +2064,43 @@ void ImProcFunctions::InverseSharp_Local(float **loctemp, const float hueref, co
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void ImProcFunctions::Sharp_Local(int call, float **loctemp, int senstype, const float hueref, const float chromaref, const float lumaref, const local_params & lp, LabImage * original, LabImage * transformed, int cx, int cy, int sk)
|
void ImProcFunctions::Sharp_Local(int call, float **loctemp, int senstype, const float hueref, const float chromaref, const float lumaref, const local_params &lp, LabImage *original, LabImage *transformed, int cx, int cy, int sk)
|
||||||
{
|
{
|
||||||
BENCHFUN
|
BENCHFUN
|
||||||
const float ach = (float)lp.trans / 100.f;
|
const float ach = lp.trans / 100.f;
|
||||||
float varsens = lp.senssha;
|
const float varsens = senstype == 1 ? lp.senslc : lp.senssha;
|
||||||
|
|
||||||
if (senstype == 0) {
|
|
||||||
varsens = lp.senssha;
|
|
||||||
|
|
||||||
} else if (senstype == 1) {
|
|
||||||
varsens = lp.senslc;
|
|
||||||
}
|
|
||||||
|
|
||||||
//balance deltaE
|
//balance deltaE
|
||||||
float kL = lp.balance;
|
float kL = lp.balance;
|
||||||
float kab = 1.f;
|
float kab = 1.f;
|
||||||
balancedeltaE(kL, kab);
|
balancedeltaE(kL, kab);
|
||||||
|
kab /= SQR(327.68f);
|
||||||
|
kL /= SQR(327.68f);
|
||||||
|
|
||||||
int GW = transformed->W;
|
const int GW = transformed->W;
|
||||||
int GH = transformed->H;
|
const int GH = transformed->H;
|
||||||
|
|
||||||
LabImage *origblur = new LabImage(GW, GH);
|
std::unique_ptr<LabImage> origblur(new LabImage(GW, GH));
|
||||||
float refa = chromaref * cos(hueref);
|
const float refa = chromaref * cos(hueref) * 327.68f;
|
||||||
float refb = chromaref * sin(hueref);
|
const float refb = chromaref * sin(hueref) * 327.68f;
|
||||||
|
const float refL = lumaref * 327.68f;
|
||||||
|
const float radius = 3.f / sk;
|
||||||
|
|
||||||
|
|
||||||
float radius = 3.f / sk;
|
|
||||||
#ifdef _OPENMP
|
#ifdef _OPENMP
|
||||||
#pragma omp parallel
|
#pragma omp parallel if (multiThread)
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
gaussianBlur(original->L, origblur->L, GW, GH, radius);
|
gaussianBlur(original->L, origblur->L, GW, GH, radius);
|
||||||
gaussianBlur(original->a, origblur->a, GW, GH, radius);
|
gaussianBlur(original->a, origblur->a, GW, GH, radius);
|
||||||
gaussianBlur(original->b, origblur->b, GW, GH, radius);
|
gaussianBlur(original->b, origblur->b, GW, GH, radius);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef _OPENMP
|
#ifdef _OPENMP
|
||||||
#pragma omp parallel if (multiThread)
|
#pragma omp parallel if (multiThread)
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
|
const int begy = int (lp.yc - lp.lyT);
|
||||||
|
const int begx = int (lp.xc - lp.lxL);
|
||||||
const int limscope = 80;
|
const int limscope = 80;
|
||||||
const float mindE = 2.f + MINSCOPE * varsens * lp.thr;
|
const float mindE = 2.f + MINSCOPE * varsens * lp.thr;
|
||||||
const float maxdE = 5.f + MAXSCOPE * varsens * (1 + 0.1f * lp.thr);
|
const float maxdE = 5.f + MAXSCOPE * varsens * (1 + 0.1f * lp.thr);
|
||||||
@ -2116,24 +2112,17 @@ void ImProcFunctions::Sharp_Local(int call, float **loctemp, int senstype, cons
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
for (int y = 0; y < transformed->H; y++) {
|
for (int y = 0; y < transformed->H; y++) {
|
||||||
|
|
||||||
const int loy = cy + y;
|
const int loy = cy + y;
|
||||||
const bool isZone0 = loy > lp.yc + lp.ly || loy < lp.yc - lp.lyT; // whole line is zone 0 => we can skip a lot of processing
|
const bool isZone0 = loy > lp.yc + lp.ly || loy < lp.yc - lp.lyT; // whole line is zone 0 => we can skip a lot of processing
|
||||||
|
|
||||||
if (isZone0) { // outside selection and outside transition zone => no effect, keep original values
|
if (isZone0) { // outside selection and outside transition zone => no effect, keep original values
|
||||||
for (int x = 0; x < transformed->W; x++) {
|
|
||||||
transformed->L[y][x] = original->L[y][x];
|
|
||||||
}
|
|
||||||
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int x = 0; x < transformed->W; x++) {
|
for (int x = 0; x < transformed->W; x++) {
|
||||||
int lox = cx + x;
|
const int lox = cx + x;
|
||||||
int zone = 0;
|
int zone = 0;
|
||||||
float localFactor = 1.f;
|
float localFactor = 1.f;
|
||||||
int begx = int (lp.xc - lp.lxL);
|
|
||||||
int begy = int (lp.yc - lp.lyT);
|
|
||||||
|
|
||||||
if (lp.shapmet == 0) {
|
if (lp.shapmet == 0) {
|
||||||
calcTransition(lox, loy, ach, lp, zone, localFactor);
|
calcTransition(lox, loy, ach, lp, zone, localFactor);
|
||||||
@ -2142,55 +2131,28 @@ void ImProcFunctions::Sharp_Local(int call, float **loctemp, int senstype, cons
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (zone == 0) { // outside selection and outside transition zone => no effect, keep original values
|
if (zone == 0) { // outside selection and outside transition zone => no effect, keep original values
|
||||||
transformed->L[y][x] = original->L[y][x];
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
float rL = origblur->L[y][x] / 327.68f;
|
const float dE = sqrt(kab * (SQR(refa - origblur->a[y][x]) + SQR(refb - origblur->b[y][x])) + kL * SQR(refL - origblur->L[y][x]));
|
||||||
float dE = sqrt(kab * SQR(refa - origblur->a[y][x] / 327.68f) + kab * SQR(refb - origblur->b[y][x] / 327.68f) + kL * SQR(lumaref - rL));
|
|
||||||
|
|
||||||
float reducdE = 0.f;
|
float reducdE = 0.f;
|
||||||
calcreducdE(dE, maxdE, mindE, maxdElim, mindElim, lp.iterat, limscope, varsens , reducdE);
|
calcreducdE(dE, maxdE, mindE, maxdElim, mindElim, lp.iterat, limscope, varsens , reducdE);
|
||||||
|
reducdE *= localFactor;
|
||||||
|
|
||||||
switch (zone) {
|
float difL;
|
||||||
|
|
||||||
case 1: { // inside transition zone
|
if (call == 2) {
|
||||||
float factorx = localFactor;
|
difL = loctemp[loy - begy][lox - begx] - original->L[y][x];
|
||||||
float difL;
|
} else {
|
||||||
|
difL = loctemp[y][x] - original->L[y][x];
|
||||||
if (call == 2) {
|
|
||||||
difL = loctemp[loy - begy][lox - begx] - original->L[y][x];
|
|
||||||
} else {
|
|
||||||
difL = loctemp[y][x] - original->L[y][x];
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
difL *= factorx;
|
|
||||||
transformed->L[y][x] = CLIP(original->L[y][x] + difL * reducdE);
|
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case 2: { // inside selection => full effect, no transition
|
|
||||||
float difL;
|
|
||||||
|
|
||||||
if (call == 2) {
|
|
||||||
difL = loctemp[loy - begy][lox - begx] - original->L[y][x];
|
|
||||||
} else {
|
|
||||||
difL = loctemp[y][x] - original->L[y][x];
|
|
||||||
}
|
|
||||||
|
|
||||||
transformed->L[y][x] = CLIP(original->L[y][x] + difL * reducdE);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
transformed->L[y][x] = CLIP(original->L[y][x] + difL * reducdE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
delete origblur;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void ImProcFunctions::Exclude_Local(float **deltaso, float hueref, float chromaref, float lumaref, float sobelref, float meansobel, const struct local_params & lp, const LabImage * original, LabImage * transformed, const LabImage * rsv, const LabImage * reserv, int cx, int cy, int sk)
|
void ImProcFunctions::Exclude_Local(float **deltaso, float hueref, float chromaref, float lumaref, float sobelref, float meansobel, const struct local_params & lp, const LabImage * original, LabImage * transformed, const LabImage * rsv, const LabImage * reserv, int cx, int cy, int sk)
|
||||||
{
|
{
|
||||||
|
|
||||||
@ -5626,10 +5588,11 @@ void ImProcFunctions::Lab_Local(int call, int sp, float** shbuffer, LabImage * o
|
|||||||
int bfh = call == 2 ? int (lp.ly + lp.lyT) + del : original->H; //bfw bfh real size of square zone
|
int bfh = call == 2 ? int (lp.ly + lp.lyT) + del : original->H; //bfw bfh real size of square zone
|
||||||
int bfw = call == 2 ? int (lp.lx + lp.lxL) + del : original->W;
|
int bfw = call == 2 ? int (lp.lx + lp.lxL) + del : original->W;
|
||||||
JaggedArray<float> loctemp(bfw, bfh);
|
JaggedArray<float> loctemp(bfw, bfh);
|
||||||
LabImage *bufloca = nullptr;
|
std::unique_ptr<LabImage> bufloca;
|
||||||
|
|
||||||
|
LabImage *localContrastSource;
|
||||||
if (call == 2) { //call from simpleprocess
|
if (call == 2) { //call from simpleprocess
|
||||||
bufloca = new LabImage(bfw, bfh);
|
bufloca.reset(new LabImage(bfw, bfh));
|
||||||
|
|
||||||
// JaggedArray<float> hbuffer(bfw, bfh);
|
// JaggedArray<float> hbuffer(bfw, bfh);
|
||||||
int begy = lp.yc - lp.lyT;
|
int begy = lp.yc - lp.lyT;
|
||||||
@ -5641,29 +5604,32 @@ void ImProcFunctions::Lab_Local(int call, int sp, float** shbuffer, LabImage * o
|
|||||||
#pragma omp parallel for schedule(dynamic,16)
|
#pragma omp parallel for schedule(dynamic,16)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
for (int y = 0; y < transformed->H ; y++) //{
|
for (int y = 0; y < transformed->H ; y++) {
|
||||||
for (int x = 0; x < transformed->W; x++) {
|
const int loy = cy + y;
|
||||||
int lox = cx + x;
|
if (loy >= begy && loy < yEn) {
|
||||||
int loy = cy + y;
|
for (int x = 0; x < transformed->W; x++) {
|
||||||
|
const int lox = cx + x;
|
||||||
if (lox >= begx && lox < xEn && loy >= begy && loy < yEn) {
|
if (lox >= begx && lox < xEn) {
|
||||||
bufloca->L[loy - begy][lox - begx] = original->L[y][x];
|
bufloca->L[loy - begy][lox - begx] = original->L[y][x];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
ImProcFunctions::localContrastloc(bufloca, sk, params->locallab.spots.at(sp).lcradius, params->locallab.spots.at(sp).lcamount, params->locallab.spots.at(sp).lcdarkness, params->locallab.spots.at(sp).lightness, loctemp);
|
localContrastSource = bufloca.get();
|
||||||
|
|
||||||
} else { //call from dcrop.cc
|
} else { //call from dcrop.cc
|
||||||
|
localContrastSource = original;
|
||||||
ImProcFunctions::localContrastloc(original, sk, params->locallab.spots.at(sp).lcradius, params->locallab.spots.at(sp).lcamount, params->locallab.spots.at(sp).lcdarkness, params->locallab.spots.at(sp).lightness, loctemp);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
LocalContrastParams localContrastParams;
|
||||||
|
localContrastParams.enabled = true;
|
||||||
|
localContrastParams.radius = params->locallab.spots.at(sp).lcradius;
|
||||||
|
localContrastParams.amount = params->locallab.spots.at(sp).lcamount;
|
||||||
|
localContrastParams.darkness = params->locallab.spots.at(sp).lcdarkness;
|
||||||
|
localContrastParams.lightness = params->locallab.spots.at(sp).lightness;
|
||||||
|
ImProcFunctions::localContrast(localContrastSource, loctemp, localContrastParams, sk);
|
||||||
|
|
||||||
//sharpen ellipse and transition
|
//sharpen ellipse and transition
|
||||||
Sharp_Local(call, loctemp, 1, hueref, chromaref, lumaref, lp, original, transformed, cx, cy, sk);
|
Sharp_Local(call, loctemp, 1, hueref, chromaref, lumaref, lp, original, transformed, cx, cy, sk);
|
||||||
|
|
||||||
delete bufloca;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user