diff --git a/rtengine/FTblockDN.cc b/rtengine/FTblockDN.cc index 7ddb6835a..7eb267577 100644 --- a/rtengine/FTblockDN.cc +++ b/rtengine/FTblockDN.cc @@ -164,17 +164,11 @@ namespace rtengine { const float gain = pow (2.0f, float(expcomp)); float incr=1.f; - float noisevar_Ldetail = SQR((SQR(100.f-dnparams.Ldetail) + 50.f*(100.f-dnparams.Ldetail)) * TS * 0.5f * incr); + float noisevar_Ldetail = SQR((float)(SQR(100.-dnparams.Ldetail) + 50.*(100.-dnparams.Ldetail)) * TS * 0.5f * incr); bool enhance_denoise = dnparams.enhance; - noisered=1.f;//chroma red - if(dnparams.redchro<-0.1f) {noisered=0.001f+SQR((100.f + dnparams.redchro)/100.0f);} - else if(dnparams.redchro>0.1f) {noisered=1.f+SQR((dnparams.redchro));} - else if (dnparams.redchro>= -0.1f && dnparams.redchro<=0.1f) noisered=0.f; - - noiseblue=1.f;//chroma blue - if(dnparams.bluechro<-0.1f) {noiseblue=0.001f+SQR((100.f + dnparams.bluechro)/100.0f);} - else if(dnparams.bluechro>0.1f) {noiseblue=1.f+SQR((dnparams.bluechro));} - else if (dnparams.bluechro>= -0.1f && dnparams.bluechro<=0.1f) noiseblue=0.f; + int gamlab = settings->denoiselabgamma;//gamma lab essentialy for Luminance detail + if(gamlab > 2) gamlab=2; + if(settings->verbose) printf("Denoise Lab=%i\n",gamlab); array2D tilemask_in(TS,TS); array2D tilemask_out(TS,TS); @@ -324,7 +318,6 @@ namespace rtengine { array2D totwt(width,height,ARRAY2D_CLEAR_DATA);//weight for combining DCT blocks // - //#ifdef _OPENMP //#pragma omp parallel for //#endif @@ -332,21 +325,35 @@ namespace rtengine { //fill tile from image; convert RGB to "luma/chroma" if (isRAW) {//image is raw; use channel differences for chroma channels if(!perf){//lab mode + //modification Jacques feb 2013 for (int i=tiletop/*, i1=0*/; ir(i,j); float G_ = gain*src->g(i,j); float B_ = gain*src->b(i,j); - //modify arbitrary data for Lab..I have test : nothing, gamma standard, gamma SRGB and GammaBT709... + //modify arbitrary data for Lab..I have test : nothing, gamma 2.6 11 - gamma 4 5 - gamma 5.5 10 //we can put other as gamma g=2.6 slope=11, etc. - // Gamma sRGB is a good compromise, but noting to do with real gamma !!!: it's only for data Lab # data RGB - //finally I opted fot gamma_26_11 + // but noting to do with real gamma !!!: it's only for data Lab # data RGB + //finally I opted fot gamma55 and with options we can change + if (gamlab == 0) {// options 12/2013 R_ = Color::igammatab_26_11[R_]; G_ = Color::igammatab_26_11[G_]; B_ = Color::igammatab_26_11[B_]; + } + else if (gamlab == 1) { + //other new gamma 4 5 + R_ = Color::igammatab_4[R_]; + G_ = Color::igammatab_4[G_]; + B_ = Color::igammatab_4[B_]; + } + else if (gamlab == 2) { + //new gamma 5.5 10 better for detail luminance..it is a compromise...which depends on the image (distribution BL, ML, HL ...) + R_ = Color::igammatab_55[R_]; + G_ = Color::igammatab_55[G_]; + B_ = Color::igammatab_55[B_]; + } //apply gamma noise standard (slider) R_ = R_<65535.0f ? gamcurve[R_] : (Color::gamman((double)R_/65535.0, gam)*32768.0f); G_ = G_<65535.0f ? gamcurve[G_] : (Color::gamman((double)G_/65535.0, gam)*32768.0f); @@ -430,7 +437,7 @@ namespace rtengine { //initial impulse denoise if (dnparams.luma>0.01) { - impulse_nr (labdn, MIN(50.0f,dnparams.luma)/20.0f); + impulse_nr (labdn, float(MIN(50.0,dnparams.luma))/20.0f); } int datalen = labdn->W * labdn->H; @@ -440,14 +447,14 @@ namespace rtengine { //and whether to subsample the image after wavelet filtering. Subsampling is coded as //binary 1 or 0 for each level, eg subsampling = 0 means no subsampling, 1 means subsample //the first level only, 7 means subsample the first three levels, etc. - float noisevarL = SQR((dnparams.luma/125.0f)*(1+ dnparams.luma/25.0f)); + float noisevarL = (float) (SQR((dnparams.luma/125.0)*(1.+ dnparams.luma/25.0))); - float interm_med= dnparams.chroma/10.0f; + float interm_med= (float) dnparams.chroma/10.0; float intermred, intermblue; - if(dnparams.redchro > 0.f) intermred=0.0014f*SQR(dnparams.redchro); else intermred= dnparams.redchro/7.0f;//increase slower than linear for more sensit - float intermred2=dnparams.redchro/7.0f; - if(dnparams.bluechro > 0.f) intermblue=0.0014f*SQR(dnparams.bluechro); else intermblue= dnparams.bluechro/7.0f;//increase slower than linear - float intermblue2=dnparams.bluechro/7.0f; + if(dnparams.redchro > 0.) intermred=0.0014f* (float)SQR(dnparams.redchro); else intermred= (float) dnparams.redchro/7.0;//increase slower than linear for more sensit + float intermred2=(float) dnparams.redchro/7.0; + if(dnparams.bluechro > 0.) intermblue=0.0014f*(float) SQR(dnparams.bluechro); else intermblue= (float)dnparams.bluechro/7.0;//increase slower than linear + float intermblue2=(float) dnparams.bluechro/7.0; //adjust noise ab in function of sliders red and blue float realred = interm_med + intermred; if (realred < 0.f) realred=0.01f; float realred2 = interm_med + intermred2; if (realred2 < 0.f) realred2=0.01f; @@ -492,7 +499,7 @@ namespace rtengine { //second impulse denoise if (dnparams.luma>0.01) { - impulse_nr (labdn, MIN(50.0f,dnparams.luma)/20.0f); + impulse_nr (labdn, MIN(50.0f,(float)dnparams.luma)/20.0f); } //PF_correct_RT(dst, dst, defringe.radius, defringe.threshold); @@ -661,10 +668,21 @@ namespace rtengine { g_ = g_<32768.0f ? igamcurve[g_] : (Color::gamman((float)g_/32768.0f, igam) * 65535.0f); b_ = b_<32768.0f ? igamcurve[b_] : (Color::gamman((float)b_/32768.0f, igam) * 65535.0f); //readapt arbitrary gamma (inverse from beginning) + if (gamlab == 0) { r_ = Color::gammatab_26_11[r_]; g_ = Color::gammatab_26_11[g_]; b_ = Color::gammatab_26_11[b_]; - + } + else if (gamlab == 1) { + r_ = Color::gammatab_4[r_]; + g_ = Color::gammatab_4[g_]; + b_ = Color::gammatab_4[b_]; + } + else if (gamlab == 2) { + r_ = Color::gammatab_55[r_]; + g_ = Color::gammatab_55[g_]; + b_ = Color::gammatab_55[b_]; + } float factor = Vmask[i1]*Hmask[j1]/gain; dsttmp->r(i,j) += factor*r_; @@ -976,7 +994,7 @@ __attribute__((force_align_arg_pointer)) void ImProcFunctions::RGBtile_denoise ( //float skip_ab_ratio = WaveletCoeffs_a.level_stride(lvl+1)/skip_ab; float skip_L_ratio = WaveletCoeffs_L.level_stride(lvl+1)/skip_L; - if (noisevar_abr>0.01) { + if (noisevar_abr>0.01f || noisevar_abb>0.01f) { //printf(" dir=%d mad_L=%f mad_a=%f mad_b=%f \n",dir,sqrt(mad_L),sqrt(mad_a),sqrt(mad_b)); @@ -1005,14 +1023,14 @@ __attribute__((force_align_arg_pointer)) void ImProcFunctions::RGBtile_denoise ( //float satfactor_a = mad_a/(mad_a+0.5*SQR(WavCoeffs_a[0][coeffloc_ab])); //float satfactor_b = mad_b/(mad_b+0.5*SQR(WavCoeffs_b[0][coeffloc_ab])); - WavCoeffs_a[dir][coeffloc_ab] *= SQR(1-xexpf(-(mag_a/mad_a)-(mag_L/(9*mad_L)))/*satfactor_a*/); - WavCoeffs_b[dir][coeffloc_ab] *= SQR(1-xexpf(-(mag_b/mad_b)-(mag_L/(9*mad_L)))/*satfactor_b*/); + WavCoeffs_a[dir][coeffloc_ab] *= SQR(1.f-xexpf(-(mag_a/mad_a)-(mag_L/(9.f*mad_L)))/*satfactor_a*/); + WavCoeffs_b[dir][coeffloc_ab] *= SQR(1.f-xexpf(-(mag_b/mad_b)-(mag_L/(9.f*mad_L)))/*satfactor_b*/); } }//now chrominance coefficients are denoised } - if (noisevar_L>0.01) { + if (noisevar_L>0.01f) { mad_L *= noisevar_L*5/(lvl+1); //OpenMP here for (int i=0; i 582=max float mad_b = madb*noisevar_abb; - if (noisevar_abr>0.01 || noisevar_abb>0.01) { + if (noisevar_abr>0.01f || noisevar_abb>0.01f) { //OpenMP here #ifdef _OPENMP @@ -1147,24 +1165,6 @@ __attribute__((force_align_arg_pointer)) void ImProcFunctions::ShrinkAll(float * m_b=mad_b; int coeffloc_ab = i*W_ab+j; int coeffloc_L = ((i*skip_L)/skip_ab)*W_L + ((j*skip_L)/skip_ab); - //modification Jacques feb 2013 - /* - float reduc=1.f; - float bluuc=1.f; - if(noisered!=0. || noiseblue !=0.) { - // float hh=xatan2(noi->b[2*i][2*j],noi->a[2*i][2*j]); - float hh =xatan2(WavCoeffs_b[dir][coeffloc_ab],WavCoeffs_a[dir][coeffloc_ab]); - //one can also use L or c (chromaticity) if necessary - // if(hh > -0.4f && hh < 1.6f) reduc=noisered;//red from purple to next yellow - // if(hh>-2.45f && hh <=-0.4f) bluuc=noiseblue;//blue - if(hh>1.3f && hh <=2.2f) bluuc=noiseblue;//blue - } - - mad_a*=reduc; - mad_a*=bluuc; - mad_b*=reduc; - mad_b*=bluuc; - */ float mag_L = SQR(WavCoeffs_L[dir][coeffloc_L ])+eps; float mag_a = SQR(WavCoeffs_a[dir][coeffloc_ab])+eps; float mag_b = SQR(WavCoeffs_b[dir][coeffloc_ab])+eps; @@ -1194,26 +1194,6 @@ __attribute__((force_align_arg_pointer)) void ImProcFunctions::ShrinkAll(float * int coeffloc_ab = i*W_ab+j; int coeffloc_L = ((i*skip_L)/skip_ab)*W_L + ((j*skip_L)/skip_ab); - //modification Jacques feb 2013 - /* - float reduc=1.f; - float bluuc=1.f; - - if(noisered!=0. || noiseblue !=0.) { - // float hh=xatan2(noi->b[2*i][2*j],noi->a[2*i][2*j]); - float hh =xatan2(WavCoeffs_b[dir][coeffloc_ab],WavCoeffs_a[dir][coeffloc_ab]); - - // if(hh > -0.4f && hh < 1.6f) reduc=noisered; - // if(hh>-2.45f && hh <=-0.4f) bluuc=noiseblue; - if(hh>1.3f && hh <=2.2f) bluuc=noiseblue;//blue - - } - - mad_a*=reduc; - mad_a*=bluuc; - mad_b*=reduc; - mad_b*=bluuc; - */ float mag_L = SQR(WavCoeffs_L[dir][coeffloc_L ])+eps; float mag_a = SQR(WavCoeffs_a[dir][coeffloc_ab])+eps; float mag_b = SQR(WavCoeffs_b[dir][coeffloc_ab])+eps; @@ -1230,7 +1210,7 @@ __attribute__((force_align_arg_pointer)) void ImProcFunctions::ShrinkAll(float * }//now chrominance coefficients are denoised } - if (noisevar_L>0.01) { + if (noisevar_L>0.01f) { #ifdef __SSE2__ __m128 magv; __m128 mad_Lv = _mm_set1_ps( mad_L ); @@ -1282,7 +1262,7 @@ __attribute__((force_align_arg_pointer)) void ImProcFunctions::ShrinkAll(float * float mag = SQR(WavCoeffs_L[dir][i]); - float sf = mag/(mag+mad_L*xexpf(-mag/(9*mad_L))+eps); + float sf = mag/(mag+mad_L*xexpf(-mag/(9.f*mad_L))+eps); //use smoothed shrinkage unless local shrinkage is much less WavCoeffs_L[dir][i] *= (SQR(sfave[i])+SQR(sf))/(sfave[i]+sf+eps); diff --git a/rtengine/color.cc b/rtengine/color.cc index e217930d5..4cc8dc63e 100644 --- a/rtengine/color.cc +++ b/rtengine/color.cc @@ -35,8 +35,13 @@ namespace rtengine { LUTf Color::gammatab; LUTf Color::igammatab_srgb; LUTf Color::gammatab_srgb; - // LUTf Color::igammatab_709; + // LUTf Color::igammatab_709; // LUTf Color::gammatab_709; + LUTf Color::igammatab_55; + LUTf Color::gammatab_55; + LUTf Color::igammatab_4; + LUTf Color::gammatab_4; + LUTf Color::igammatab_26_11; LUTf Color::gammatab_26_11; LUTf Color::igammatab_24_17; @@ -138,8 +143,13 @@ namespace rtengine { gammatab(65536,0); igammatab_srgb(65536,0); gammatab_srgb(65536,0); - // igammatab_709(65536,0); - // gammatab_709(65536,0); + // igammatab_709(65536,0); + // gammatab_709(65536,0); + igammatab_55(65536,0); + gammatab_55(65536,0); + igammatab_4(65536,0); + gammatab_4(65536,0); + igammatab_26_11(65536,0); gammatab_26_11(65536,0); igammatab_24_17(65536,0); @@ -151,12 +161,21 @@ namespace rtengine { igammatab_srgb[i] = (65535.0 * igamma2 (i/65535.0)); for (int i=0; i<65536; i++) gammatab[i] = (65535.0 * pow (i/65535.0, 0.454545)); -/* - for (int i=0; i<65536; i++) + + /* for (int i=0; i<65536; i++) gammatab_709[i] = (65535.0 * gamma709 (i/65535.0)); for (int i=0; i<65536; i++) igammatab_709[i] = (65535.0 * igamma709 (i/65535.0)); -*/ +*/ + for (int i=0; i<65536; i++) + gammatab_55[i] = (65535.0 * gamma55 (i/65535.0)); + for (int i=0; i<65536; i++) + igammatab_55[i] = (65535.0 * igamma55 (i/65535.0)); + for (int i=0; i<65536; i++) + gammatab_4[i] = (65535.0 * gamma4 (i/65535.0)); + for (int i=0; i<65536; i++) + igammatab_4[i] = (65535.0 * igamma4 (i/65535.0)); + for (int i=0; i<65536; i++) gammatab_26_11[i] = (65535.0 * gamma26_11 (i/65535.0)); for (int i=0; i<65536; i++) diff --git a/rtengine/color.h b/rtengine/color.h index 4d57cb374..8a725da6b 100644 --- a/rtengine/color.h +++ b/rtengine/color.h @@ -102,6 +102,11 @@ public: static LUTf gammatab_srgb; // static LUTf igammatab_709; // static LUTf gammatab_709; + static LUTf igammatab_55; + static LUTf gammatab_55; + static LUTf igammatab_4; + static LUTf gammatab_4; + static LUTf igammatab_26_11; static LUTf gammatab_26_11; static LUTf igammatab_24_17; @@ -142,19 +147,34 @@ public: // standard srgb gamma and its inverse - static inline double gamma2 (double x) { + static inline double gamma2 (double x) { // g3 1+g4 return x <= 0.003041 ? x*12.92 : 1.055011*exp(log(x)/sRGBGammaCurve)-0.055011; } - static inline double igamma2 (double x) { + static inline double igamma2 (double x) { //g2 return x <= 0.039293 ? x/12.92 : exp(log((x+0.055011)/1.055011)*sRGBGammaCurve); } -/* static inline double gamma709 (double x) { + static inline double gamma55 (double x) { // g3 1+g4 + return x <= 0.013189 ? x*10.0 : 1.593503*exp(log(x)/5.5)-0.593503;// 5.5 10 + } + static inline double igamma55 (double x) { //g2 + return x <= 0.131889 ? x/10.0 : exp(log((x+0.593503)/1.593503)*5.5); // 5.5 10 + } + static inline double gamma4 (double x) { // g3 1+g4 + return x <= 0.03089 ? x*5.0 : 1.478793*exp(log(x)/4.1)-0.478793;// 4 5 + + } + static inline double igamma4 (double x) { //g2 + return x <= 0.154449 ? x/5.0 : exp(log((x+0.478793)/1.478793)*4.1);// 4 5 + } + + /* + static inline double gamma709 (double x) { return x <= 0.0176 ? x*4.5 : 1.0954*exp(log(x)/2.2)-0.0954; } static inline double igamma709 (double x) { return x <= 0.0795 ? x/4.5 : exp(log((x+0.0954)/1.0954)*2.2); } -*/ + */ static inline double gamma24_17 (double x) { return x <= 0.001867 ? x*17.0 : 1.044445*exp(log(x)/2.4)-0.044445; } diff --git a/rtengine/settings.h b/rtengine/settings.h index 57fa9e785..8a57e593b 100644 --- a/rtengine/settings.h +++ b/rtengine/settings.h @@ -55,6 +55,8 @@ namespace rtengine { double protectredh; bool ciebadpixgauss; int CRI_color; // N� for display Lab value ; 0 disabled + int denoiselabgamma; // 0=gamma 26 11 1=gamma 40 5 2 =gamma 55 10 + // bool bw_complementary; double artifact_cbdl; double level0_cbdl; diff --git a/rtgui/options.cc b/rtgui/options.cc index 44a5007e0..3b9d4b45f 100644 --- a/rtgui/options.cc +++ b/rtgui/options.cc @@ -520,6 +520,8 @@ void Options::setDefaults () { rtSettings.protectredh = 0.3; rtSettings.CRI_color =0; rtSettings.autocielab=true; + rtSettings.denoiselabgamma=2; + // rtSettings.ciebadpixgauss=false; rtSettings.rgbcurveslumamode_gamut=true; lastIccDir = rtSettings.iccDirectory; @@ -742,6 +744,7 @@ if (keyFile.has_group ("Color Management")) { if (keyFile.has_key ("Color Management", "Intent")) rtSettings.colorimetricIntent = keyFile.get_integer("Color Management", "Intent"); if (keyFile.has_key ("Color Management", "CRI")) rtSettings.CRI_color = keyFile.get_integer("Color Management", "CRI"); + if (keyFile.has_key ("Color Management", "DenoiseLabgamma"))rtSettings.denoiselabgamma = keyFile.get_integer("Color Management", "DenoiseLabgamma"); if (keyFile.has_key ("Color Management", "view")) rtSettings.viewingdevice = keyFile.get_integer("Color Management", "view"); if (keyFile.has_key ("Color Management", "grey")) rtSettings.viewingdevicegrey = keyFile.get_integer("Color Management", "grey"); if (keyFile.has_key ("Color Management", "CBDLArtif")) rtSettings.artifact_cbdl = keyFile.get_double("Color Management", "CBDLArtif"); @@ -1046,6 +1049,7 @@ int Options::saveToFile (Glib::ustring fname) { keyFile.set_integer ("Color Management", "Amountchroma", rtSettings.amchroma); keyFile.set_double ("Color Management", "ProtectRedH", rtSettings.protectredh); keyFile.set_integer ("Color Management", "CRI", rtSettings.CRI_color); + keyFile.set_integer ("Color Management", "DenoiseLabgamma", rtSettings.denoiselabgamma); // keyFile.set_boolean ("Color Management", "Ciebadpixgauss", rtSettings.ciebadpixgauss); keyFile.set_double ("Color Management", "CBDLArtif", rtSettings.artifact_cbdl); keyFile.set_double ("Color Management", "CBDLlevel0", rtSettings.level0_cbdl);