diff --git a/rtengine/dcrop.cc b/rtengine/dcrop.cc index bfee6c61d..4399b84cd 100644 --- a/rtengine/dcrop.cc +++ b/rtengine/dcrop.cc @@ -807,8 +807,8 @@ void Crop::update (int todo) bool wavcontlutili = parent->wavcontlutili; LUTu dummy; + int modedehaz; parent->ipf.MSR(labnCrop, labnCrop->W, labnCrop->H, 1); - parent->ipf.chromiLuminanceCurve (this, 1, labnCrop, labnCrop, parent->chroma_acurve, parent->chroma_bcurve, parent->satcurve, parent->lhskcurve, parent->clcurve, parent->lumacurve, utili, autili, butili, ccutili, cclutili, clcutili, dummy, dummy, dummy, dummy); parent->ipf.vibrance (labnCrop); diff --git a/rtengine/ipdehaz.cc b/rtengine/ipdehaz.cc index a385d92eb..16d9a3afd 100644 --- a/rtengine/ipdehaz.cc +++ b/rtengine/ipdehaz.cc @@ -20,169 +20,100 @@ * Retinex for bridging the gap between color images and the * human observation of scenes. IEEE Transactions on Image Processing, * 1997, 6(7): 965-976 - * inspired from 2003 Fabien Pelisson + * inspired from 2003 Fabien Pelisson */ - - - # include - # include - # include - # include - # include - #include "rtengine.h" - - #include "improcfun.h" - # define MAX_DEHAZE_SCALES 8 - # define clipdehaz( val, minv, maxv ) (( val = (val < minv ? minv : val ) ) > maxv ? maxv : val ) + + + + + +#include +#include +#include +#include +#include +#include "rtengine.h" +#include "gauss.h" + +#include "improcfun.h" +#define MAX_DEHAZE_SCALES 6 +#define clipdehaz( val, minv, maxv ) (( val = (val < minv ? minv : val ) ) > maxv ? maxv : val ) namespace rtengine { extern const Settings* settings; - - static float DehazeScales[MAX_DEHAZE_SCALES]; - - typedef struct - { - int N; - float sigma; - double B; - double b[4]; - } gauss3; - + +static float DehazeScales[MAX_DEHAZE_SCALES]; + void dehaze_scales( float* scales, int nscales, int mode, int s) - { - if ( nscales == 1 ) - { - scales[0] = (float)s / 2.f; - } + { + if ( nscales == 1 ) + { + scales[0] = (float)s / 2.f; + } else if (nscales == 2) - { - scales[0] = (float) s / 2.f; - scales[1] = (float) s; - } - else - { - float size_step = (float) s / (float) nscales; - - if(mode==0) { - for (int i = 0; i < nscales; ++i ) + { + scales[0] = (float) s / 2.f; + scales[1] = (float) s; + } + else + { + float size_step = (float) s / (float) nscales; + + if(mode==0) { + for (int i = 0; i < nscales; ++i ) scales[i] = 2.0f + (float)i * size_step; - } - else if (mode==1) { - size_step = (float)log(s - 2.0f) / (float) nscales; - for (int i = 0; i < nscales; ++i ) - scales[i] = 2.0f + (float)pow (10.f, (i * size_step) / log (10.f)); } - else if(mode==2){ - size_step = (float) log(s - 2.0f) / (float) nscales; - for ( int i = 0; i < nscales; ++i ) - scales[i] = s - (float)pow (10.f, (i * size_step) / log (10.f)); - } - } + else if (mode==1) { + size_step = (float)log(s - 2.0f) / (float) nscales; + for (int i = 0; i < nscales; ++i ) + scales[i] = 2.0f + (float)pow (10.f, (i * size_step) / log (10.f)); + } + else if(mode==2){ + size_step = (float) log(s - 2.0f) / (float) nscales; + for ( int i = 0; i < nscales; ++i ) + scales[i] = s - (float)pow (10.f, (i * size_step) / log (10.f)); + } + } } -void mean_stddv( float *dst, float &mean, float &stddv, int W_L, int H_L ) - { - float vsquared; - int i, j; - - vsquared = 0.0f; - mean = 0.0f; - for (int i=0; i= 2.5f ) - { - q = 0.98711f * sigma - 0.96330f; - } - else if ( (sigma >= 0.5f) && (sigma < 2.5f) ) - { - q = 3.97156f - 4.14554f * (float) sqrt ((double) 1 - 0.26891 * sigma); - } - else - { - q = 0.1147705018520355224609375f; - } - - q2 = q * q; - q3 = q * q2; - c->b[0] = (1.57825f+(2.44413f*q)+(1.4281f *q2)+(0.422205f*q3)); - c->b[1] = ( (2.44413f*q)+(2.85619f*q2)+(1.26661f *q3)); - c->b[2] = ( -((1.4281f*q2)+(1.26661f *q3))); - c->b[3] = ( (0.422205f*q3)); - c->B = 1.0f-((c->b[1]+c->b[2]+c->b[3])/c->b[0]); - c->sigma = sigma; - c->N = 3; - } + vsquared = 0.0f; + mean = 0.0f; + for (int i = 0; i B*in[i*rowstride] + - ((c->b[1]*w1[n-1] + - c->b[2]*w1[n-2] + - c->b[3]*w1[n-3] ) / c->b[0])); - } - - w2[size+1]= w1[size+3]; - w2[size+2]= w1[size+3]; - w2[size+3]= w1[size+3]; - for ( i = size, n = i; i >= 0; i--, n-- ) - { - w2[n]= out[i * rowstride] = (float)(c->B*w1[n] + - ((c->b[1]*w2[n+1] + - c->b[2]*w2[n+2] + - c->b[3]*w2[n+3] ) / c->b[0])); - } - delete [] w1; - delete [] w2; - } void ImProcFunctions::MSR(LabImage* lab, int width, int height, int skip) { - int Is; - float weight; - gauss3 coef; - float mean, stddv; - float mini, delta, maxi; - float eps = 5.f; + float pond; + float mean, stddv; + float mini, delta, maxi; + float eps = 2.f; float gain = (float) params->labCurve.gain;//def =1 not use - float offset = (float) params->labCurve.offs;//def = 0 not use + float offset = 1.f; + float neg=(float) params->labCurve.offs;//def = 0 not use float strength = (float) params->labCurve.str; int scal = params->labCurve.scal;//def=3 int nei = (int) 2.5f*params->labCurve.neigh;//def = 200 + int vart= params->labCurve.vart; int modedehaz; if(params->labCurve.dehazmet=="none") modedehaz=-1;//enabled disabled if(params->labCurve.dehazmet=="uni") modedehaz=0; @@ -191,91 +122,125 @@ void ImProcFunctions::MSR(LabImage* lab, int width, int height, int skip) if (modedehaz !=-1) {//enabled int H_L=height; int W_L=width; - float *src = new float[H_L*W_L]; - memset( src, 0, H_L*W_L * sizeof (float) ); - - float *dst = new float[H_L*W_L]; - memset( dst, 0, H_L*W_L * sizeof (float) ); - - float *out = new float[H_L*W_L]; - memset( out, 0, H_L*W_L * sizeof (float) ); - - float *in = new float[H_L*W_L]; - memset( in, 0, H_L*W_L * sizeof (float) ); - + float** src; + src = new float*[H_L]; + for (int i = 0; i < H_L; i++) { + src[i] = new float[W_L]; + memset( src[i], 0, W_L * sizeof (float) ); + } + float** dst; + dst = new float*[H_L]; + for (int i = 0; i < H_L; i++) { + dst[i] = new float[W_L]; + memset( dst[i], 0, W_L * sizeof (float) ); + } + float** in; + in = new float*[H_L]; + for (int i = 0; i < H_L; i++) { + in[i] = new float[W_L]; + memset( in[i], 0, W_L * sizeof (float) ); + } + float** out; + out = new float*[H_L]; + for (int i = 0; i < H_L; i++) { + out[i] = new float[W_L]; + memset( out[i], 0, W_L * sizeof (float) ); + } + for (int i=0; i< H_L; i++) { for (int j=0; jL[i][j] + eps; + src[i][j]=lab->L[i][j] + eps; } - } - Is = width * height ; - dehaze_scales( DehazeScales, scal, modedehaz, nei ); + } + dehaze_scales( DehazeScales, scal, modedehaz, nei ); - weight = 1.0f / (float) scal; - - int posw = 0; - for (int i = 0; i < Is ; i++ ) - { - in[i] = (float)(src[i] + eps); //avoid log(0) - } - for ( int scale = 0; scale < scal; scale++ ) - { - compute_coefs3( &coef, DehazeScales[scale] ); - for (int row = 0; row < height; row++ ) - { - posw = row * width; - gausssmooth( in + posw, out + posw, width, 1, &coef); - } - memcpy( in, out, Is * sizeof(float) ); - memset( out, 0 , Is * sizeof(float) ); - - for (int col = 0; col < width; col++ ) - { - posw = col; - gausssmooth( in + posw, out + posw, height, width, &coef ); - } - - for ( int i = 0; i < Is; i++ ) - { - dst[i] += weight * (float)( log(src[i] + eps) - log(out[i]) ); - } - } - delete [] in; - delete [] out; - - - // Ci(x,y)=log[a Ii(x,y)]-log[ Ei=1-s Ii(x,y)] - - float beta = 16384.0f; - for ( int i = 0; i < Is; i ++ ) - { - float logsrc = (float)log( (float) src[i] + eps ); - dst[i] = gain * ((float)(log(beta * (src[i] + eps)) - logsrc) * dst[i]) + offset; - } + pond = 1.0f / (float) scal; + +#ifdef _OPENMP +#pragma omp for +#endif + for (int i = 0; i < H_L ; i++ ) + for (int j=0; j buffer(max(W_L,H_L)); + gaussHorizontal (in, out, buffer, W_L, H_L, DehazeScales[scale]); + gaussVertical (out, out, buffer,W_L, H_L, DehazeScales[scale]); + } + for ( int i=0; i < H_L; i++) + for (int j=0; j < W_L; j++) + { + dst[i][j] += pond * (float)( log(src[i][j] + eps) - log(out[i][j]) ); + } + } + + for (int i = 0; i < H_L; i++) { + delete [] in[i]; + } + delete [] in; + for (int i = 0; i < H_L; i++) { + delete [] out[i]; + } + delete [] out; + + + + + +float beta=16384.0f; + + +#ifdef _OPENMP +#pragma omp for +#endif + for (int i=0; i< H_L; i++ ) + for (int j=0; jL[ii][jj]=((100.f - strength)* lab->L[ii][jj] + strength * src[i])/100.f; + if ( !delta ) delta = 1.0f; +#ifdef _OPENMP +#pragma omp for +#endif + for ( int i=0; i < H_L; i ++ ) + for (int j=0; j< W_L; j++) { + float cd = vart*32768.f * ( dst[i][j] - mini ) / delta; + src[i][j] = clipdehaz( cd, 0.f, 32768.f ); + lab->L[i][j]=((100.f - strength)* lab->L[i][j] + strength * src[i][j])/100.f; } - + + for (int i = 0; i < H_L; i++) { + delete [] dst[i]; + } delete [] dst; - delete [] src; - + for (int i = 0; i < H_L; i++) { + delete [] src[i]; + } + delete [] src; } } -} \ No newline at end of file +} + + \ No newline at end of file diff --git a/rtengine/procevents.h b/rtengine/procevents.h index d33c1f8a1..1d61b9966 100644 --- a/rtengine/procevents.h +++ b/rtengine/procevents.h @@ -438,6 +438,7 @@ enum ProcEvent { EvLoffs = 409, EvLstr = 410, EvLscal = 411, + EvLvart = 412, NUMOFEVENTS }; diff --git a/rtengine/procparams.cc b/rtengine/procparams.cc index 006b1ad2d..f4d53d671 100644 --- a/rtengine/procparams.cc +++ b/rtengine/procparams.cc @@ -887,6 +887,7 @@ void ProcParams::setDefaults () labCurve.neigh = 80; labCurve.gain = 1; labCurve.offs = 0; + labCurve.vart = 1; labCurve.avoidcolorshift = false; labCurve.lcredsk = true; labCurve.rstprotection = 0; @@ -1559,6 +1560,9 @@ int ProcParams::save (Glib::ustring fname, Glib::ustring fname2, bool fnameAbsol if (!pedited || pedited->labCurve.offs) { keyFile.set_integer ("Luminance Curve","Offs", labCurve.offs); } + if (!pedited || pedited->labCurve.vart) { + keyFile.set_integer ("Luminance Curve","Vart", labCurve.vart); + } if (!pedited || pedited->labCurve.avoidcolorshift) { keyFile.set_boolean ("Luminance Curve", "AvoidColorShift", labCurve.avoidcolorshift); @@ -3714,6 +3718,13 @@ int ProcParams::load (Glib::ustring fname, ParamsEdited* pedited) pedited->labCurve.offs = true; } } + if (keyFile.has_key ("Luminance Curve", "Vart")) { + labCurve.vart = keyFile.get_integer ("Luminance Curve", "Vart"); + + if (pedited) { + pedited->labCurve.vart = true; + } + } if (ppVersion < 303) { // transform Saturation into Chromaticity @@ -7078,6 +7089,7 @@ bool ProcParams::operator== (const ProcParams& other) && labCurve.gain == other.labCurve.gain && labCurve.offs == other.labCurve.offs && labCurve.dehazmet == other.labCurve.dehazmet + && labCurve.vart == other.labCurve.vart && labCurve.brightness == other.labCurve.brightness && labCurve.contrast == other.labCurve.contrast diff --git a/rtengine/procparams.h b/rtengine/procparams.h index 4e31a477d..91439cf2c 100644 --- a/rtengine/procparams.h +++ b/rtengine/procparams.h @@ -289,6 +289,7 @@ public: int gain; int offs; Glib::ustring dehazmet; + int vart; }; diff --git a/rtengine/refreshmap.cc b/rtengine/refreshmap.cc index 600d5e902..2bd73a3c4 100644 --- a/rtengine/refreshmap.cc +++ b/rtengine/refreshmap.cc @@ -433,7 +433,9 @@ int refreshmap[rtengine::NUMOFEVENTS] = { LUMINANCECURVE, // EvLgain LUMINANCECURVE, // EvLoffs LUMINANCECURVE, // EvLstr - LUMINANCECURVE // EvLscal + LUMINANCECURVE, // EvLscal + LUMINANCECURVE // EvLvart + }; diff --git a/rtgui/labcurve.cc b/rtgui/labcurve.cc index bf0e892e6..c1e045407 100644 --- a/rtgui/labcurve.cc +++ b/rtgui/labcurve.cc @@ -235,10 +235,11 @@ LCurve::LCurve () : FoldableToolPanel(this, "labcurves", M("TP_LABCURVE_LABEL")) dehazVBox->pack_start(*dhbox); str = Gtk::manage (new Adjuster (M("TP_LABCURVE_STR"), 0, 100., 1., 70.)); - scal = Gtk::manage (new Adjuster (M("TP_LABCURVE_SCAL"), 1, 8., 1., 3.)); + scal = Gtk::manage (new Adjuster (M("TP_LABCURVE_SCAL"), 1, 6., 1., 3.)); neigh = Gtk::manage (new Adjuster (M("TP_LABCURVE_NEIGH"), 6, 100., 1., 80.)); - gain = Gtk::manage (new Adjuster (M("TP_LABCURVE_GAIN"), 0.9, 1.1, 0.01, 1.)); - offs = Gtk::manage (new Adjuster (M("TP_LABCURVE_OFFS"), -50, 50, 1, 0)); + gain = Gtk::manage (new Adjuster (M("TP_LABCURVE_GAIN"), 0.8, 1.4, 0.01, 1.)); + offs = Gtk::manage (new Adjuster (M("TP_LABCURVE_OFFS"), -10, 5, 0.1, 0)); + vart = Gtk::manage (new Adjuster (M("TP_LABCURVE_VART"), 0.5, 15., 0.01, 1)); dehazVBox->pack_start (*str); str->show (); @@ -248,17 +249,20 @@ LCurve::LCurve () : FoldableToolPanel(this, "labcurves", M("TP_LABCURVE_LABEL")) dehazVBox->pack_start (*neigh); neigh->show (); - // dehazVBox->pack_start (*gain); - // gain->show (); +// dehazVBox->pack_start (*gain); +// gain->show (); - // dehazVBox->pack_start (*offs); +// dehazVBox->pack_start (*offs); // offs->show (); +// dehazVBox->pack_start (*vart); + // vart->show (); str->setAdjusterListener (this); scal->setAdjusterListener (this); neigh->setAdjusterListener (this); gain->setAdjusterListener (this); offs->setAdjusterListener (this); + vart->setAdjusterListener (this); dehazFrame->add(*dehazVBox); pack_start (*dehazFrame); @@ -289,9 +293,13 @@ void LCurve::read (const ProcParams* pp, const ParamsEdited* pedited) neigh->setEditedState (pedited->labCurve.neigh ? Edited : UnEdited); gain->setEditedState (pedited->labCurve.gain ? Edited : UnEdited); offs->setEditedState (pedited->labCurve.offs ? Edited : UnEdited); + vart->setEditedState (pedited->labCurve.vart ? Edited : UnEdited); + // if (!pedited->labCurve.dehazmet) { + // dehazmet->set_active (3); + // } if (!pedited->labCurve.dehazmet) { - dehazmet->set_active (3); + dehazmet->set_active_text(M("GENERAL_UNCHANGED")); } //%%%%%%%%%%%%%%%%%%%%%% @@ -316,8 +324,9 @@ void LCurve::read (const ProcParams* pp, const ParamsEdited* pedited) offs->setValue (pp->labCurve.offs); str->setValue (pp->labCurve.str); scal->setValue (pp->labCurve.scal); + vart->setValue (pp->labCurve.vart); - dehazmet->set_active (0); +// dehazmet->set_active (0); if (pp->labCurve.dehazmet == "none") { dehazmet->set_active (0); } else if (pp->labCurve.dehazmet == "uni") { @@ -426,6 +435,7 @@ void LCurve::write (ProcParams* pp, ParamsEdited* pedited) pp->labCurve.neigh = neigh->getValue (); pp->labCurve.gain = (int)gain->getValue (); pp->labCurve.offs = (int)offs->getValue (); + pp->labCurve.vart = (int)vart->getValue (); //%%%%%%%%%%%%%%%%%%%%%% pp->labCurve.avoidcolorshift = avoidcolorshift->get_active (); @@ -454,7 +464,8 @@ void LCurve::write (ProcParams* pp, ParamsEdited* pedited) pedited->labCurve.lcredsk = !lcredsk->get_inconsistent(); pedited->labCurve.rstprotection = rstprotection->getEditedState (); - pedited->labCurve.dehazmet = dehazmet->get_active_row_number() != 3; + // pedited->labCurve.dehazmet = dehazmet->get_active_row_number() != 3; + pedited->labCurve.dehazmet = dehazmet->get_active_text() != M("GENERAL_UNCHANGED"); //%%%%%%%%%%%%%%%%%%%%%% pedited->labCurve.str = str->getEditedState (); @@ -462,6 +473,7 @@ void LCurve::write (ProcParams* pp, ParamsEdited* pedited) pedited->labCurve.neigh = neigh->getEditedState (); pedited->labCurve.gain = gain->getEditedState (); pedited->labCurve.offs = offs->getEditedState (); + pedited->labCurve.vart = vart->getEditedState (); pedited->labCurve.lcurve = !lshape->isUnChanged (); @@ -473,6 +485,9 @@ void LCurve::write (ProcParams* pp, ParamsEdited* pedited) pedited->labCurve.hhcurve = !hhshape->isUnChanged (); pedited->labCurve.lccurve = !lcshape->isUnChanged (); pedited->labCurve.clcurve = !clshape->isUnChanged (); + + + } if (dehazmet->get_active_row_number() == 0) { pp->labCurve.dehazmet = "none"; } else if (dehazmet->get_active_row_number() == 1) { @@ -482,9 +497,8 @@ void LCurve::write (ProcParams* pp, ParamsEdited* pedited) } else if (dehazmet->get_active_row_number() == 3) { pp->labCurve.dehazmet = "high"; } - - - } + + } void LCurve::dehazmetChanged() @@ -507,6 +521,7 @@ void LCurve::setDefaults (const ProcParams* defParams, const ParamsEdited* pedit offs->setDefault (defParams->labCurve.offs); str->setDefault (defParams->labCurve.str); scal->setDefault (defParams->labCurve.scal); + vart->setDefault (defParams->labCurve.vart); if (pedited) { brightness->setDefaultEditedState (pedited->labCurve.brightness ? Edited : UnEdited); @@ -518,6 +533,7 @@ void LCurve::setDefaults (const ProcParams* defParams, const ParamsEdited* pedit offs->setDefaultEditedState (pedited->labCurve.offs ? Edited : UnEdited); str->setDefaultEditedState (pedited->labCurve.str ? Edited : UnEdited); scal->setDefaultEditedState (pedited->labCurve.scal ? Edited : UnEdited); + vart->setDefaultEditedState (pedited->labCurve.vart ? Edited : UnEdited); } else { brightness->setDefaultEditedState (Irrelevant); @@ -527,6 +543,7 @@ void LCurve::setDefaults (const ProcParams* defParams, const ParamsEdited* pedit neigh->setDefaultEditedState (Irrelevant); gain->setDefaultEditedState (Irrelevant); offs->setDefaultEditedState (Irrelevant); + vart->setDefaultEditedState (Irrelevant); str->setDefaultEditedState (Irrelevant); scal->setDefaultEditedState (Irrelevant); } @@ -682,6 +699,10 @@ void LCurve::adjusterChanged (Adjuster* a, double newval) if (listener) { listener->panelChanged (EvLoffs, costr); } + } else if (a == vart) { + if (listener) { + listener->panelChanged (EvLvart, costr); + } } else if (a == chromaticity) { if (multiImage) { @@ -774,6 +795,7 @@ void LCurve::setBatchMode (bool batchMode) offs->showEditedCB (); str->showEditedCB (); scal->showEditedCB (); + vart->showEditedCB (); curveEditorG->setBatchMode (batchMode); lcshape->setBottomBarColorProvider(NULL, -1); @@ -810,4 +832,5 @@ void LCurve::trimValues (rtengine::procparams::ProcParams* pp) neigh->trimValue(pp->labCurve.neigh); gain->trimValue(pp->labCurve.gain); offs->trimValue(pp->labCurve.offs); + vart->trimValue(pp->labCurve.vart); } diff --git a/rtgui/labcurve.h b/rtgui/labcurve.h index 9546005a1..6fd5cd031 100644 --- a/rtgui/labcurve.h +++ b/rtgui/labcurve.h @@ -39,6 +39,7 @@ protected: Adjuster* neigh; Adjuster* gain; Adjuster* offs; + Adjuster* vart; DiagonalCurveEditor* lshape; DiagonalCurveEditor* ashape; diff --git a/rtgui/paramsedited.cc b/rtgui/paramsedited.cc index c699766f1..ad4e17bcd 100644 --- a/rtgui/paramsedited.cc +++ b/rtgui/paramsedited.cc @@ -64,6 +64,7 @@ void ParamsEdited::set (bool v) labCurve.neigh = v; labCurve.gain = v; labCurve.offs = v; + labCurve.vart = v; labCurve.brightness = v; labCurve.contrast = v; labCurve.chromaticity = v; @@ -525,6 +526,7 @@ void ParamsEdited::initFrom (const std::vector labCurve.neigh = labCurve.neigh && p.labCurve.neigh == other.labCurve.neigh; labCurve.gain = labCurve.gain && p.labCurve.gain == other.labCurve.gain; labCurve.offs = labCurve.offs && p.labCurve.offs == other.labCurve.offs; + labCurve.vart = labCurve.vart && p.labCurve.vart == other.labCurve.vart; labCurve.brightness = labCurve.brightness && p.labCurve.brightness == other.labCurve.brightness; labCurve.contrast = labCurve.contrast && p.labCurve.contrast == other.labCurve.contrast; labCurve.chromaticity = labCurve.chromaticity && p.labCurve.chromaticity == other.labCurve.chromaticity; @@ -1073,6 +1075,9 @@ void ParamsEdited::combine (rtengine::procparams::ProcParams& toEdit, const rten if (labCurve.offs) { toEdit.labCurve.offs = mods.labCurve.offs; } + if (labCurve.vart) { + toEdit.labCurve.vart = mods.labCurve.vart; + } if (labCurve.avoidcolorshift) { toEdit.labCurve.avoidcolorshift = mods.labCurve.avoidcolorshift; diff --git a/rtgui/paramsedited.h b/rtgui/paramsedited.h index c5516317c..7820aadc9 100644 --- a/rtgui/paramsedited.h +++ b/rtgui/paramsedited.h @@ -67,6 +67,7 @@ public: bool gain; bool offs; bool dehazmet; + bool vart; bool avoidcolorshift; bool rstprotection;