diff --git a/rtdata/languages/default b/rtdata/languages/default index f0a00913e..e7c661817 100644 --- a/rtdata/languages/default +++ b/rtdata/languages/default @@ -474,7 +474,8 @@ HISTORY_MSG_251;B&W - Algorithm HISTORY_MSG_252;CbDL Skin Tones HISTORY_MSG_253;CbDL Reduce artifacts HISTORY_MSG_254;CbDL - Hueskin -HISTORY_MSG_255;CbDL - Algorithm +HISTORY_MSG_255;NR - median +HISTORY_MSG_256;NR - median method HISTORY_NEWSNAPSHOT;Add HISTORY_NEWSNAPSHOT_TOOLTIP;Shortcut: Alt-s HISTORY_SNAPSHOTS;Snapshots @@ -1069,6 +1070,8 @@ TP_DIRPYRDENOISE_CHROMA;Chrominance - Master TP_DIRPYRDENOISE_ENABLED_TOOLTIP;Can be used on raw and non-raw images.\n\nFor non-raw images noise reduction of luminance depends on the gamma of the input color profile. An sRGB gamma is assumed, thus if the image uses an input color profile of a different gamma, the effects of luminance noise reduction will differ. TP_DIRPYRDENOISE_ENH;Enhanced mode TP_DIRPYRDENOISE_ENH_TOOLTIP;Increases noise reduction quality at the expense of a 20% processing time increase. +TP_DIRPYRDENOISE_MED;Median +TP_DIRPYRDENOISE_MED_TOOLTIP;Add a median 3x3 soft or 3x3 standard or 5x5 strong at the end of threatment - Increases noise reduction at the expense of a 4% to 10% processing time increase. TP_DIRPYRDENOISE_GAMMA;Gamma TP_DIRPYRDENOISE_GAMMA_TOOLTIP;Gamma varies noise reduction strength across the range of tones. Smaller values will target shadows, while larger values will stretch the effect to the brighter tones. TP_DIRPYRDENOISE_LABEL;Noise Reduction @@ -1080,6 +1083,12 @@ TP_DIRPYRDENOISE_METHOD_TOOLTIP;For raw images either RGB or Lab methods can be TP_DIRPYRDENOISE_PERF;RGB mode (raw images) TP_DIRPYRDENOISE_RED;Chrominance - Red-Green TP_DIRPYRDENOISE_RGB;RGB +TP_DIRPYRDENOISE_MEDMETHOD;Median Method +TP_DIRPYRDENOISE_SOFT;3x3 soft +TP_DIRPYRDENOISE_33;3x3 standard +TP_DIRPYRDENOISE_55;5x5 +TP_DIRPYRDENOISE_55SOFT;5x5 soft +TP_DIRPYRDENOISE_MET_TOOLTIP;allow different denoise: soft preserve detail, 3x3 standard, 5x5 soft, 5x5 TP_DIRPYREQUALIZER_ALGO;Algorithm Skin TP_DIRPYREQUALIZER_ALGO_FI;Fine TP_DIRPYREQUALIZER_ALGO_LA;Large diff --git a/rtengine/FTblockDN.cc b/rtengine/FTblockDN.cc index 6b54a22e1..8b1df4315 100644 --- a/rtengine/FTblockDN.cc +++ b/rtengine/FTblockDN.cc @@ -40,7 +40,7 @@ #include "boxblur.h" #include "rt_math.h" #include "mytime.h" -#include "sleef.c" +#include "sleef.c" #include "opthelper.h" #ifdef _OPENMP @@ -62,6 +62,65 @@ #define epsilon 0.001f/(TS*TS) //tolerance +#define PIX_SORT(a,b) { if ((a)>(b)) {temp=(a);(a)=(b);(b)=temp;} } + +#define med3(a0,a1,a2,a3,a4,a5,a6,a7,a8,median) { \ +pp[0]=a0; pp[1]=a1; pp[2]=a2; pp[3]=a3; pp[4]=a4; pp[5]=a5; pp[6]=a6; pp[7]=a7; pp[8]=a8; \ +PIX_SORT(pp[1],pp[2]); PIX_SORT(pp[4],pp[5]); PIX_SORT(pp[7],pp[8]); \ +PIX_SORT(pp[0],pp[1]); PIX_SORT(pp[3],pp[4]); PIX_SORT(pp[6],pp[7]); \ +PIX_SORT(pp[1],pp[2]); PIX_SORT(pp[4],pp[5]); PIX_SORT(pp[7],pp[8]); \ +PIX_SORT(pp[0],pp[3]); PIX_SORT(pp[5],pp[8]); PIX_SORT(pp[4],pp[7]); \ +PIX_SORT(pp[3],pp[6]); PIX_SORT(pp[1],pp[4]); PIX_SORT(pp[2],pp[5]); \ +PIX_SORT(pp[4],pp[7]); PIX_SORT(pp[4],pp[2]); PIX_SORT(pp[6],pp[4]); \ +PIX_SORT(pp[4],pp[2]); median=pp[4];} //pp4 = median + +#define med2(a0,a1,a2,a3,a4,median) { \ +pp[0]=a0; pp[1]=a1; pp[2]=a2; pp[3]=a3; pp[4]=a4; \ +PIX_SORT(pp[0],pp[1]) ; PIX_SORT(pp[3],pp[4]) ; PIX_SORT(pp[0],pp[3]) ;\ +PIX_SORT(pp[1],pp[4]) ; PIX_SORT(pp[1],pp[2]) ; PIX_SORT(pp[2],pp[3]) ;\ +PIX_SORT(pp[1],pp[2]) ; median=pp[2] ;} + +#define med5(a0,a1,a2,a3,a4,a5,a6,a7,a8,a9,a10,a11,a12,a13,a14,a15,a16,a17,a18,a19,a20,a21,a22,a23,a24,median) { \ +pp[0]=a0; pp[1]=a1; pp[2]=a2; pp[3]=a3; pp[4]=a4; pp[5]=a5; pp[6]=a6; pp[7]=a7; pp[8]=a8; pp[9]=a9; pp[10]=a10; pp[11]=a11; pp[12]=a12; \ +pp[13]=a13; pp[14]=a14; pp[15]=a15; pp[16]=a16; pp[17]=a17; pp[18]=a18; pp[19]=a19; pp[20]=a20; pp[21]=a21; pp[22]=a22; pp[23]=a23; pp[24]=a24; \ +PIX_SORT(pp[0], pp[1]) ; PIX_SORT(pp[3], pp[4]) ; PIX_SORT(pp[2], pp[4]) ;\ +PIX_SORT(pp[2], pp[3]) ; PIX_SORT(pp[6], pp[7]) ; PIX_SORT(pp[5], pp[7]) ;\ +PIX_SORT(pp[5], pp[6]) ; PIX_SORT(pp[9], pp[10]) ; PIX_SORT(pp[8], pp[10]) ;\ +PIX_SORT(pp[8], pp[9]) ; PIX_SORT(pp[12], pp[13]) ; PIX_SORT(pp[11], pp[13]) ;\ +PIX_SORT(pp[11], pp[12]) ; PIX_SORT(pp[15], pp[16]) ; PIX_SORT(pp[14], pp[16]) ;\ +PIX_SORT(pp[14], pp[15]) ; PIX_SORT(pp[18], pp[19]) ; PIX_SORT(pp[17], pp[19]) ;\ +PIX_SORT(pp[17], pp[18]) ; PIX_SORT(pp[21], pp[22]) ; PIX_SORT(pp[20], pp[22]) ;\ +PIX_SORT(pp[20], pp[21]) ; PIX_SORT(pp[23], pp[24]) ; PIX_SORT(pp[2], pp[5]) ;\ +PIX_SORT(pp[3], pp[6]) ; PIX_SORT(pp[0], pp[6]) ; PIX_SORT(pp[0], pp[3]) ;\ +PIX_SORT(pp[4], pp[7]) ; PIX_SORT(pp[1], pp[7]) ; PIX_SORT(pp[1], pp[4]) ;\ +PIX_SORT(pp[11], pp[14]) ; PIX_SORT(pp[8], pp[14]) ; PIX_SORT(pp[8], pp[11]) ;\ +PIX_SORT(pp[12], pp[15]) ; PIX_SORT(pp[9], pp[15]) ; PIX_SORT(pp[9], pp[12]) ;\ +PIX_SORT(pp[13], pp[16]) ; PIX_SORT(pp[10], pp[16]) ; PIX_SORT(pp[10], pp[13]) ;\ +PIX_SORT(pp[20], pp[23]) ; PIX_SORT(pp[17], pp[23]) ; PIX_SORT(pp[17], pp[20]) ;\ +PIX_SORT(pp[21], pp[24]) ; PIX_SORT(pp[18], pp[24]) ; PIX_SORT(pp[18], pp[21]) ;\ +PIX_SORT(pp[19], pp[22]) ; PIX_SORT(pp[8], pp[17]) ; PIX_SORT(pp[9], pp[18]) ;\ +PIX_SORT(pp[0], pp[18]) ; PIX_SORT(pp[0], pp[9]) ; PIX_SORT(pp[10], pp[19]) ;\ +PIX_SORT(pp[1], pp[19]) ; PIX_SORT(pp[1], pp[10]) ; PIX_SORT(pp[11], pp[20]) ;\ +PIX_SORT(pp[2], pp[20]) ; PIX_SORT(pp[2], pp[11]) ; PIX_SORT(pp[12], pp[21]) ;\ +PIX_SORT(pp[3], pp[21]) ; PIX_SORT(pp[3], pp[12]) ; PIX_SORT(pp[13], pp[22]) ;\ +PIX_SORT(pp[4], pp[22]) ; PIX_SORT(pp[4], pp[13]) ; PIX_SORT(pp[14], pp[23]) ;\ +PIX_SORT(pp[5], pp[23]) ; PIX_SORT(pp[5], pp[14]) ; PIX_SORT(pp[15], pp[24]) ;\ +PIX_SORT(pp[6], pp[24]) ; PIX_SORT(pp[6], pp[15]) ; PIX_SORT(pp[7], pp[16]) ;\ +PIX_SORT(pp[7], pp[19]) ; PIX_SORT(pp[13], pp[21]) ; PIX_SORT(pp[15], pp[23]) ;\ +PIX_SORT(pp[7], pp[13]) ; PIX_SORT(pp[7], pp[15]) ; PIX_SORT(pp[1], pp[9]) ;\ +PIX_SORT(pp[3], pp[11]) ; PIX_SORT(pp[5], pp[17]) ; PIX_SORT(pp[11], pp[17]) ;\ +PIX_SORT(pp[9], pp[17]) ; PIX_SORT(pp[4], pp[10]) ; PIX_SORT(pp[6], pp[12]) ;\ +PIX_SORT(pp[7], pp[14]) ; PIX_SORT(pp[4], pp[6]) ; PIX_SORT(pp[4], pp[7]) ;\ +PIX_SORT(pp[12], pp[14]) ; PIX_SORT(pp[10], pp[14]) ; PIX_SORT(pp[6], pp[7]) ;\ +PIX_SORT(pp[10], pp[12]) ; PIX_SORT(pp[6], pp[10]) ; PIX_SORT(pp[6], pp[17]) ;\ +PIX_SORT(pp[12], pp[17]) ; PIX_SORT(pp[7], pp[17]) ; PIX_SORT(pp[7], pp[10]) ;\ +PIX_SORT(pp[12], pp[18]) ; PIX_SORT(pp[7], pp[12]) ; PIX_SORT(pp[10], pp[18]) ;\ +PIX_SORT(pp[12], pp[20]) ; PIX_SORT(pp[10], pp[20]) ; PIX_SORT(pp[10], pp[12]) ;\ +median=pp[12];} + +#define ELEM_FLOAT_SWAP(a,b) { register float t=(a);(a)=(b);(b)=t; } + + namespace rtengine { // %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -83,14 +142,58 @@ namespace rtengine { extern const Settings* settings; +// Median calculation using quicksort +float fq_sort2(float arr[], int n) +{ + int low, high ; + int median; + int middle, ll, hh; + + low = 0 ; high = n-1 ; median = (low + high) / 2; + for (;;) { + if (high <= low) + return arr[median] ; + if (high == low + 1) { + if (arr[low] > arr[high]) + ELEM_FLOAT_SWAP(arr[low], arr[high]) ; + return arr[median] ; + } + + middle = (low + high) / 2; + if (arr[middle] > arr[high]) ELEM_FLOAT_SWAP(arr[middle], arr[high]) ; + if (arr[low] > arr[high]) ELEM_FLOAT_SWAP(arr[low], arr[high]) ; + if (arr[middle] > arr[low]) ELEM_FLOAT_SWAP(arr[middle], arr[low]) ; + + ELEM_FLOAT_SWAP(arr[middle], arr[low+1]) ; + ll = low + 1; + hh = high; + + for (;;) { + do ll++; while (arr[low] > arr[ll]) ; + do hh--; while (arr[hh] > arr[low]) ; + + if (hh < ll) + break; + + ELEM_FLOAT_SWAP(arr[ll], arr[hh]) ; + } + + ELEM_FLOAT_SWAP(arr[low], arr[hh]) ; + + if (hh <= median) + low = ll; + if (hh >= median) + high = hh - 1; + } + } void ImProcFunctions::RGB_denoise(Imagefloat * src, Imagefloat * dst, bool isRAW, const procparams::DirPyrDenoiseParams & dnparams, const procparams::DefringeParams & defringe, const double expcomp) - { + { //#ifdef _DEBUG -// MyTime t1e,t2e; -// t1e.set(); + MyTime t1e,t2e; + t1e.set(); //#endif static MyMutex FftwMutex; @@ -108,13 +211,16 @@ namespace rtengine { //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - const short int imheight=src->height, imwidth=src->width; - - if (dnparams.luma==0 && dnparams.chroma==0) { - //nothing to do; copy src to dst - memcpy(dst->data,src->data,dst->width*dst->height*3*sizeof(float)); + const short int imheight=src->height, imwidth=src->width; + + if (dnparams.luma==0 && dnparams.chroma==0 && !dnparams.median) { + //nothing to do; copy src to dst or do nothing in case src == dst + if(src != dst) + memcpy(dst->data,src->data,dst->width*dst->height*3*sizeof(float)); return; } + + if (dnparams.luma!=0 || dnparams.chroma!=0) { perf=false; if(dnparams.dmethod=="RGB") perf=true;//RGB mode //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -165,6 +271,7 @@ namespace rtengine { float incr=1.f; float noisevar_Ldetail = SQR((float)(SQR(100.-dnparams.Ldetail) + 50.*(100.-dnparams.Ldetail)) * TS * 0.5f * incr); bool enhance_denoise = dnparams.enhance; +// bool median_denoise = dnparams.median; int gamlab = settings->denoiselabgamma;//gamma lab essentialy for Luminance detail if(gamlab > 2) gamlab=2; if(settings->verbose) printf("Denoise Lab=%i\n",gamlab); @@ -173,7 +280,7 @@ namespace rtengine { array2D tilemask_out(TS,TS); const int border = MAX(2,TS/16); - + #ifdef _OPENMP #pragma omp parallel for #endif @@ -294,9 +401,9 @@ namespace rtengine { { Lblox = (float*) fftwf_malloc(max_numblox_W*TS*TS*sizeof(float)); fLblox = (float*) fftwf_malloc(max_numblox_W*TS*TS*sizeof(float)); - } - - float * nbrwt = new float[TS*TS]; + } + + float * nbrwt = new float[TS*TS]; float * blurbuffer = new float[TS*TS]; #ifdef _OPENMP #pragma omp for schedule(dynamic) collapse(2) @@ -321,7 +428,7 @@ namespace rtengine { //TODO: implement using AlignedBufferMP //fill tile from image; convert RGB to "luma/chroma" if (isRAW) {//image is raw; use channel differences for chroma channels - if(!perf){//lab mode + if(!perf){//lab mode //modification Jacques feb 2013 for (int i=tiletop/*, i1=0*/; iwidth, hei=dst->height; + float** tm; + tm = new float*[hei]; + for (int i=0; ir(i,j),source->r(i-1,j),source->r(i+1,j),source->r(i,j+1),source->r(i,j-1),tm[i][j]);//3x3 soft + } + else + for (int j=1; jr(i,j),source->r(i-1,j),source->r(i+1,j),source->r(i,j+1),source->r(i,j-1),source->r(i-1,j-1),source->r(i-1,j+1),source->r(i+1,j-1),source->r(i+1,j+1),tm[i][j]);//3x3 + } + } + } else { +#pragma omp for + for (int i=2; ir(i,j),source->r(i-1,j),source->r(i+1,j),source->r(i,j+1),source->r(i,j-1),source->r(i-1,j-1),source->r(i-1,j+1),source->r(i+1,j-1),source->r(i+1,j+1), + source->r(i-2,j),source->r(i+2,j),source->r(i,j+2),source->r(i,j-2),source->r(i-2,j-2),source->r(i-2,j+2),source->r(i+2,j-2),source->r(i+2,j+2), + source->r(i-2,j+1),source->r(i+2,j+1),source->r(i-1,j+2),source->r(i-1,j-2),source->r(i-2,j-1),source->r(i+2,j-1),source->r(i+1,j+2),source->r(i+1,j-2), + tm[i][j]);//5x5 + } + else + for (int j=2; jr(i,j);pp[1]=source->r(i-1,j); pp[2]=source->r(i+1,j);pp[3]=source->r(i,j+1);pp[4]=source->r(i,j-1);pp[5]=source->r(i-1,j-1);pp[6]=source->r(i-1,j+1); + pp[7]=source->r(i+1,j-1);pp[8]=source->r(i+1,j+1);pp[9]=source->r(i+2,j);pp[10]=source->r(i-2,j);pp[11]=source->r(i,j+2);pp[12]=source->r(i,j-2); + fq_sort2(pp,13); + tm[i][j]=pp[6];//5x5 soft + } + } + } +#ifdef _OPENMP +#pragma omp for nowait +#endif + for(int i = border; i < hei-border; i++ ) { + for(int j = border; j < wid-border; j++) { + dst->r(i,j) = tm[i][j]; + } + } + + if(methmed < 2) { +#pragma omp for + for (int i=1; ib(i,j),source->b(i-1,j),source->b(i+1,j),source->b(i,j+1),source->b(i,j-1),tm[i][j]); + } + else + for (int j=1; jb(i,j),source->b(i-1,j),source->b(i+1,j),source->b(i,j+1),source->b(i,j-1),source->b(i-1,j-1),source->b(i-1,j+1),source->b(i+1,j-1),source->b(i+1,j+1),tm[i][j]); + } + } + } else { +#pragma omp for + for (int i=2; ib(i,j),source->b(i-1,j),source->b(i+1,j),source->b(i,j+1),source->b(i,j-1),source->b(i-1,j-1),source->b(i-1,j+1),source->b(i+1,j-1),source->b(i+1,j+1), + source->b(i-2,j),source->b(i+2,j),source->b(i,j+2),source->b(i,j-2),source->b(i-2,j-2),source->b(i-2,j+2),source->b(i+2,j-2),source->b(i+2,j+2), + source->b(i-2,j+1),source->b(i+2,j+1),source->b(i-1,j+2),source->b(i-1,j-2),source->b(i-2,j-1),source->b(i+2,j-1),source->b(i+1,j+2),source->b(i+1,j-2), + tm[i][j]);//5x5 + } + else + for (int j=2; jb(i,j);pp[1]=source->b(i-1,j); pp[2]=source->b(i+1,j);pp[3]=source->b(i,j+1);pp[4]=source->b(i,j-1);pp[5]=source->b(i-1,j-1);pp[6]=source->b(i-1,j+1); + pp[7]=source->b(i+1,j-1);pp[8]=source->b(i+1,j+1);pp[9]=source->b(i+2,j);pp[10]=source->b(i-2,j);pp[11]=source->b(i,j+2);pp[12]=source->b(i,j-2); + fq_sort2(pp,13); + tm[i][j]=pp[6];//5x5 soft + } + } + } + +#ifdef _OPENMP +#pragma omp for nowait +#endif + for(int i = border; i < hei-border; i++ ) { + for(int j = border; j < wid-border; j++) { + dst->b(i,j) = tm[i][j]; + } + } + + + if(methmed < 2) { +#pragma omp for + for (int i=1; ig(i,j),source->g(i-1,j),source->g(i+1,j),source->g(i,j+1),source->g(i,j-1),tm[i][j]); + } + else + for (int j=1; jg(i,j),source->g(i-1,j),source->g(i+1,j),source->g(i,j+1),source->g(i,j-1),source->g(i-1,j-1),source->g(i-1,j+1),source->g(i+1,j-1),source->g(i+1,j+1),tm[i][j]); + } + } + } else { +#pragma omp for + for (int i=2; ig(i,j),source->g(i-1,j),source->g(i+1,j),source->g(i,j+1),source->g(i,j-1),source->g(i-1,j-1),source->g(i-1,j+1),source->g(i+1,j-1),source->g(i+1,j+1), + source->g(i-2,j),source->g(i+2,j),source->g(i,j+2),source->g(i,j-2),source->g(i-2,j-2),source->g(i-2,j+2),source->g(i+2,j-2),source->g(i+2,j+2), + source->g(i-2,j+1),source->g(i+2,j+1),source->g(i-1,j+2),source->g(i-1,j-2),source->g(i-2,j-1),source->g(i+2,j-1),source->g(i+1,j+2),source->g(i+1,j-2), + tm[i][j]);//5x5 + } + else + for (int j=2; jg(i,j);pp[1]=source->g(i-1,j); pp[2]=source->g(i+1,j);pp[3]=source->g(i,j+1);pp[4]=source->g(i,j-1);pp[5]=source->g(i-1,j-1);pp[6]=source->g(i-1,j+1); + pp[7]=source->g(i+1,j-1);pp[8]=source->g(i+1,j+1);pp[9]=source->g(i+2,j);pp[10]=source->g(i-2,j);pp[11]=source->g(i,j+2);pp[12]=source->g(i,j-2); + fq_sort2(pp,13); + tm[i][j]=pp[6];//5x5 soft + } + } + } + +#ifdef _OPENMP +#pragma omp for +#endif + for(int i = border; i < hei-border; i++ ) { + for(int j = border; j < wid-border; j++) { + dst->g(i,j) = tm[i][j]; + } + } +} + + for (int i=0; iverbose) { -// t2e.set(); -// printf("Denoise performed in %d usec:\n", t2e.etime(t1e)); -// } + if (settings->verbose) { + t2e.set(); + printf("Denoise performed in %d usec:\n", t2e.etime(t1e)); + } //#endif }//end of main RGB_denoise @@ -890,13 +1167,13 @@ SSEFUNCTION void ImProcFunctions::RGBtile_denoise (float * fLblox, int hblproc, return (( (median-1) + (datalen/2-count_)/((float)(count-count_)) )/0.6745); } - + float ImProcFunctions::Mad( float * RESTRICT DataList, int datalen, int * RESTRICT histo) { //computes Median Absolute Deviation //DataList values should mostly have abs val < 65535 - for (int i=0; i<65536; i++) + for (int i=0; i<65536; i++) histo[i]=0; //calculate histogram of absolute values of HH wavelet coeffs @@ -916,7 +1193,7 @@ SSEFUNCTION void ImProcFunctions::RGBtile_denoise (float * fLblox, int hblproc, // interpolate return (( (median-1) + (datalen/2-count_)/((float)(count-count_)) )/0.6745); } - + //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% @@ -951,7 +1228,7 @@ SSEFUNCTION void ImProcFunctions::WaveletDenoiseAll_BiShrink(wavelet_decompositi madL[lvl][dir-1] = SQR(Mad(WavCoeffs_L[dir], Wlvl_L*Hlvl_L, madHisto)); mada[lvl][dir-1] = SQR(Mad(WavCoeffs_a[dir], Wlvl_ab*Hlvl_ab, madHisto)); madb[lvl][dir-1] = SQR(Mad(WavCoeffs_b[dir], Wlvl_ab*Hlvl_ab, madHisto)); - } + } } delete [] madHisto; @@ -982,8 +1259,8 @@ SSEFUNCTION void ImProcFunctions::WaveletDenoiseAll_BiShrink(wavelet_decompositi //float ** WavPars_b = WaveletCoeffs_b.level_coeffs(lvl+1); //simple wavelet shrinkage - float * sfave = new float[Wlvl_L*Hlvl_L]; - float * WavCoeffsLtemp = new float[Hlvl_ab*Wlvl_ab]; + float * sfave = new float[Wlvl_L*Hlvl_L]; + float * WavCoeffsLtemp = new float[Hlvl_ab*Wlvl_ab]; // array2D edge(Wlvl_L,Hlvl_L); @@ -992,8 +1269,8 @@ SSEFUNCTION void ImProcFunctions::WaveletDenoiseAll_BiShrink(wavelet_decompositi for (int dir=1; dir<4; dir++) { float mad_L = madL[lvl][dir-1]; float mad_a = noisevar_abr*mada[lvl][dir-1]; - float mad_b = noisevar_abb*madb[lvl][dir-1]; - + float mad_b = noisevar_abb*madb[lvl][dir-1]; + //float mad_Lpar = madL[lvl+1][dir-1]; //float mad_apar = mada[lvl+1][dir-1]; @@ -1003,37 +1280,37 @@ SSEFUNCTION void ImProcFunctions::WaveletDenoiseAll_BiShrink(wavelet_decompositi // float skip_L_ratio = WaveletCoeffs_L.level_stride(lvl+1)/skip_L; if (noisevar_abr>0.01f || noisevar_abb>0.01f) { - for(int i=0;i0.01f) { - mad_L *= noisevar_L*5.f/(lvl+1); -#ifdef __SSE2__ - int j; - __m128 mad_Lv = _mm_set1_ps(mad_L); - __m128 mad_Lm9v = _mm_set1_ps(mad_L * 9.f); - __m128 epsv = _mm_set1_ps(eps); - __m128 mag_Lv; - for (int i=0; i0.01f) { + mad_L *= noisevar_L*5.f/(lvl+1); +#ifdef __SSE2__ + int j; + __m128 mad_Lv = _mm_set1_ps(mad_L); + __m128 mad_Lm9v = _mm_set1_ps(mad_L * 9.f); + __m128 epsv = _mm_set1_ps(eps); + __m128 mag_Lv; + for (int i=0; i (edge, edge, buffer, Wlvl_L, Hlvl_L, 1<<(lvl+1), false); boxblur(sfave, sfave, lvl+2, lvl+2, Wlvl_L, Hlvl_L);//increase smoothness by locally averaging shrinkage - -#ifdef __SSE2__ - __m128 tempLv; - __m128 tempL2v; - __m128 sf_Lv; - + +#ifdef __SSE2__ + __m128 tempLv; + __m128 tempL2v; + __m128 sf_Lv; + for (int i=0; i 582=max float mad_b = madb*noisevar_abb; - if (noisevar_abr>0.01f || noisevar_abb>0.01f) { - for(int i=0;i0.01f || noisevar_abb>0.01f) { + for(int i=0;i2*thresh_a ? 1 : (coeff_a2*thresh_b ? 1 : (coeff_bdirpyrDenoise.enabled) keyFile.set_boolean ("Directional Pyramid Denoising", "Enabled", dirpyrDenoise.enabled); if (!pedited || pedited->dirpyrDenoise.enhance) keyFile.set_boolean ("Directional Pyramid Denoising", "Enhance", dirpyrDenoise.enhance); + if (!pedited || pedited->dirpyrDenoise.median) keyFile.set_boolean ("Directional Pyramid Denoising", "Median", dirpyrDenoise.median); // if (!pedited || pedited->dirpyrDenoise.perform) keyFile.set_boolean ("Directional Pyramid Denoising", "Perform", dirpyrDenoise.perform); if (!pedited || pedited->dirpyrDenoise.luma) keyFile.set_double ("Directional Pyramid Denoising", "Luma", dirpyrDenoise.luma); if (!pedited || pedited->dirpyrDenoise.Ldetail) keyFile.set_double ("Directional Pyramid Denoising", "Ldetail", dirpyrDenoise.Ldetail); if (!pedited || pedited->dirpyrDenoise.chroma) keyFile.set_double ("Directional Pyramid Denoising", "Chroma", dirpyrDenoise.chroma); if (!pedited || pedited->dirpyrDenoise.dmethod) keyFile.set_string ("Directional Pyramid Denoising", "Method", dirpyrDenoise.dmethod); + if (!pedited || pedited->dirpyrDenoise.medmethod) keyFile.set_string ("Directional Pyramid Denoising", "MedMethod", dirpyrDenoise.medmethod); if (!pedited || pedited->dirpyrDenoise.redchro) keyFile.set_double ("Directional Pyramid Denoising", "Redchro", dirpyrDenoise.redchro); if (!pedited || pedited->dirpyrDenoise.bluechro)keyFile.set_double ("Directional Pyramid Denoising", "Bluechro", dirpyrDenoise.bluechro); if (!pedited || pedited->dirpyrDenoise.gamma) keyFile.set_double ("Directional Pyramid Denoising", "Gamma", dirpyrDenoise.gamma); @@ -1482,11 +1486,13 @@ if (keyFile.has_group ("Impulse Denoising")) { if (keyFile.has_group ("Directional Pyramid Denoising")) {//TODO: No longer an accurate description for FT denoise if (keyFile.has_key ("Directional Pyramid Denoising", "Enabled")) { dirpyrDenoise.enabled = keyFile.get_boolean ("Directional Pyramid Denoising", "Enabled"); if (pedited) pedited->dirpyrDenoise.enabled = true; } if (keyFile.has_key ("Directional Pyramid Denoising", "Enhance")) { dirpyrDenoise.enhance = keyFile.get_boolean ("Directional Pyramid Denoising", "Enhance"); if (pedited) pedited->dirpyrDenoise.enhance = true; } + if (keyFile.has_key ("Directional Pyramid Denoising", "Median")) { dirpyrDenoise.median = keyFile.get_boolean ("Directional Pyramid Denoising", "Median"); if (pedited) pedited->dirpyrDenoise.median = true; } // if (keyFile.has_key ("Directional Pyramid Denoising", "Perform")) { dirpyrDenoise.perform = keyFile.get_boolean ("Directional Pyramid Denoising", "Perform"); if (pedited) pedited->dirpyrDenoise.perform = true; } if (keyFile.has_key ("Directional Pyramid Denoising", "Luma")) { dirpyrDenoise.luma = keyFile.get_double ("Directional Pyramid Denoising", "Luma"); if (pedited) pedited->dirpyrDenoise.luma = true; } if (keyFile.has_key ("Directional Pyramid Denoising", "Ldetail")) { dirpyrDenoise.Ldetail = keyFile.get_double ("Directional Pyramid Denoising", "Ldetail"); if (pedited) pedited->dirpyrDenoise.Ldetail = true; } if (keyFile.has_key ("Directional Pyramid Denoising", "Chroma")) { dirpyrDenoise.chroma = keyFile.get_double ("Directional Pyramid Denoising", "Chroma"); if (pedited) pedited->dirpyrDenoise.chroma = true; } if (keyFile.has_key ("Directional Pyramid Denoising", "Method")) {dirpyrDenoise.dmethod = keyFile.get_string ("Directional Pyramid Denoising", "Method"); if (pedited) pedited->dirpyrDenoise.dmethod = true; } + if (keyFile.has_key ("Directional Pyramid Denoising", "MedMethod")) {dirpyrDenoise.medmethod = keyFile.get_string ("Directional Pyramid Denoising", "MedMethod"); if (pedited) pedited->dirpyrDenoise.medmethod = true; } if (keyFile.has_key ("Directional Pyramid Denoising", "Redchro")) { dirpyrDenoise.redchro = keyFile.get_double ("Directional Pyramid Denoising", "Redchro"); if (pedited) pedited->dirpyrDenoise.redchro = true; } if (keyFile.has_key ("Directional Pyramid Denoising", "Bluechro")) { dirpyrDenoise.bluechro = keyFile.get_double ("Directional Pyramid Denoising", "Bluechro"); if (pedited) pedited->dirpyrDenoise.bluechro = true; } @@ -1910,11 +1916,13 @@ bool ProcParams::operator== (const ProcParams& other) { && impulseDenoise.thresh == other.impulseDenoise.thresh && dirpyrDenoise.enabled == other.dirpyrDenoise.enabled && dirpyrDenoise.enhance == other.dirpyrDenoise.enhance + && dirpyrDenoise.median == other.dirpyrDenoise.median // && dirpyrDenoise.perform == other.dirpyrDenoise.perform && dirpyrDenoise.luma == other.dirpyrDenoise.luma && dirpyrDenoise.Ldetail == other.dirpyrDenoise.Ldetail && dirpyrDenoise.chroma == other.dirpyrDenoise.chroma && dirpyrDenoise.dmethod == other.dirpyrDenoise.dmethod + && dirpyrDenoise.medmethod == other.dirpyrDenoise.medmethod && dirpyrDenoise.redchro == other.dirpyrDenoise.redchro && dirpyrDenoise.bluechro == other.dirpyrDenoise.bluechro && dirpyrDenoise.gamma == other.dirpyrDenoise.gamma diff --git a/rtengine/procparams.h b/rtengine/procparams.h index e4948a1ea..a71cb59dd 100644 --- a/rtengine/procparams.h +++ b/rtengine/procparams.h @@ -473,6 +473,7 @@ class DirPyrDenoiseParams { public: bool enabled; bool enhance; + bool median; bool perform; double luma; @@ -482,6 +483,7 @@ class DirPyrDenoiseParams { double bluechro; double gamma; Glib::ustring dmethod; + Glib::ustring medmethod; }; //EPD related parameters. diff --git a/rtengine/refreshmap.cc b/rtengine/refreshmap.cc index 73f0007da..05b7bb6b1 100644 --- a/rtengine/refreshmap.cc +++ b/rtengine/refreshmap.cc @@ -273,7 +273,9 @@ ALLNORAW, // EvDPDNenhance RGBCURVE, // EvBWMethodalg DIRPYREQUALIZER, // EvDirPyrEqualizerSkin DIRPYREQUALIZER, // EvDirPyrEqlgamutlab -DIRPYREQUALIZER // EvDirPyrEqualizerHueskin +DIRPYREQUALIZER, // EvDirPyrEqualizerHueskin +ALLNORAW, // EvDPDNmedian +ALLNORAW //EvDPDNmedmet //DIRPYREQUALIZER // EvDirPyrEqualizeralg //LUMINANCECURVE // EvCATsharpcie diff --git a/rtgui/dirpyrdenoise.cc b/rtgui/dirpyrdenoise.cc index 3d2a1bd89..5c98dc2bb 100644 --- a/rtgui/dirpyrdenoise.cc +++ b/rtgui/dirpyrdenoise.cc @@ -87,6 +87,22 @@ DirPyrDenoise::DirPyrDenoise () : FoldableToolPanel(this), lastenhance(false) { enhance->set_active (false); enhance->set_tooltip_text (M("TP_DIRPYRDENOISE_ENH_TOOLTIP")); + median = Gtk::manage (new Gtk::CheckButton (M("TP_DIRPYRDENOISE_MED"))); + median->set_active (false); + median->set_tooltip_text (M("TP_DIRPYRDENOISE_MED_TOOLTIP")); + + medmethod = Gtk::manage (new MyComboBoxText ()); + medmethod->append_text (M("TP_DIRPYRDENOISE_SOFT")); + medmethod->append_text (M("TP_DIRPYRDENOISE_33")); + medmethod->append_text (M("TP_DIRPYRDENOISE_55SOFT")); + medmethod->append_text (M("TP_DIRPYRDENOISE_55")); + medmethod->set_active (0); + medmethod->set_tooltip_text (M("TP_DIRPYRDENOISE_MET_TOOLTIP")); + medmethodconn = medmethod->signal_changed().connect ( sigc::mem_fun(*this, &DirPyrDenoise::medmethodChanged) ); + + ctbox = Gtk::manage (new Gtk::HBox ()); + Gtk::Label* labm = Gtk::manage (new Gtk::Label (M("TP_DIRPYRDENOISE_MEDMETHOD"))); + ctbox->pack_start (*labm, Gtk::PACK_SHRINK, 4); pack_start (*luma); pack_start (*Ldetail); @@ -96,9 +112,13 @@ DirPyrDenoise::DirPyrDenoise () : FoldableToolPanel(this), lastenhance(false) { pack_start (*gamma); pack_start (*enhance); + pack_start (*median); + ctbox->pack_start (*medmethod); + pack_start (*ctbox); // pack_start (*perform); enhanConn = enhance->signal_toggled().connect( sigc::mem_fun(*this, &DirPyrDenoise::enhanceChanged) ); + medianConn = median->signal_toggled().connect( sigc::mem_fun(*this, &DirPyrDenoise::medianChanged) ); } @@ -107,16 +127,32 @@ void DirPyrDenoise::read (const ProcParams* pp, const ParamsEdited* pedited) { disableListener (); dmethodconn.block(true); enaConn.block (true); + medmethodconn.block(true); dmethod->set_active (0); if (pp->dirpyrDenoise.dmethod=="RGB") dmethod->set_active (0); else if (pp->dirpyrDenoise.dmethod=="Lab") dmethod->set_active (1); - + + medmethod->set_active (0); + if (pp->dirpyrDenoise.medmethod=="soft") + medmethod->set_active (0); + else if (pp->dirpyrDenoise.medmethod=="33") + medmethod->set_active (1); + else if (pp->dirpyrDenoise.medmethod=="55soft") + medmethod->set_active (2); + else if (pp->dirpyrDenoise.medmethod=="55") + medmethod->set_active (3); + + + if (pedited) { if (!pedited->dirpyrDenoise.dmethod) dmethod->set_active (2); + if (!pedited->dirpyrDenoise.medmethod) + medmethod->set_active (4); + luma->setEditedState (pedited->dirpyrDenoise.luma ? Edited : UnEdited); Ldetail->setEditedState (pedited->dirpyrDenoise.Ldetail ? Edited : UnEdited); chroma->setEditedState (pedited->dirpyrDenoise.chroma ? Edited : UnEdited); @@ -126,15 +162,18 @@ void DirPyrDenoise::read (const ProcParams* pp, const ParamsEdited* pedited) { gamma->setEditedState (pedited->dirpyrDenoise.gamma ? Edited : UnEdited); enabled->set_inconsistent (!pedited->dirpyrDenoise.enabled); enhance->set_inconsistent (!pedited->dirpyrDenoise.enhance); + median->set_inconsistent (!pedited->dirpyrDenoise.median); // perform->set_inconsistent (!pedited->dirpyrDenoise.perform); } // perfconn.block (true); enabled->set_active (pp->dirpyrDenoise.enabled); enhance->set_active (pp->dirpyrDenoise.enhance); // perform->set_active (pp->dirpyrDenoise.perform); + median->set_active (pp->dirpyrDenoise.median); // perfconn.block (false); lastEnabled = pp->dirpyrDenoise.enabled; + lastmedian = pp->dirpyrDenoise.median; lastenhance = pp->dirpyrDenoise.enhance; // lastperform = pp->dirpyrDenoise.perform; luma->setValue (pp->dirpyrDenoise.luma); @@ -147,6 +186,7 @@ void DirPyrDenoise::read (const ProcParams* pp, const ParamsEdited* pedited) { enaConn.block (false); dmethodconn.block(false); + medmethodconn.block(false); enableListener (); } @@ -161,9 +201,11 @@ void DirPyrDenoise::write (ProcParams* pp, ParamsEdited* pedited) { pp->dirpyrDenoise.enabled = enabled->get_active(); pp->dirpyrDenoise.enhance = enhance->get_active(); // pp->dirpyrDenoise.perform = perform->get_active(); + pp->dirpyrDenoise.median = median->get_active(); if (pedited) { pedited->dirpyrDenoise.dmethod = dmethod->get_active_row_number() != 2; + pedited->dirpyrDenoise.medmethod = medmethod->get_active_row_number() != 3; pedited->dirpyrDenoise.luma = luma->getEditedState (); pedited->dirpyrDenoise.Ldetail = Ldetail->getEditedState (); pedited->dirpyrDenoise.chroma = chroma->getEditedState (); @@ -172,12 +214,23 @@ void DirPyrDenoise::write (ProcParams* pp, ParamsEdited* pedited) { pedited->dirpyrDenoise.gamma = gamma->getEditedState (); pedited->dirpyrDenoise.enabled = !enabled->get_inconsistent(); pedited->dirpyrDenoise.enhance = !enhance->get_inconsistent(); + pedited->dirpyrDenoise.median = !median->get_inconsistent(); // pedited->dirpyrDenoise.perform = !perform->get_inconsistent(); } if (dmethod->get_active_row_number()==0) pp->dirpyrDenoise.dmethod = "RGB"; else if (dmethod->get_active_row_number()==1) pp->dirpyrDenoise.dmethod = "Lab"; + + if (medmethod->get_active_row_number()==0) + pp->dirpyrDenoise.medmethod = "soft"; + else if (medmethod->get_active_row_number()==1) + pp->dirpyrDenoise.medmethod = "33"; + else if (medmethod->get_active_row_number()==2) + pp->dirpyrDenoise.medmethod = "55soft"; + else if (medmethod->get_active_row_number()==3) + pp->dirpyrDenoise.medmethod = "55"; + } void DirPyrDenoise::dmethodChanged () { @@ -187,6 +240,12 @@ void DirPyrDenoise::dmethodChanged () { } } +void DirPyrDenoise::medmethodChanged () { + + if (listener && (multiImage||enabled->get_active()) ) { + listener->panelChanged (EvDPDNmedmet, medmethod->get_active_text ()); + } +} void DirPyrDenoise::setDefaults (const ProcParams* defParams, const ParamsEdited* pedited) { @@ -283,6 +342,29 @@ void DirPyrDenoise::enhanceChanged () { } } +void DirPyrDenoise::medianChanged () { + + if (batchMode) { + if (median->get_inconsistent()) { + median->set_inconsistent (false); + medianConn.block (true); + median->set_active (false); + medianConn.block (false); + } + else if (lastmedian) + median->set_inconsistent (true); + + lastmedian = median->get_active (); + } + + if (listener) { + if (median->get_active ()) + listener->panelChanged (EvDPDNmedian, M("GENERAL_ENABLED")); + else + listener->panelChanged (EvDPDNmedian, M("GENERAL_DISABLED")); + } +} + /* void DirPyrDenoise::perform_toggled () { @@ -318,6 +400,8 @@ void DirPyrDenoise::setBatchMode (bool batchMode) { bluechro->showEditedCB (); gamma->showEditedCB (); dmethod->append_text (M("GENERAL_UNCHANGED")); + medmethod->append_text (M("GENERAL_UNCHANGED")); + } void DirPyrDenoise::setAdjusterBehavior (bool lumaadd, bool lumdetadd, bool chromaadd, bool chromaredadd, bool chromablueadd, bool gammaadd) { diff --git a/rtgui/dirpyrdenoise.h b/rtgui/dirpyrdenoise.h index 5f7380cd6..60ba9bc05 100644 --- a/rtgui/dirpyrdenoise.h +++ b/rtgui/dirpyrdenoise.h @@ -38,13 +38,18 @@ class DirPyrDenoise : public ToolParamBlock, public AdjusterListener, public Fol sigc::connection enaConn; Gtk::CheckButton* enhance; bool lastenhance; - sigc::connection enhanConn; + sigc::connection enhanConn, medianConn; + Gtk::CheckButton* median; + bool lastmedian; // Gtk::CheckButton* perform; // bool lastperform; // sigc::connection perfconn; MyComboBoxText* dmethod; sigc::connection dmethodconn; + MyComboBoxText* medmethod; + sigc::connection medmethodconn; + Gtk::HBox* ctbox; public: @@ -59,8 +64,10 @@ class DirPyrDenoise : public ToolParamBlock, public AdjusterListener, public Fol void adjusterChanged (Adjuster* a, double newval); void enabledChanged (); void enhanceChanged (); + void medianChanged (); // void perform_toggled (); void dmethodChanged (); + void medmethodChanged (); void setAdjusterBehavior (bool lumaadd, bool lumdetadd, bool chromaadd, bool chromaredadd, bool chromablueadd, bool gammaadd); void trimValues (rtengine::procparams::ProcParams* pp); diff --git a/rtgui/paramsedited.cc b/rtgui/paramsedited.cc index ed068e1f6..0a53bd820 100644 --- a/rtgui/paramsedited.cc +++ b/rtgui/paramsedited.cc @@ -154,6 +154,7 @@ void ParamsEdited::set (bool v) { dirpyrDenoise.enabled = v; dirpyrDenoise.enhance = v; // dirpyrDenoise.perform = v; + dirpyrDenoise.median = v; dirpyrDenoise.luma = v; dirpyrDenoise.Ldetail = v; dirpyrDenoise.chroma = v; @@ -161,6 +162,7 @@ void ParamsEdited::set (bool v) { dirpyrDenoise.bluechro = v; dirpyrDenoise.gamma = v; dirpyrDenoise.dmethod = v; + dirpyrDenoise.medmethod = v; epd.enabled = v; epd.strength = v; epd.edgeStopping = v; @@ -441,6 +443,7 @@ void ParamsEdited::initFrom (const std::vector dirpyrDenoise.enabled = dirpyrDenoise.enabled && p.dirpyrDenoise.enabled == other.dirpyrDenoise.enabled; dirpyrDenoise.enhance = dirpyrDenoise.enhance && p.dirpyrDenoise.enhance == other.dirpyrDenoise.enhance; + dirpyrDenoise.median = dirpyrDenoise.median && p.dirpyrDenoise.median == other.dirpyrDenoise.median; // dirpyrDenoise.perform = dirpyrDenoise.perform && p.dirpyrDenoise.perform == other.dirpyrDenoise.perform; dirpyrDenoise.luma = dirpyrDenoise.luma && p.dirpyrDenoise.luma == other.dirpyrDenoise.luma; dirpyrDenoise.Ldetail = dirpyrDenoise.Ldetail && p.dirpyrDenoise.Ldetail == other.dirpyrDenoise.Ldetail; @@ -449,6 +452,7 @@ void ParamsEdited::initFrom (const std::vector dirpyrDenoise.bluechro = dirpyrDenoise.bluechro && p.dirpyrDenoise.bluechro == other.dirpyrDenoise.bluechro; dirpyrDenoise.gamma = dirpyrDenoise.gamma && p.dirpyrDenoise.gamma == other.dirpyrDenoise.gamma; dirpyrDenoise.dmethod = dirpyrDenoise.dmethod && p.dirpyrDenoise.dmethod == other.dirpyrDenoise.dmethod; + dirpyrDenoise.medmethod = dirpyrDenoise.medmethod && p.dirpyrDenoise.medmethod == other.dirpyrDenoise.medmethod; epd.enabled = epd.enabled && p.epd.enabled == other.epd.enabled; epd.strength = epd.strength && p.epd.strength == other.epd.strength; @@ -728,6 +732,7 @@ void ParamsEdited::combine (rtengine::procparams::ProcParams& toEdit, const rten if (dirpyrDenoise.enabled) toEdit.dirpyrDenoise.enabled = mods.dirpyrDenoise.enabled; if (dirpyrDenoise.enhance) toEdit.dirpyrDenoise.enhance = mods.dirpyrDenoise.enhance; + if (dirpyrDenoise.median) toEdit.dirpyrDenoise.median = mods.dirpyrDenoise.median; if (dirpyrDenoise.luma) toEdit.dirpyrDenoise.luma = dontforceSet && options.baBehav[ADDSET_DIRPYRDN_LUMA] ? toEdit.dirpyrDenoise.luma + mods.dirpyrDenoise.luma : mods.dirpyrDenoise.luma; if (dirpyrDenoise.Ldetail) toEdit.dirpyrDenoise.Ldetail = dontforceSet && options.baBehav[ADDSET_DIRPYRDN_LUMDET] ? toEdit.dirpyrDenoise.Ldetail + mods.dirpyrDenoise.Ldetail : mods.dirpyrDenoise.Ldetail; if (dirpyrDenoise.chroma) toEdit.dirpyrDenoise.chroma = dontforceSet && options.baBehav[ADDSET_DIRPYRDN_CHROMA] ? toEdit.dirpyrDenoise.chroma + mods.dirpyrDenoise.chroma : mods.dirpyrDenoise.chroma; @@ -736,6 +741,7 @@ void ParamsEdited::combine (rtengine::procparams::ProcParams& toEdit, const rten if (dirpyrDenoise.gamma) toEdit.dirpyrDenoise.gamma = dontforceSet && options.baBehav[ADDSET_DIRPYRDN_GAMMA] ? toEdit.dirpyrDenoise.gamma + mods.dirpyrDenoise.gamma : mods.dirpyrDenoise.gamma; // if (dirpyrDenoise.perform) toEdit.dirpyrDenoise.perform = mods.dirpyrDenoise.perform; if (dirpyrDenoise.dmethod) toEdit.dirpyrDenoise.dmethod = mods.dirpyrDenoise.dmethod; + if (dirpyrDenoise.medmethod) toEdit.dirpyrDenoise.medmethod = mods.dirpyrDenoise.medmethod; if (epd.enabled) toEdit.epd.enabled = mods.epd.enabled; if (epd.strength) toEdit.epd.strength = mods.epd.strength; diff --git a/rtgui/paramsedited.h b/rtgui/paramsedited.h index 7b436fce4..b7d2eada7 100644 --- a/rtgui/paramsedited.h +++ b/rtgui/paramsedited.h @@ -234,6 +234,7 @@ class DirPyrDenoiseParamsEdited { public: bool enabled; bool enhance; + bool median; bool Ldetail; bool luma; bool chroma; @@ -242,6 +243,8 @@ public: bool gamma; // bool perform; bool dmethod; + bool medmethod; + }; class EPDParamsEdited{