Merge pull request #5700 from Beep6581/wavtm

Wavelet - change labels et tooltip
This commit is contained in:
Desmis 2020-04-05 06:54:23 +02:00 committed by GitHub
commit 2b230bfd1e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 769 additions and 241 deletions

View File

@ -791,6 +791,9 @@ HISTORY_MSG_SOFTLIGHT_STRENGTH;Soft light - Strength
HISTORY_MSG_TEMPOUT;CAM02 automatic temperature HISTORY_MSG_TEMPOUT;CAM02 automatic temperature
HISTORY_MSG_TM_FATTAL_ANCHOR;DRC - Anchor HISTORY_MSG_TM_FATTAL_ANCHOR;DRC - Anchor
HISTORY_MSG_TRANS_Method;Geometry - Method HISTORY_MSG_TRANS_Method;Geometry - Method
HISTORY_MSG_WAVBALCHROM;Balance chroma
HISTORY_MSG_WAVCHROMFI;Chroma fine
HISTORY_MSG_WAVCHROMCO;Chroma coarse
HISTORY_MSG_WAVCLARI;Clarity HISTORY_MSG_WAVCLARI;Clarity
HISTORY_MSG_WAVEDGS;Edge stopping HISTORY_MSG_WAVEDGS;Edge stopping
HISTORY_MSG_WAVMERGEC;Merge C HISTORY_MSG_WAVMERGEC;Merge C
@ -798,12 +801,12 @@ HISTORY_MSG_WAVMERGEL;Merge L
HISTORY_MSG_WAVRADIUS;Radius Shadows-Highlight HISTORY_MSG_WAVRADIUS;Radius Shadows-Highlight
HISTORY_MSG_WAVSCALE;Scale HISTORY_MSG_WAVSCALE;Scale
HISTORY_MSG_WAVSHOWMASK;Show wavelet mask HISTORY_MSG_WAVSHOWMASK;Show wavelet mask
HISTORY_MSG_WAVSIGMA;Sigma HISTORY_MSG_WAVSIGMA;Damper
HISTORY_MSG_WAVSOFTRAD;Soft radius clarity HISTORY_MSG_WAVSOFTRAD;Soft radius clarity
HISTORY_MSG_WAVSOFTRADEND;Soft radius final HISTORY_MSG_WAVSOFTRADEND;Soft radius final
HISTORY_MSG_WAVUSHAMET;Clarity method HISTORY_MSG_WAVUSHAMET;Clarity method
HISTORY_MSG_THRESWAV;Balance threshold HISTORY_MSG_THRESWAV;Balance threshold
HISTORY_MSG_BLUWAV;Effects HISTORY_MSG_BLUWAV;Damper
HISTORY_MSG_WAVOLDSH;Old algorithm HISTORY_MSG_WAVOLDSH;Old algorithm
HISTORY_MSG_WAVOFFSET;Offset HISTORY_MSG_WAVOFFSET;Offset
HISTORY_MSG_WAVLOWTHR;Threshold low contrast HISTORY_MSG_WAVLOWTHR;Threshold low contrast
@ -2142,12 +2145,13 @@ TP_WAVELET_BALANCE;Contrast balance d/v-h
TP_WAVELET_BALANCE_TOOLTIP;Alters the balance between the wavelet directions: vertical-horizontal and diagonal.\nIf contrast, chroma or residual tone mapping are activated, the effect due to balance is amplified. TP_WAVELET_BALANCE_TOOLTIP;Alters the balance between the wavelet directions: vertical-horizontal and diagonal.\nIf contrast, chroma or residual tone mapping are activated, the effect due to balance is amplified.
TP_WAVELET_BALCHRO;Chroma balance TP_WAVELET_BALCHRO;Chroma balance
TP_WAVELET_BALCHRO_TOOLTIP;If enabled, the 'Contrast balance' curve or slider also modifies chroma balance. TP_WAVELET_BALCHRO_TOOLTIP;If enabled, the 'Contrast balance' curve or slider also modifies chroma balance.
TP_WAVELET_BALCHROM;Chroma balance
TP_WAVELET_BANONE;None TP_WAVELET_BANONE;None
TP_WAVELET_BASLI;Slider TP_WAVELET_BASLI;Slider
TP_WAVELET_BATYPE;Contrast balance method TP_WAVELET_BATYPE;Contrast balance method
TP_WAVELET_BLCURVE;Blur by levels TP_WAVELET_BLCURVE;Blur by levels
TP_WAVELET_BLURFRAME;Blur TP_WAVELET_BLURFRAME;Blur
TP_WAVELET_BLUWAV;Effects TP_WAVELET_BLUWAV;Damper
TP_WAVELET_CBENAB;Toning and Color Balance TP_WAVELET_CBENAB;Toning and Color Balance
TP_WAVELET_CB_TOOLTIP;For strong values product color-toning by combining it or not with levels decomposition 'toning'\nFor low values you can change the white balance of the background (sky, ...) without changing that of the front plane, generally more contrasted TP_WAVELET_CB_TOOLTIP;For strong values product color-toning by combining it or not with levels decomposition 'toning'\nFor low values you can change the white balance of the background (sky, ...) without changing that of the front plane, generally more contrasted
TP_WAVELET_CCURVE;Local contrast TP_WAVELET_CCURVE;Local contrast
@ -2157,7 +2161,10 @@ TP_WAVELET_CH3;Link contrast levels
TP_WAVELET_CHCU;Curve TP_WAVELET_CHCU;Curve
TP_WAVELET_CHR;Chroma-contrast link strength TP_WAVELET_CHR;Chroma-contrast link strength
TP_WAVELET_CHRO;Saturated/pastel threshold TP_WAVELET_CHRO;Saturated/pastel threshold
TP_WAVELET_CHROFRAME;Denoise Chroma
TP_WAVELET_CHROMAFRAME;Chroma TP_WAVELET_CHROMAFRAME;Chroma
TP_WAVELET_CHROMCO;Chroma Coarse
TP_WAVELET_CHROMFI;Chroma Fine
TP_WAVELET_CHRO_TOOLTIP;Sets the wavelet level which will be the threshold between saturated and pastel colors.\n1-x: saturated\nx-9: pastel\n\nIf the value exceeds the amount of wavelet levels you are using then it will be ignored. TP_WAVELET_CHRO_TOOLTIP;Sets the wavelet level which will be the threshold between saturated and pastel colors.\n1-x: saturated\nx-9: pastel\n\nIf the value exceeds the amount of wavelet levels you are using then it will be ignored.
TP_WAVELET_CHR_TOOLTIP;Adjusts chroma as a function of "contrast levels" and "chroma-contrast link strength" TP_WAVELET_CHR_TOOLTIP;Adjusts chroma as a function of "contrast levels" and "chroma-contrast link strength"
TP_WAVELET_CHRWAV;Blur chroma TP_WAVELET_CHRWAV;Blur chroma
@ -2206,7 +2213,7 @@ TP_WAVELET_EDGEDETECTTHR;Threshold low (noise)
TP_WAVELET_EDGEDETECTTHR2;Threshold high (detection) TP_WAVELET_EDGEDETECTTHR2;Threshold high (detection)
TP_WAVELET_EDGEDETECTTHR_TOOLTIP;This adjuster lets you target edge detection for example to avoid applying edge sharpness to fine details, such as noise in the sky. TP_WAVELET_EDGEDETECTTHR_TOOLTIP;This adjuster lets you target edge detection for example to avoid applying edge sharpness to fine details, such as noise in the sky.
TP_WAVELET_EDGEDETECT_TOOLTIP;Moving the slider to the right increases edge sensitivity. This affects local contrast, edge settings and noise. TP_WAVELET_EDGEDETECT_TOOLTIP;Moving the slider to the right increases edge sensitivity. This affects local contrast, edge settings and noise.
TP_WAVELET_EDEFFECT;Effect TP_WAVELET_EDEFFECT;Damper
TP_WAVELET_EDEFFECT_TOOLTIP;This slider controls how wide the range of contrast values are that receive the maximum effect from the tool.\nMaximum value (2.5) disabled the tool TP_WAVELET_EDEFFECT_TOOLTIP;This slider controls how wide the range of contrast values are that receive the maximum effect from the tool.\nMaximum value (2.5) disabled the tool
TP_WAVELET_EDGESENSI;Edge sensitivity TP_WAVELET_EDGESENSI;Edge sensitivity
TP_WAVELET_EDGREINF_TOOLTIP;Reinforce or reduce the action of the first level, do the opposite to the second level, and leave the rest unchanged. TP_WAVELET_EDGREINF_TOOLTIP;Reinforce or reduce the action of the first level, do the opposite to the second level, and leave the rest unchanged.
@ -2283,8 +2290,8 @@ TP_WAVELET_SETTINGS;Wavelet Settings
TP_WAVELET_SHA;Sharp mask TP_WAVELET_SHA;Sharp mask
TP_WAVELET_SHFRAME;Shadows/Highlights TP_WAVELET_SHFRAME;Shadows/Highlights
TP_WAVELET_SHOWMASK;Show wavelet 'mask' TP_WAVELET_SHOWMASK;Show wavelet 'mask'
TP_WAVELET_SIGMA;Effects TP_WAVELET_SIGMA;Damper
TP_WAVELET_SIGMA_TOOLTIP;This slider controls how wide the range of contrast values are that receive the maximum effect from the tool.\n The higher it is, the more contrast values will be strongly modified and the higher the risk to generate artifacts. The lower it is, the more pinpoint will the effect be applied to a certain range of contrast values TP_WAVELET_SIGMA_TOOLTIP;The effect of the contrast sliders is stronger in medium contrast details, and weaker in high and low contrast details.\n With this slider you can control how quickly the effect dampens towards the extreme contrasts.\n The higher the slider is set, the wider the range of contrasts which will get a strong change, and the higher the risk to generate artifacts.\n The lower it is, the more pinpoint will the effect be applied to a narrow range of contrast values.
TP_WAVELET_SKIN;Skin targetting/protection TP_WAVELET_SKIN;Skin targetting/protection
TP_WAVELET_SKIN_TOOLTIP;At -100 skin-tones are targetted.\nAt 0 all tones are treated equally.\nAt +100 skin-tones are protected while all other tones are affected. TP_WAVELET_SKIN_TOOLTIP;At -100 skin-tones are targetted.\nAt 0 all tones are treated equally.\nAt +100 skin-tones are protected while all other tones are affected.
TP_WAVELET_SKY;Sky targetting/protection TP_WAVELET_SKY;Sky targetting/protection

View File

@ -63,8 +63,8 @@
namespace rtengine namespace rtengine
{ {
// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% // %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
// %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% // %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
/* /*
Structure of the algorithm: Structure of the algorithm:
@ -483,7 +483,6 @@ enum nrquality {QUALITY_STANDARD, QUALITY_HIGH};
void ImProcFunctions::RGB_denoise(int kall, Imagefloat * src, Imagefloat * dst, Imagefloat * calclum, float * ch_M, float *max_r, float *max_b, bool isRAW, const procparams::DirPyrDenoiseParams & dnparams, const double expcomp, const NoiseCurve & noiseLCurve, const NoiseCurve & noiseCCurve, float &nresi, float &highresi) void ImProcFunctions::RGB_denoise(int kall, Imagefloat * src, Imagefloat * dst, Imagefloat * calclum, float * ch_M, float *max_r, float *max_b, bool isRAW, const procparams::DirPyrDenoiseParams & dnparams, const double expcomp, const NoiseCurve & noiseLCurve, const NoiseCurve & noiseCCurve, float &nresi, float &highresi)
{ {
BENCHFUN BENCHFUN
//#ifdef _DEBUG //#ifdef _DEBUG
MyTime t1e, t2e; MyTime t1e, t2e;
t1e.set(); t1e.set();
@ -1183,6 +1182,7 @@ BENCHFUN
} else { } else {
madL[lvl][dir - 1] = SQR(MadRgb(WavCoeffs_L[dir], Wlvl_L * Hlvl_L)); madL[lvl][dir - 1] = SQR(MadRgb(WavCoeffs_L[dir], Wlvl_L * Hlvl_L));
} }
} }
} }
} }
@ -1200,16 +1200,16 @@ BENCHFUN
if (!memoryAllocationFailed) { if (!memoryAllocationFailed) {
if (nrQuality == QUALITY_STANDARD) { if (nrQuality == QUALITY_STANDARD) {
if (!WaveletDenoiseAllAB(*Ldecomp, *adecomp, noisevarchrom, madL, noisevarab_r, useNoiseCCurve, autoch, denoiseMethodRgb)) { //enhance mode if (!WaveletDenoiseAllAB(*Ldecomp, *adecomp, noisevarchrom, madL, nullptr, 0, noisevarab_r, useNoiseCCurve, autoch, denoiseMethodRgb, denoiseNestedLevels)) { //enhance mode
memoryAllocationFailed = true; memoryAllocationFailed = true;
} }
} else { /*if (nrQuality==QUALITY_HIGH)*/ } else { /*if (nrQuality==QUALITY_HIGH)*/
if (!WaveletDenoiseAll_BiShrinkAB(*Ldecomp, *adecomp, noisevarchrom, madL, noisevarab_r, useNoiseCCurve, autoch, denoiseMethodRgb)) { //enhance mode if (!WaveletDenoiseAll_BiShrinkAB(*Ldecomp, *adecomp, noisevarchrom, madL, nullptr, 0, noisevarab_r, useNoiseCCurve, autoch, denoiseMethodRgb, denoiseNestedLevels)) { //enhance mode
memoryAllocationFailed = true; memoryAllocationFailed = true;
} }
if (!memoryAllocationFailed) { if (!memoryAllocationFailed) {
if (!WaveletDenoiseAllAB(*Ldecomp, *adecomp, noisevarchrom, madL, noisevarab_r, useNoiseCCurve, autoch, denoiseMethodRgb)) { if (!WaveletDenoiseAllAB(*Ldecomp, *adecomp, noisevarchrom, madL, nullptr, 0, noisevarab_r, useNoiseCCurve, autoch, denoiseMethodRgb, denoiseNestedLevels)) {
memoryAllocationFailed = true; memoryAllocationFailed = true;
} }
} }
@ -1237,16 +1237,16 @@ BENCHFUN
if (!memoryAllocationFailed) { if (!memoryAllocationFailed) {
if (nrQuality == QUALITY_STANDARD) { if (nrQuality == QUALITY_STANDARD) {
if (!WaveletDenoiseAllAB(*Ldecomp, *bdecomp, noisevarchrom, madL, noisevarab_b, useNoiseCCurve, autoch, denoiseMethodRgb)) { //enhance mode if (!WaveletDenoiseAllAB(*Ldecomp, *bdecomp, noisevarchrom, madL, nullptr, 0, noisevarab_b, useNoiseCCurve, autoch, denoiseMethodRgb, denoiseNestedLevels)) { //enhance mode
memoryAllocationFailed = true; memoryAllocationFailed = true;
} }
} else { /*if (nrQuality==QUALITY_HIGH)*/ } else { /*if (nrQuality==QUALITY_HIGH)*/
if (!WaveletDenoiseAll_BiShrinkAB(*Ldecomp, *bdecomp, noisevarchrom, madL, noisevarab_b, useNoiseCCurve, autoch, denoiseMethodRgb)) { //enhance mode if (!WaveletDenoiseAll_BiShrinkAB(*Ldecomp, *bdecomp, noisevarchrom, madL, nullptr, 0, noisevarab_b, useNoiseCCurve, autoch, denoiseMethodRgb, denoiseNestedLevels)) { //enhance mode
memoryAllocationFailed = true; memoryAllocationFailed = true;
} }
if (!memoryAllocationFailed) { if (!memoryAllocationFailed) {
if (!WaveletDenoiseAllAB(*Ldecomp, *bdecomp, noisevarchrom, madL, noisevarab_b, useNoiseCCurve, autoch, denoiseMethodRgb)) { if (!WaveletDenoiseAllAB(*Ldecomp, *bdecomp, noisevarchrom, madL, nullptr, 0, noisevarab_b, useNoiseCCurve, autoch, denoiseMethodRgb, denoiseNestedLevels)) {
memoryAllocationFailed = true; memoryAllocationFailed = true;
} }
} }
@ -1273,16 +1273,16 @@ BENCHFUN
int edge = 0; int edge = 0;
if (nrQuality == QUALITY_STANDARD) { if (nrQuality == QUALITY_STANDARD) {
if (!WaveletDenoiseAllL(*Ldecomp, noisevarlum, madL, nullptr, edge)) { //enhance mode if (!WaveletDenoiseAllL(*Ldecomp, noisevarlum, madL, nullptr, edge, denoiseNestedLevels)) { //enhance mode
memoryAllocationFailed = true; memoryAllocationFailed = true;
} }
} else { /*if (nrQuality==QUALITY_HIGH)*/ } else { /*if (nrQuality==QUALITY_HIGH)*/
if (!WaveletDenoiseAll_BiShrinkL(*Ldecomp, noisevarlum, madL)) { //enhance mode if (!WaveletDenoiseAll_BiShrinkL(*Ldecomp, noisevarlum, madL, nullptr, edge, denoiseNestedLevels)) { //enhance mode
memoryAllocationFailed = true; memoryAllocationFailed = true;
} }
if (!memoryAllocationFailed) { if (!memoryAllocationFailed) {
if (!WaveletDenoiseAllL(*Ldecomp, noisevarlum, madL, nullptr, edge)) { if (!WaveletDenoiseAllL(*Ldecomp, noisevarlum, madL, nullptr, edge, denoiseNestedLevels)) {
memoryAllocationFailed = true; memoryAllocationFailed = true;
} }
} }
@ -1354,9 +1354,11 @@ BENCHFUN
#else #else
int subThread = 0; int subThread = 0;
#endif #endif
// float blurbuffer[TS * TS] ALIGNED64;
float *Lblox = LbloxArray[subThread]; float *Lblox = LbloxArray[subThread];
float *fLblox = fLbloxArray[subThread]; float *fLblox = fLbloxArray[subThread];
float pBuf[width + TS + 2 * blkrad * offset] ALIGNED16; float pBuf[width + TS + 2 * blkrad * offset] ALIGNED16;
// float nbrwt[TS * TS] ALIGNED64;
#ifdef _OPENMP #ifdef _OPENMP
#pragma omp for #pragma omp for
#endif #endif
@ -1432,6 +1434,7 @@ BENCHFUN
for (int hblk = 0; hblk < numblox_W; ++hblk) { for (int hblk = 0; hblk < numblox_W; ++hblk) {
RGBtile_denoise(fLblox, hblk, noisevar_Ldetail); RGBtile_denoise(fLblox, hblk, noisevar_Ldetail);
// RGBtile_denoise(fLblox, hblk, noisevar_Ldetail, nbrwt, blurbuffer);
}//end of horizontal block loop }//end of horizontal block loop
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% //%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@ -1448,8 +1451,14 @@ BENCHFUN
//add row of blocks to output image tile //add row of blocks to output image tile
RGBoutput_tile_row(Lblox, Ldetail, tilemask_out, height, width, topproc); RGBoutput_tile_row(Lblox, Ldetail, tilemask_out, height, width, topproc);
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
}//end of vertical block loop }//end of vertical block loop
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
} }
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
#ifdef _OPENMP #ifdef _OPENMP
#pragma omp parallel for num_threads(denoiseNestedLevels) if (denoiseNestedLevels>1) #pragma omp parallel for num_threads(denoiseNestedLevels) if (denoiseNestedLevels>1)
@ -2036,6 +2045,13 @@ BENCHFUN
}//end of main RGB_denoise }//end of main RGB_denoise
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
//void ImProcFunctions::RGBtile_denoise(float * fLblox, int hblproc, float noisevar_Ldetail, float * nbrwt, float * blurbuffer) //for DCT
void ImProcFunctions::RGBtile_denoise(float* fLblox, int hblproc, float noisevar_Ldetail) //for DCT void ImProcFunctions::RGBtile_denoise(float* fLblox, int hblproc, float noisevar_Ldetail) //for DCT
{ {
float nbrwt[TS * TS] ALIGNED64; float nbrwt[TS * TS] ALIGNED64;
@ -2062,6 +2078,10 @@ void ImProcFunctions::RGBtile_denoise(float* fLblox, int hblproc, float noisevar
} }
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
void ImProcFunctions::RGBoutput_tile_row(float *bloxrow_L, float ** Ldetail, float ** tilemask_out, int height, int width, int top) void ImProcFunctions::RGBoutput_tile_row(float *bloxrow_L, float ** Ldetail, float ** tilemask_out, int height, int width, int top)
{ {
const int numblox_W = ceil((static_cast<float>(width)) / (offset)); const int numblox_W = ceil((static_cast<float>(width)) / (offset));
@ -2189,11 +2209,19 @@ void ImProcFunctions::Noise_residualAB(const wavelet_decomposition &WaveletCoeff
chmaxresid = maxresid; chmaxresid = maxresid;
} }
bool ImProcFunctions::WaveletDenoiseAll_BiShrinkL(const wavelet_decomposition &WaveletCoeffs_L, float *noisevarlum, float madL[8][3]) bool ImProcFunctions::WaveletDenoiseAll_BiShrinkL(const wavelet_decomposition &WaveletCoeffs_L, float *noisevarlum, float madL[8][3], float * vari, int edge, int denoiseNestedLevels)
{ {
int maxlvl = min(WaveletCoeffs_L.maxlevel(), 5); int maxlvl = min(WaveletCoeffs_L.maxlevel(), 5);
const float eps = 0.01f; const float eps = 0.01f;
if (edge == 1 || edge == 3) {
maxlvl = 4; //for refine denoise edge wavelet
}
if (edge == 2) {
maxlvl = 7; //for locallab denoise
}
int maxWL = 0, maxHL = 0; int maxWL = 0, maxHL = 0;
for (int lvl = 0; lvl < maxlvl; ++lvl) { for (int lvl = 0; lvl < maxlvl; ++lvl) {
@ -2204,6 +2232,7 @@ bool ImProcFunctions::WaveletDenoiseAll_BiShrinkL(const wavelet_decomposition &W
if (WaveletCoeffs_L.level_H(lvl) > maxHL) { if (WaveletCoeffs_L.level_H(lvl) > maxHL) {
maxHL = WaveletCoeffs_L.level_H(lvl); maxHL = WaveletCoeffs_L.level_H(lvl);
} }
} }
bool memoryAllocationFailed = false; bool memoryAllocationFailed = false;
@ -2234,14 +2263,52 @@ bool ImProcFunctions::WaveletDenoiseAll_BiShrinkL(const wavelet_decomposition &W
float ** WavCoeffs_L = WaveletCoeffs_L.level_coeffs(lvl); float ** WavCoeffs_L = WaveletCoeffs_L.level_coeffs(lvl);
if (lvl == maxlvl - 1) { if (lvl == maxlvl - 1) {
int edge = 0; // int edge = 0;
ShrinkAllL(WaveletCoeffs_L, buffer, lvl, dir, noisevarlum, madL[lvl], nullptr, edge); ShrinkAllL(WaveletCoeffs_L, buffer, lvl, dir, noisevarlum, madL[lvl], vari, edge);
} else { } else {
//simple wavelet shrinkage //simple wavelet shrinkage
float * sfave = buffer[0] + 32; float * sfave = buffer[0] + 32;
float * sfaved = buffer[2] + 96; float * sfaved = buffer[2] + 96;
float mad_Lr = madL[lvl][dir - 1]; float mad_Lr = madL[lvl][dir - 1];
/*
if ((edge == 1 || edge == 2 || edge == 3) && vari) {
noisevarlum = blurBuffer; // we need one buffer, but fortunately we don't have to allocate a new one because we can use blurBuffer
for (int i = 0; i < Wlvl_L * Hlvl_L; ++i) {
noisevarlum[i] = vari[lvl];
}
}
*/
float *nvl = nullptr;
nvl = new float[Hlvl_L * Wlvl_L];
for (int i = 0; i < Hlvl_L * Wlvl_L; ++i) {
nvl[i] = 0.f;
}
if ((edge == 1 || edge == 2 || edge == 3) && vari) {
// nvl = blurBuffer; // we need one buffer, but fortunately we don't have to allocate a new one because we can use blurBuffer
if ((edge == 1 || edge == 3)) {
for (int i = 0; i < Hlvl_L * Wlvl_L; ++i) {
nvl[i] = vari[lvl];
}
}
if (edge == 2) {
for (int i = 0; i < Hlvl_L * Wlvl_L; ++i) {
nvl[i] = vari[lvl] * SQR(noisevarlum[i]);
}
}
}
else {
for (int i = 0; i < Hlvl_L * Wlvl_L; ++i) {
nvl[i] = noisevarlum[i];
}
}
float levelFactor = mad_Lr * 5.f / (lvl + 1); float levelFactor = mad_Lr * 5.f / (lvl + 1);
#ifdef __SSE2__ #ifdef __SSE2__
@ -2253,14 +2320,14 @@ bool ImProcFunctions::WaveletDenoiseAll_BiShrinkL(const wavelet_decomposition &W
int coeffloc_L; int coeffloc_L;
for (coeffloc_L = 0; coeffloc_L < Hlvl_L * Wlvl_L - 3; coeffloc_L += 4) { for (coeffloc_L = 0; coeffloc_L < Hlvl_L * Wlvl_L - 3; coeffloc_L += 4) {
mad_Lv = LVFU(noisevarlum[coeffloc_L]) * levelFactorv; mad_Lv = LVFU(nvl[coeffloc_L]) * levelFactorv;
mag_Lv = SQRV(LVFU(WavCoeffs_L[dir][coeffloc_L])); mag_Lv = SQRV(LVFU(WavCoeffs_L[dir][coeffloc_L]));
STVFU(sfave[coeffloc_L], mag_Lv / (mag_Lv + mad_Lv * xexpf(-mag_Lv / (mad_Lv * ninev)) + epsv)); STVFU(sfave[coeffloc_L], mag_Lv / (mag_Lv + mad_Lv * xexpf(-mag_Lv / (mad_Lv * ninev)) + epsv));
} }
for (; coeffloc_L < Hlvl_L * Wlvl_L; ++coeffloc_L) { for (; coeffloc_L < Hlvl_L * Wlvl_L; ++coeffloc_L) {
float mag_L = SQR(WavCoeffs_L[dir][coeffloc_L]); float mag_L = SQR(WavCoeffs_L[dir][coeffloc_L]);
sfave[coeffloc_L] = mag_L / (mag_L + levelFactor * noisevarlum[coeffloc_L] * xexpf(-mag_L / (9.f * levelFactor * noisevarlum[coeffloc_L])) + eps); sfave[coeffloc_L] = mag_L / (mag_L + levelFactor * nvl[coeffloc_L] * xexpf(-mag_L / (9.f * levelFactor * nvl[coeffloc_L])) + eps);
} }
#else #else
@ -2270,12 +2337,13 @@ bool ImProcFunctions::WaveletDenoiseAll_BiShrinkL(const wavelet_decomposition &W
int coeffloc_L = i * Wlvl_L + j; int coeffloc_L = i * Wlvl_L + j;
float mag_L = SQR(WavCoeffs_L[dir][coeffloc_L]); float mag_L = SQR(WavCoeffs_L[dir][coeffloc_L]);
sfave[coeffloc_L] = mag_L / (mag_L + levelFactor * noisevarlum[coeffloc_L] * xexpf(-mag_L / (9.f * levelFactor * noisevarlum[coeffloc_L])) + eps); sfave[coeffloc_L] = mag_L / (mag_L + levelFactor * nvl[coeffloc_L] * xexpf(-mag_L / (9.f * levelFactor * nvl[coeffloc_L])) + eps);
} }
} }
#endif #endif
boxblur(sfave, sfaved, lvl + 2, Wlvl_L, Hlvl_L, false); //increase smoothness by locally averaging shrinkage boxblur(sfave, sfaved, lvl + 2, Wlvl_L, Hlvl_L, false); //increase smoothness by locally averaging shrinkage
#ifdef __SSE2__ #ifdef __SSE2__
vfloat sfavev; vfloat sfavev;
vfloat sf_Lv; vfloat sf_Lv;
@ -2306,7 +2374,9 @@ bool ImProcFunctions::WaveletDenoiseAll_BiShrinkL(const wavelet_decomposition &W
} }
#endif #endif
delete [] nvl;
} }
} }
} }
} }
@ -2321,11 +2391,20 @@ bool ImProcFunctions::WaveletDenoiseAll_BiShrinkL(const wavelet_decomposition &W
return (!memoryAllocationFailed); return (!memoryAllocationFailed);
} }
bool ImProcFunctions::WaveletDenoiseAll_BiShrinkAB(const wavelet_decomposition &WaveletCoeffs_L, const wavelet_decomposition &WaveletCoeffs_ab,
float *noisevarchrom, float madL[8][3], float noisevar_ab, const bool useNoiseCCurve, bool autoch, bool denoiseMethodRgb) bool ImProcFunctions::WaveletDenoiseAll_BiShrinkAB(const wavelet_decomposition &WaveletCoeffs_L, const wavelet_decomposition &WaveletCoeffs_ab, float *noisevarchrom, float madL[8][3], float *variC, int local, float noisevar_ab, const bool useNoiseCCurve, bool autoch, bool denoiseMethodRgb, int denoiseNestedLevels)
{ {
int maxlvl = WaveletCoeffs_L.maxlevel(); int maxlvl = WaveletCoeffs_L.maxlevel();
if (local == 2) {
maxlvl = 7; //for local denoise
}
if (local == 3) {
maxlvl = 4; //for shape detection
}
if (autoch && noisevar_ab <= 0.001f) { if (autoch && noisevar_ab <= 0.001f) {
noisevar_ab = 0.02f; noisevar_ab = 0.02f;
} }
@ -2393,14 +2472,36 @@ bool ImProcFunctions::WaveletDenoiseAll_BiShrinkAB(const wavelet_decomposition &
float ** WavCoeffs_ab = WaveletCoeffs_ab.level_coeffs(lvl); float ** WavCoeffs_ab = WaveletCoeffs_ab.level_coeffs(lvl);
if (lvl == maxlvl - 1) { if (lvl == maxlvl - 1) {
ShrinkAllAB(WaveletCoeffs_L, WaveletCoeffs_ab, buffer, lvl, dir, noisevarchrom, noisevar_ab, useNoiseCCurve, autoch, denoiseMethodRgb, madL[lvl], madab[lvl], true); ShrinkAllAB(WaveletCoeffs_L, WaveletCoeffs_ab, buffer, lvl, dir, noisevarchrom, noisevar_ab, useNoiseCCurve, autoch, denoiseMethodRgb, madL[lvl], nullptr, 0, madab[lvl], true);
} else { } else {
//simple wavelet shrinkage //simple wavelet shrinkage
float noisevarfc;
float mad_Lr = madL[lvl][dir - 1]; float mad_Lr = madL[lvl][dir - 1];
float mad_abr = useNoiseCCurve ? noisevar_ab * madab[lvl][dir - 1] : SQR(noisevar_ab) * madab[lvl][dir - 1]; float *nvc = nullptr;
nvc = new float[Hlvl_ab * Wlvl_ab];
if (noisevar_ab > 0.001f) { if ((local == 2 || local == 3) && variC && useNoiseCCurve) {
noisevarfc = variC[lvl];
for (int p = 0; p < Hlvl_ab * Wlvl_ab; p++) {
nvc[p] = 10.f * sqrt(variC[lvl]) * SQR(1.f + 4.f * noisevarchrom[p]);
}
} else {
noisevarfc = noisevar_ab;
for (int p = 0; p < Hlvl_ab * Wlvl_ab; p++) {
nvc[p] = noisevarchrom[p];
}
}
// float mad_abr = useNoiseCCurve ? noisevar_ab * madab[lvl][dir - 1] : SQR(noisevar_ab) * madab[lvl][dir - 1];
float mad_abr = useNoiseCCurve ? noisevarfc * madab[lvl][dir - 1] : SQR(noisevarfc) * madab[lvl][dir - 1];
if (noisevarfc > 0.001f) {
#ifdef __SSE2__ #ifdef __SSE2__
vfloat onev = F2V(1.f); vfloat onev = F2V(1.f);
@ -2412,7 +2513,7 @@ bool ImProcFunctions::WaveletDenoiseAll_BiShrinkAB(const wavelet_decomposition &
int coeffloc_ab; int coeffloc_ab;
for (coeffloc_ab = 0; coeffloc_ab < Hlvl_ab * Wlvl_ab - 3; coeffloc_ab += 4) { for (coeffloc_ab = 0; coeffloc_ab < Hlvl_ab * Wlvl_ab - 3; coeffloc_ab += 4) {
mad_abv = LVFU(noisevarchrom[coeffloc_ab]) * mad_abrv; mad_abv = LVFU(nvc[coeffloc_ab]) * mad_abrv;
tempabv = LVFU(WavCoeffs_ab[dir][coeffloc_ab]); tempabv = LVFU(WavCoeffs_ab[dir][coeffloc_ab]);
mag_Lv = LVFU(WavCoeffs_L[dir][coeffloc_ab]); mag_Lv = LVFU(WavCoeffs_L[dir][coeffloc_ab]);
@ -2425,7 +2526,7 @@ bool ImProcFunctions::WaveletDenoiseAll_BiShrinkAB(const wavelet_decomposition &
for (; coeffloc_ab < Hlvl_ab * Wlvl_ab; ++coeffloc_ab) { for (; coeffloc_ab < Hlvl_ab * Wlvl_ab; ++coeffloc_ab) {
float mag_L = SQR(WavCoeffs_L[dir][coeffloc_ab ]); float mag_L = SQR(WavCoeffs_L[dir][coeffloc_ab ]);
float mag_ab = SQR(WavCoeffs_ab[dir][coeffloc_ab]); float mag_ab = SQR(WavCoeffs_ab[dir][coeffloc_ab]);
WavCoeffs_ab[dir][coeffloc_ab] *= SQR(1.f - xexpf(-(mag_ab / (noisevarchrom[coeffloc_ab] * mad_abr)) - (mag_L / (9.f * mad_Lr)))/*satfactor_a*/); WavCoeffs_ab[dir][coeffloc_ab] *= SQR(1.f - xexpf(-(mag_ab / (nvc[coeffloc_ab] * mad_abr)) - (mag_L / (9.f * mad_Lr)))/*satfactor_a*/);
}//now chrominance coefficients are denoised }//now chrominance coefficients are denoised
#else #else
@ -2437,7 +2538,7 @@ bool ImProcFunctions::WaveletDenoiseAll_BiShrinkAB(const wavelet_decomposition &
float mag_L = SQR(WavCoeffs_L[dir][coeffloc_ab ]); float mag_L = SQR(WavCoeffs_L[dir][coeffloc_ab ]);
float mag_ab = SQR(WavCoeffs_ab[dir][coeffloc_ab]); float mag_ab = SQR(WavCoeffs_ab[dir][coeffloc_ab]);
WavCoeffs_ab[dir][coeffloc_ab] *= SQR(1.f - xexpf(-(mag_ab / (noisevarchrom[coeffloc_ab] * mad_abr)) - (mag_L / (9.f * mad_Lr)))/*satfactor_a*/); WavCoeffs_ab[dir][coeffloc_ab] *= SQR(1.f - xexpf(-(mag_ab / (nvc[coeffloc_ab] * mad_abr)) - (mag_L / (9.f * mad_Lr)))/*satfactor_a*/);
} }
}//now chrominance coefficients are denoised }//now chrominance coefficients are denoised
@ -2445,9 +2546,12 @@ bool ImProcFunctions::WaveletDenoiseAll_BiShrinkAB(const wavelet_decomposition &
#endif #endif
} }
delete [] nvc;
} }
} }
} }
} }
for (int i = 2; i >= 0; i--) { for (int i = 2; i >= 0; i--) {
@ -2459,16 +2563,20 @@ bool ImProcFunctions::WaveletDenoiseAll_BiShrinkAB(const wavelet_decomposition &
} }
bool ImProcFunctions::WaveletDenoiseAllL(const wavelet_decomposition &WaveletCoeffs_L, float *noisevarlum, float madL[8][3], float * vari, int edge)//mod JD bool ImProcFunctions::WaveletDenoiseAllL(const wavelet_decomposition &WaveletCoeffs_L, float *noisevarlum, float madL[8][3], float * vari, int edge, int denoiseNestedLevels)//mod JD
{ {
int maxlvl = min(WaveletCoeffs_L.maxlevel(), 5); int maxlvl = min(WaveletCoeffs_L.maxlevel(), 5);
if (edge == 1) { if (edge == 1 || edge == 3) {
maxlvl = 4; //for refine denoise edge wavelet maxlvl = 4; //for refine denoise edge wavelet
} }
if (edge == 2) {
maxlvl = 7; //for locallab denoise
}
int maxWL = 0, maxHL = 0; int maxWL = 0, maxHL = 0;
for (int lvl = 0; lvl < maxlvl; ++lvl) { for (int lvl = 0; lvl < maxlvl; ++lvl) {
@ -2517,11 +2625,20 @@ bool ImProcFunctions::WaveletDenoiseAllL(const wavelet_decomposition &WaveletCoe
bool ImProcFunctions::WaveletDenoiseAllAB(const wavelet_decomposition &WaveletCoeffs_L, const wavelet_decomposition &WaveletCoeffs_ab, bool ImProcFunctions::WaveletDenoiseAllAB(const wavelet_decomposition &WaveletCoeffs_L, const wavelet_decomposition &WaveletCoeffs_ab,
float *noisevarchrom, float madL[8][3], float noisevar_ab, const bool useNoiseCCurve, bool autoch, bool denoiseMethodRgb)//mod JD float *noisevarchrom, float madL[8][3], float *variC, int local, float noisevar_ab, const bool useNoiseCCurve, bool autoch, bool denoiseMethodRgb, int denoiseNestedLevels)//mod JD
{ {
int maxlvl = WaveletCoeffs_L.maxlevel(); int maxlvl = WaveletCoeffs_L.maxlevel();
if (local == 2) {
maxlvl = 7; //for local denoise
}
if (local == 3) {
maxlvl = 4; //for shape detection
}
int maxWL = 0, maxHL = 0; int maxWL = 0, maxHL = 0;
for (int lvl = 0; lvl < maxlvl; ++lvl) { for (int lvl = 0; lvl < maxlvl; ++lvl) {
@ -2555,7 +2672,7 @@ bool ImProcFunctions::WaveletDenoiseAllAB(const wavelet_decomposition &WaveletCo
for (int lvl = 0; lvl < maxlvl; ++lvl) { for (int lvl = 0; lvl < maxlvl; ++lvl) {
for (int dir = 1; dir < 4; ++dir) { for (int dir = 1; dir < 4; ++dir) {
ShrinkAllAB(WaveletCoeffs_L, WaveletCoeffs_ab, buffer, lvl, dir, noisevarchrom, noisevar_ab, useNoiseCCurve, autoch, denoiseMethodRgb, madL[lvl]); ShrinkAllAB(WaveletCoeffs_L, WaveletCoeffs_ab, buffer, lvl, dir, noisevarchrom, noisevar_ab, useNoiseCCurve, autoch, denoiseMethodRgb, madL[lvl], variC, local, nullptr, 0);
} }
} }
} }
@ -2569,8 +2686,6 @@ bool ImProcFunctions::WaveletDenoiseAllAB(const wavelet_decomposition &WaveletCo
return (!memoryAllocationFailed); return (!memoryAllocationFailed);
} }
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
void ImProcFunctions::ShrinkAllL(const wavelet_decomposition &WaveletCoeffs_L, float **buffer, int level, int dir, void ImProcFunctions::ShrinkAllL(const wavelet_decomposition &WaveletCoeffs_L, float **buffer, int level, int dir,
@ -2582,7 +2697,7 @@ void ImProcFunctions::ShrinkAllL(const wavelet_decomposition &WaveletCoeffs_L, f
float * sfave = buffer[0] + 32; float * sfave = buffer[0] + 32;
float * sfaved = buffer[1] + 64; float * sfaved = buffer[1] + 64;
float * blurBuffer = buffer[2] + 96; // float * blurBuffer = buffer[2] + 96;
const int W_L = WaveletCoeffs_L.level_W(level); const int W_L = WaveletCoeffs_L.level_W(level);
const int H_L = WaveletCoeffs_L.level_H(level); const int H_L = WaveletCoeffs_L.level_H(level);
@ -2591,30 +2706,54 @@ void ImProcFunctions::ShrinkAllL(const wavelet_decomposition &WaveletCoeffs_L, f
const float mad_L = madL[dir - 1] ; const float mad_L = madL[dir - 1] ;
const float levelFactor = mad_L * 5.f / static_cast<float>(level + 1); const float levelFactor = mad_L * 5.f / static_cast<float>(level + 1);
if (edge == 1 && vari) { float *nvl = nullptr;
noisevarlum = blurBuffer; // we need one buffer, but fortunately we don't have to allocate a new one because we can use blurBuffer nvl = new float[ H_L * W_L];
for (int i = 0; i < W_L * H_L; ++i) { for (int i = 0; i < W_L * H_L; ++i) {
noisevarlum[i] = vari[level]; nvl[i] = 0.f;
}
} }
if ((edge == 1 || edge == 2 || edge == 3) && vari) {
// nvl = blurBuffer; // we need one buffer, but fortunately we don't have to allocate a new one because we can use blurBuffer
if ((edge == 1 || edge == 3)) {
for (int i = 0; i < W_L * H_L; ++i) {
nvl[i] = vari[level]; //* SQR(1.f + 4.f * noisevarchrom[p]);
}
}
if (edge == 2) {
for (int i = 0; i < W_L * H_L; ++i) {
nvl[i] = vari[level] * SQR(noisevarlum[i]);
}
}
}
else {
for (int i = 0; i < W_L * H_L; ++i) {
nvl[i] = noisevarlum[i];
}
}
int i = 0; int i = 0;
#ifdef __SSE2__ #ifdef __SSE2__
const vfloat levelFactorv = F2V(levelFactor); const vfloat levelFactorv = F2V(levelFactor);
const vfloat ninev = F2V(9.f); const vfloat ninev = F2V(9.f);
const vfloat epsv = F2V(eps); const vfloat epsv = F2V(eps);
for (; i < W_L * H_L - 3; i += 4) {
const vfloat mad_Lv = LVFU(noisevarlum[i]) * levelFactorv; for (i = 0; i < W_L * H_L - 3; i += 4) {
// const vfloat mad_Lv = LVFU(noisevarlum[i]) * levelFactorv;
const vfloat mad_Lv = LVFU(nvl[i]) * levelFactorv;
const vfloat magv = SQRV(LVFU(WavCoeffs_L[dir][i])); const vfloat magv = SQRV(LVFU(WavCoeffs_L[dir][i]));
STVFU(sfave[i], magv / (magv + mad_Lv * xexpf(-magv / (ninev * mad_Lv)) + epsv)); STVFU(sfave[i], magv / (magv + mad_Lv * xexpf(-magv / (ninev * mad_Lv)) + epsv));
} }
#endif #endif
// few remaining pixels // few remaining pixels
for (; i < W_L * H_L; ++i) { for (; i < W_L * H_L; ++i) {
const float mag = SQR(WavCoeffs_L[dir][i]); float mag = SQR(WavCoeffs_L[dir][i]);
sfave[i] = mag / (mag + levelFactor * noisevarlum[i] * xexpf(-mag / (9 * levelFactor * noisevarlum[i])) + eps); sfave[i] = mag / (mag + levelFactor * nvl[i] * xexpf(-mag / (9 * levelFactor * nvl[i])) + eps);
} }
boxblur(sfave, sfaved, level + 2, W_L, H_L, false); //increase smoothness by locally averaging shrinkage boxblur(sfave, sfaved, level + 2, W_L, H_L, false); //increase smoothness by locally averaging shrinkage
@ -2634,12 +2773,15 @@ void ImProcFunctions::ShrinkAllL(const wavelet_decomposition &WaveletCoeffs_L, f
//use smoothed shrinkage unless local shrinkage is much less //use smoothed shrinkage unless local shrinkage is much less
WavCoeffs_L[dir][i] *= (SQR(sfaved[i]) + SQR(sf)) / (sfaved[i] + sf + eps); WavCoeffs_L[dir][i] *= (SQR(sfaved[i]) + SQR(sf)) / (sfaved[i] + sf + eps);
}//now luminance coefficients are denoised }//now luminance coefficients are denoised
delete [] nvl;
} }
void ImProcFunctions::ShrinkAllAB(const wavelet_decomposition &WaveletCoeffs_L, const wavelet_decomposition &WaveletCoeffs_ab, float **buffer, int level, int dir, void ImProcFunctions::ShrinkAllAB(const wavelet_decomposition & WaveletCoeffs_L, const wavelet_decomposition & WaveletCoeffs_ab, float **buffer, int level, int dir,
float *noisevarchrom, float noisevar_ab, const bool useNoiseCCurve, bool autoch, float * noisevarchrom, float noisevar_ab, const bool useNoiseCCurve, bool autoch,
bool denoiseMethodRgb, float * madL, float * madaab, bool madCalculated) bool denoiseMethodRgb, float * madL, float * variC, int local, float * madaab, bool madCalculated)
{ {
//simple wavelet shrinkage //simple wavelet shrinkage
@ -2651,6 +2793,7 @@ void ImProcFunctions::ShrinkAllAB(const wavelet_decomposition &WaveletCoeffs_L,
float * sfaveab = buffer[0] + 32; float * sfaveab = buffer[0] + 32;
float * sfaveabd = buffer[1] + 64; float * sfaveabd = buffer[1] + 64;
// float * blurBuffer = buffer[2] + 96;
int W_ab = WaveletCoeffs_ab.level_W(level); int W_ab = WaveletCoeffs_ab.level_W(level);
int H_ab = WaveletCoeffs_ab.level_H(level); int H_ab = WaveletCoeffs_ab.level_H(level);
@ -2670,9 +2813,30 @@ void ImProcFunctions::ShrinkAllAB(const wavelet_decomposition &WaveletCoeffs_L,
madab = SQR(MadRgb(WavCoeffs_ab[dir], W_ab * H_ab)); madab = SQR(MadRgb(WavCoeffs_ab[dir], W_ab * H_ab));
} }
} }
float noisevarfc;
if (noisevar_ab > 0.001f) { float *nvc = nullptr;
madab = useNoiseCCurve ? madab : madab * noisevar_ab; nvc = new float[ H_ab * W_ab];
if ((local == 2 || local == 3) && variC && useNoiseCCurve) {
noisevarfc = variC[level];
for (int p = 0; p < H_ab * W_ab; p++) {
nvc[p] = 10.f * sqrt(variC[level]) * SQR(1.f + 4.f * noisevarchrom[p]);
}
} else {
noisevarfc = noisevar_ab;
for (int p = 0; p < H_ab * W_ab; p++) {
nvc[p] = noisevarchrom[p];
}
}
// printf("varfc=%f nvc0=%f nvc1=%f nvc2=%f\n", noisevarfc, nvc[10], nvc[H_ab * W_ab /3], nvc[H_ab * W_ab /2]);
if (noisevarfc > 0.001f) {//noisevar_ab
//madab = useNoiseCCurve ? madab : madab * noisevar_ab;
madab = useNoiseCCurve ? madab : madab * noisevarfc;
#ifdef __SSE2__ #ifdef __SSE2__
vfloat onev = F2V(1.f); vfloat onev = F2V(1.f);
vfloat mad_abrv = F2V(madab); vfloat mad_abrv = F2V(madab);
@ -2680,10 +2844,11 @@ void ImProcFunctions::ShrinkAllAB(const wavelet_decomposition &WaveletCoeffs_L,
vfloat rmadLm9v = onev / F2V(mad_L * 9.f); vfloat rmadLm9v = onev / F2V(mad_L * 9.f);
vfloat mad_abv ; vfloat mad_abv ;
vfloat mag_Lv, mag_abv; vfloat mag_Lv, mag_abv;
int coeffloc_ab; int coeffloc_ab;
for (coeffloc_ab = 0; coeffloc_ab < H_ab * W_ab - 3; coeffloc_ab += 4) { for (coeffloc_ab = 0; coeffloc_ab < H_ab * W_ab - 3; coeffloc_ab += 4) {
mad_abv = LVFU(noisevarchrom[coeffloc_ab]) * mad_abrv; mad_abv = LVFU(nvc[coeffloc_ab]) * mad_abrv;
mag_Lv = LVFU(WavCoeffs_L[dir][coeffloc_ab]); mag_Lv = LVFU(WavCoeffs_L[dir][coeffloc_ab]);
mag_abv = SQRV(LVFU(WavCoeffs_ab[dir][coeffloc_ab])); mag_abv = SQRV(LVFU(WavCoeffs_ab[dir][coeffloc_ab]));
@ -2695,7 +2860,7 @@ void ImProcFunctions::ShrinkAllAB(const wavelet_decomposition &WaveletCoeffs_L,
for (; coeffloc_ab < H_ab * W_ab; ++coeffloc_ab) { for (; coeffloc_ab < H_ab * W_ab; ++coeffloc_ab) {
float mag_L = SQR(WavCoeffs_L[dir][coeffloc_ab]); float mag_L = SQR(WavCoeffs_L[dir][coeffloc_ab]);
float mag_ab = SQR(WavCoeffs_ab[dir][coeffloc_ab]); float mag_ab = SQR(WavCoeffs_ab[dir][coeffloc_ab]);
sfaveab[coeffloc_ab] = (1.f - xexpf(-(mag_ab / (noisevarchrom[coeffloc_ab] * madab)) - (mag_L / (9.f * mad_L)))); sfaveab[coeffloc_ab] = (1.f - xexpf(-(mag_ab / (nvc[coeffloc_ab] * madab)) - (mag_L / (9.f * mad_L))));
}//now chrominance coefficients are denoised }//now chrominance coefficients are denoised
#else #else
@ -2705,13 +2870,14 @@ void ImProcFunctions::ShrinkAllAB(const wavelet_decomposition &WaveletCoeffs_L,
int coeffloc_ab = i * W_ab + j; int coeffloc_ab = i * W_ab + j;
float mag_L = SQR(WavCoeffs_L[dir][coeffloc_ab]); float mag_L = SQR(WavCoeffs_L[dir][coeffloc_ab]);
float mag_ab = SQR(WavCoeffs_ab[dir][coeffloc_ab]); float mag_ab = SQR(WavCoeffs_ab[dir][coeffloc_ab]);
sfaveab[coeffloc_ab] = (1.f - xexpf(-(mag_ab / (noisevarchrom[coeffloc_ab] * madab)) - (mag_L / (9.f * mad_L)))); sfaveab[coeffloc_ab] = (1.f - xexpf(-(mag_ab / (nvc[coeffloc_ab] * madab)) - (mag_L / (9.f * mad_L))));
} }
}//now chrominance coefficients are denoised }//now chrominance coefficients are denoised
#endif #endif
boxblur(sfaveab, sfaveabd, level + 2, W_ab, H_ab, false); //increase smoothness by locally averaging shrinkage boxblur(sfaveab, sfaveabd, level + 2, W_ab, H_ab, false); //increase smoothness by locally averaging shrinkage
// boxblur(sfaveab, sfaveabd, blurBuffer, level + 2, level + 2, W_ab, H_ab); //increase smoothness by locally averaging shrinkage
#ifdef __SSE2__ #ifdef __SSE2__
vfloat epsv = F2V(eps); vfloat epsv = F2V(eps);
vfloat sfabv; vfloat sfabv;
@ -2749,12 +2915,13 @@ void ImProcFunctions::ShrinkAllAB(const wavelet_decomposition &WaveletCoeffs_L,
#endif #endif
} }
delete [] nvc;
} }
void ImProcFunctions::ShrinkAll_info(float ** WavCoeffs_a, float ** WavCoeffs_b, void ImProcFunctions::ShrinkAll_info(float ** WavCoeffs_a, float ** WavCoeffs_b,
int W_ab, int H_ab, float **noisevarlum, float **noisevarchrom, float **noisevarhue, float &chaut, int &Nb, float &redaut, float &blueaut, int W_ab, int H_ab, float **noisevarlum, float **noisevarchrom, float **noisevarhue, float & chaut, int &Nb, float & redaut, float & blueaut,
float &maxredaut, float &maxblueaut, float &minredaut, float &minblueaut, int schoice, int lvl, float &chromina, float &sigma, float &lumema, float &sigma_L, float &redyel, float &skinc, float &nsknc, float & maxredaut, float & maxblueaut, float & minredaut, float & minblueaut, int schoice, int lvl, float & chromina, float & sigma, float & lumema, float & sigma_L, float & redyel, float & skinc, float & nsknc,
float &maxchred, float &maxchblue, float &minchred, float &minchblue, int &nb, float &chau, float &chred, float &chblue, bool denoiseMethodRgb) float & maxchred, float & maxchblue, float & minchred, float & minchblue, int &nb, float & chau, float & chred, float & chblue, bool denoiseMethodRgb)
{ {
//simple wavelet shrinkage //simple wavelet shrinkage
@ -2869,9 +3036,9 @@ void ImProcFunctions::ShrinkAll_info(float ** WavCoeffs_a, float ** WavCoeffs_b,
} }
void ImProcFunctions::WaveletDenoiseAll_info(int levwav, const wavelet_decomposition &WaveletCoeffs_a, void ImProcFunctions::WaveletDenoiseAll_info(int levwav, const wavelet_decomposition & WaveletCoeffs_a,
const wavelet_decomposition &WaveletCoeffs_b, float **noisevarlum, float **noisevarchrom, float **noisevarhue, float &chaut, int &Nb, float &redaut, float &blueaut, float &maxredaut, float &maxblueaut, float &minredaut, float &minblueaut, int schoice, const wavelet_decomposition & WaveletCoeffs_b, float **noisevarlum, float **noisevarchrom, float **noisevarhue, float & chaut, int &Nb, float & redaut, float & blueaut, float & maxredaut, float & maxblueaut, float & minredaut, float & minblueaut, int schoice,
float &chromina, float &sigma, float &lumema, float &sigma_L, float &redyel, float &skinc, float &nsknc, float &maxchred, float &maxchblue, float &minchred, float &minchblue, int &nb, float &chau, float &chred, float &chblue, bool denoiseMethodRgb) float & chromina, float & sigma, float & lumema, float & sigma_L, float & redyel, float & skinc, float & nsknc, float & maxchred, float & maxchblue, float & minchred, float & minchblue, int &nb, float & chau, float & chred, float & chblue, bool denoiseMethodRgb)
{ {
int maxlvl = levwav; int maxlvl = levwav;
@ -2914,7 +3081,7 @@ void ImProcFunctions::RGB_denoise_infoGamCurve(const procparams::DirPyrDenoisePa
} }
} }
void ImProcFunctions::calcautodn_info(float &chaut, float &delta, int Nb, int levaut, float maxmax, float lumema, float chromina, int mode, int lissage, float redyel, float skinc, float nsknc) void ImProcFunctions::calcautodn_info(float & chaut, float & delta, int Nb, int levaut, float maxmax, float lumema, float chromina, int mode, int lissage, float redyel, float skinc, float nsknc)
{ {
float reducdelta = 1.f; float reducdelta = 1.f;

View File

@ -238,18 +238,29 @@ public:
void RGB_denoise_info(Imagefloat * src, Imagefloat * provicalc, bool isRAW, const LUTf &gamcurve, float gam, float gamthresh, float gamslope, const procparams::DirPyrDenoiseParams & dnparams, const double expcomp, float &chaut, int &Nb, float &redaut, float &blueaut, float &maxredaut, float & maxblueaut, float &minredaut, float & minblueaut, float &chromina, float &sigma, float &lumema, float &sigma_L, float &redyel, float &skinc, float &nsknc, bool multiThread = false); void RGB_denoise_info(Imagefloat * src, Imagefloat * provicalc, bool isRAW, const LUTf &gamcurve, float gam, float gamthresh, float gamslope, const procparams::DirPyrDenoiseParams & dnparams, const double expcomp, float &chaut, int &Nb, float &redaut, float &blueaut, float &maxredaut, float & maxblueaut, float &minredaut, float & minblueaut, float &chromina, float &sigma, float &lumema, float &sigma_L, float &redyel, float &skinc, float &nsknc, bool multiThread = false);
void RGBtile_denoise(float * fLblox, int hblproc, float noisevar_Ldetail); //for DCT void RGBtile_denoise(float * fLblox, int hblproc, float noisevar_Ldetail); //for DCT
void RGBoutput_tile_row(float *bloxrow_L, float ** Ldetail, float ** tilemask_out, int height, int width, int top); void RGBoutput_tile_row(float *bloxrow_L, float ** Ldetail, float ** tilemask_out, int height, int width, int top);
bool WaveletDenoiseAllL(const wavelet_decomposition &WaveletCoeffs_L, float *noisevarlum, float madL[8][3], float * vari, int edge); // bool WaveletDenoiseAllL(const wavelet_decomposition &WaveletCoeffs_L, float *noisevarlum, float madL[8][3], float * vari, int edge);
bool WaveletDenoiseAllAB(const wavelet_decomposition &WaveletCoeffs_L, const wavelet_decomposition &WaveletCoeffs_ab, float *noisevarchrom, float madL[8][3], float noisevar_ab, const bool useNoiseCCurve, bool autoch, bool denoiseMethodRgb); // bool WaveletDenoiseAllAB(const wavelet_decomposition &WaveletCoeffs_L, const wavelet_decomposition &WaveletCoeffs_ab, float *noisevarchrom, float madL[8][3], float noisevar_ab, const bool useNoiseCCurve, bool autoch, bool denoiseMethodRgb);
void WaveletDenoiseAll_info(int levwav, const wavelet_decomposition &WaveletCoeffs_a, void WaveletDenoiseAll_info(int levwav, const wavelet_decomposition &WaveletCoeffs_a,
const wavelet_decomposition &WaveletCoeffs_b, float **noisevarlum, float **noisevarchrom, float **noisevarhue, float &chaut, int &Nb, float &redaut, float &blueaut, float &maxredaut, float &maxblueaut, float &minredaut, float & minblueaut, int schoice, float &chromina, float &sigma, float &lumema, float &sigma_L, float &redyel, float &skinc, float &nsknc, const wavelet_decomposition &WaveletCoeffs_b, float **noisevarlum, float **noisevarchrom, float **noisevarhue, float &chaut, int &Nb, float &redaut, float &blueaut, float &maxredaut, float &maxblueaut, float &minredaut, float & minblueaut, int schoice, float &chromina, float &sigma, float &lumema, float &sigma_L, float &redyel, float &skinc, float &nsknc,
float &maxchred, float &maxchblue, float &minchred, float &minchblue, int &nb, float &chau, float &chred, float &chblue, bool denoiseMethodRgb); float &maxchred, float &maxchblue, float &minchred, float &minchblue, int &nb, float &chau, float &chred, float &chblue, bool denoiseMethodRgb);
bool WaveletDenoiseAll_BiShrinkL(const wavelet_decomposition &WaveletCoeffs_L, float *noisevarlum, float madL[8][3]); bool WaveletDenoiseAllL(const wavelet_decomposition &WaveletCoeffs_L, float *noisevarlum, float madL[8][3], float * vari, int edge, int denoiseNestedLevels);
bool WaveletDenoiseAll_BiShrinkAB(const wavelet_decomposition &WaveletCoeffs_L, const wavelet_decomposition &WaveletCoeffs_ab, float *noisevarchrom, float madL[8][3], float noisevar_ab, bool WaveletDenoiseAllAB(const wavelet_decomposition &WaveletCoeffs_L, const wavelet_decomposition &WaveletCoeffs_ab, float *noisevarchrom, float madL[8][3], float *variC, int local, float noisevar_ab, const bool useNoiseCCurve, bool autoch, bool denoiseMethodRgb, int denoiseNestedLevels);
const bool useNoiseCCurve, bool autoch, bool denoiseMethodRgb); bool WaveletDenoiseAll_BiShrinkAB(const wavelet_decomposition &WaveletCoeffs_L, const wavelet_decomposition &WaveletCoeffs_ab, float *noisevarchrom, float madL[8][3], float *variC, int local, float noisevar_ab, const bool useNoiseCCurve, bool autoch, bool denoiseMethodRgb, int denoiseNestedLevels);
bool WaveletDenoiseAll_BiShrinkL(const wavelet_decomposition &WaveletCoeffs_L, float *noisevarlum, float madL[8][3], float * vari, int edge, int denoiseNestedLevels);
// bool WaveletDenoiseAll_BiShrinkL(const wavelet_decomposition &WaveletCoeffs_L, float *noisevarlum, float madL[8][3]);
// bool WaveletDenoiseAll_BiShrinkAB(const wavelet_decomposition &WaveletCoeffs_L, const wavelet_decomposition &WaveletCoeffs_ab, float *noisevarchrom, float madL[8][3], float noisevar_ab,
// const bool useNoiseCCurve, bool autoch, bool denoiseMethodRgb);
void ShrinkAllL(const wavelet_decomposition &WaveletCoeffs_L, float **buffer, int level, int dir, float *noisevarlum, float * madL, float * vari, int edge); void ShrinkAllL(const wavelet_decomposition &WaveletCoeffs_L, float **buffer, int level, int dir, float *noisevarlum, float * madL, float * vari, int edge);
void ShrinkAllAB(const wavelet_decomposition &WaveletCoeffs_L, const wavelet_decomposition &WaveletCoeffs_ab, float **buffer, int level, int dir, void ShrinkAllAB(const wavelet_decomposition &WaveletCoeffs_L, const wavelet_decomposition &WaveletCoeffs_ab, float **buffer, int level, int dir,
float *noisevarchrom, float noisevar_ab, const bool useNoiseCCurve, bool autoch, bool denoiseMethodRgb, float * madL, float * madaab = nullptr, bool madCalculated = false); float *noisevarchrom, float noisevar_ab, const bool useNoiseCCurve, bool autoch, bool denoiseMethodRgb, float * madL, float * variC, int local, float * madaab = nullptr, bool madCalculated = false);
// void ShrinkAllL(const wavelet_decomposition &WaveletCoeffs_L, float **buffer, int level, int dir, float *noisevarlum, float * madL, float * vari, int edge);
// void ShrinkAllAB(const wavelet_decomposition &WaveletCoeffs_L, const wavelet_decomposition &WaveletCoeffs_ab, float **buffer, int level, int dir,
// float *noisevarchrom, float noisevar_ab, const bool useNoiseCCurve, bool autoch, bool denoiseMethodRgb, float * madL, float * madaab = nullptr, bool madCalculated = false);
void ShrinkAll_info(float ** WavCoeffs_a, float ** WavCoeffs_b, void ShrinkAll_info(float ** WavCoeffs_a, float ** WavCoeffs_b,
int W_ab, int H_ab, float **noisevarlum, float **noisevarchrom, float **noisevarhue, float &chaut, int &Nb, float &redaut, float &blueaut, float &maxredaut, float &maxblueaut, float &minredaut, float &minblueaut, int schoice, int lvl, float &chromina, float &sigma, float &lumema, float &sigma_L, float &redyel, float &skinc, float &nsknc, int W_ab, int H_ab, float **noisevarlum, float **noisevarchrom, float **noisevarhue, float &chaut, int &Nb, float &redaut, float &blueaut, float &maxredaut, float &maxblueaut, float &minredaut, float &minblueaut, int schoice, int lvl, float &chromina, float &sigma, float &lumema, float &sigma_L, float &redyel, float &skinc, float &nsknc,
float &maxchred, float &maxchblue, float &minchred, float &minchblue, int &nb, float &chau, float &chred, float &chblue, bool denoiseMethodRgb); float &maxchred, float &maxchblue, float &minchred, float &minchblue, int &nb, float &chau, float &chred, float &chblue, bool denoiseMethodRgb);

View File

@ -138,6 +138,9 @@ struct cont_params {
float edgampl; float edgampl;
int neigh; int neigh;
bool lipp; bool lipp;
float balchrom;
float chromfi;
float chromco;
}; };
int wavNestedLevels = 1; int wavNestedLevels = 1;
@ -196,6 +199,7 @@ void ImProcFunctions::ip_wavelet(LabImage * lab, LabImage * dst, int kall, const
if (params->wavelet.BAmethod != "none") { if (params->wavelet.BAmethod != "none") {
cp.bam = true; cp.bam = true;
if (params->wavelet.BAmethod == "sli") { if (params->wavelet.BAmethod == "sli") {
cp.BAmet = 1; cp.BAmet = 1;
} else if (params->wavelet.BAmethod == "cur") { } else if (params->wavelet.BAmethod == "cur") {
@ -260,7 +264,7 @@ void ImProcFunctions::ip_wavelet(LabImage * lab, LabImage * dst, int kall, const
DaubLen = 8; DaubLen = 8;
} else if (params->wavelet.daubcoeffmethod == "10_") { } else if (params->wavelet.daubcoeffmethod == "10_") {
DaubLen = 12; DaubLen = 12;
} else /* if (params->wavelet.daubcoeffmethod == "14_") */{ } else { /* if (params->wavelet.daubcoeffmethod == "14_") */
DaubLen = 16; DaubLen = 16;
} }
@ -394,6 +398,9 @@ void ImProcFunctions::ip_wavelet(LabImage * lab, LabImage * dst, int kall, const
cp.val = waparams.edgval; cp.val = waparams.edgval;
cp.til = waparams.edgthresh; cp.til = waparams.edgthresh;
cp.eff = waparams.edgeffect; cp.eff = waparams.edgeffect;
cp.balchrom = waparams.balchrom;
cp.chromfi = waparams.chromfi;
cp.chromco = waparams.chromco;
cp.conres = waparams.rescon; cp.conres = waparams.rescon;
cp.conresH = waparams.resconH; cp.conresH = waparams.resconH;
@ -877,7 +884,7 @@ void ImProcFunctions::ip_wavelet(LabImage * lab, LabImage * dst, int kall, const
vari[3] = rtengine::max(0.0001f, vari[3]); vari[3] = rtengine::max(0.0001f, vari[3]);
float* noisevarlum = nullptr; // we need a dummy to pass it to WaveletDenoiseAllL float* noisevarlum = nullptr; // we need a dummy to pass it to WaveletDenoiseAllL
WaveletDenoiseAllL(*Ldecomp, noisevarlum, madL, vari, edge); WaveletDenoiseAllL(*Ldecomp, noisevarlum, madL, vari, edge, 1);
} }
//Flat curve for Contrast=f(H) in levels //Flat curve for Contrast=f(H) in levels
@ -906,6 +913,213 @@ void ImProcFunctions::ip_wavelet(LabImage * lab, LabImage * dst, int kall, const
} }
} }
/*
float variC[7];
float variCb[7];
float noisecfr = cp.chromfi;
float noiseccr = cp.chromco;
if (cp.balchrom > 0.f) {
noisecfr = cp.chromfi * ((100.f + cp.balchrom) / 10.f);
noiseccr = cp.chromco + ((100.f + cp.balchrom) / 10.f);
}
float noisecfb = cp.chromfi;
float noiseccb = cp.chromco;
if (cp.balchrom < 0.f) {
noisecfb = cp.chromfi * ((100.f - cp.balchrom) / 10.f);
noiseccb = cp.chromco * ((100.f - cp.balchrom) / 10.f);
}
if (noisecfr < 0.f) {
noisecfr = 0.0001f;
}
if (noiseccr < 0.f) {
noiseccr = 0.0001f;
}
if (noisecfb < 0.f) {
noisecfb = 0.0001f;
}
if (noiseccb < 0.f) {
noiseccb = 0.0001f;
}
int edge = 2;
variC[0] = SQR(noisecfr);
variC[1] = SQR(noisecfr);
variC[2] = SQR(noisecfr);
variC[3] = SQR(noisecfr);
variC[4] = SQR(noisecfr);
variC[5] = SQR(noiseccr);
variC[6] = SQR(noiseccr);
variCb[0] = SQR(noisecfb);
variCb[1] = SQR(noisecfb);
variCb[2] = SQR(noisecfb);
variCb[3] = SQR(noisecfb);
variCb[4] = SQR(noisecfb);
variCb[5] = SQR(noiseccb);
variCb[6] = SQR(noiseccb);
float k1 = 0.f;
float k2 = 0.f;
float k3 = 0.f;
if (cp.chromfi) {
k1 = 0.f;
k2 = 0.f;
k3 = 0.f;
} else if (cp.chromfi < 0.3f) {
k1 = 0.1f;
k2 = 0.0f;
k3 = 0.f;
} else if (cp.chromfi < 0.5f) {
k1 = 0.2f;
k2 = 0.1f;
k3 = 0.f;
} else if (cp.chromfi < 0.8f) {
k1 = 0.3f;
k2 = 0.25f;
k3 = 0.f;
} else if (cp.chromfi < 1.f) {
k1 = 0.4f;
k2 = 0.25f;
k3 = 0.1f;
} else if (cp.chromfi < 2.f) {
k1 = 0.5f;
k2 = 0.3f;
k3 = 0.15f;
} else if (cp.chromfi < 3.f) {
k1 = 0.6f;
k2 = 0.45f;
k3 = 0.3f;
} else if (cp.chromfi < 4.f) {
k1 = 0.7f;
k2 = 0.5f;
k3 = 0.4f;
} else if (cp.chromfi < 5.f) {
k1 = 0.8f;
k2 = 0.6f;
k3 = 0.5f;
} else if (cp.chromfi < 10.f) {
k1 = 0.85f;
k2 = 0.7f;
k3 = 0.6f;
} else if (cp.chromfi < 20.f) {
k1 = 0.9f;
k2 = 0.8f;
k3 = 0.7f;
} else if (cp.chromfi < 50.f) {
k1 = 1.f;
k2 = 1.f;
k3 = 0.9f;
} else {
k1 = 1.f;
k2 = 1.f;
k3 = 1.f;
}
float minic = 0.0001f;
variC[0] = max(minic, variC[0]);
variC[1] = max(minic, k1 * variC[1]);
variC[2] = max(minic, k2 * variC[2]);
variC[3] = max(minic, k3 * variC[3]);
variCb[0] = max(minic, variCb[0]);
variCb[1] = max(minic, k1 * variCb[1]);
variCb[2] = max(minic, k2 * variCb[2]);
variCb[3] = max(minic, k3 * variCb[3]);
float k4 = 0.f;
float k5 = 0.f;
float k6 = 0.f;
if (cp.chromco == 0.01f) {
k4 = 0.f;
k5 = 0.0f;
} else if (cp.chromco < 0.2f) {
k4 = 0.1f;
k5 = 0.0f;
} else if (cp.chromco < 0.5f) {
k4 = 0.15f;
k5 = 0.0f;
} else if (cp.chromco < 1.f) {
k4 = 0.15f;
k5 = 0.1f;
} else if (cp.chromco < 3.f) {
k4 = 0.3f;
k5 = 0.15f;
} else if (cp.chromco < 4.f) {
k4 = 0.6f;
k5 = 0.4f;
} else if (cp.chromco < 6.f) {
k4 = 0.8f;
k5 = 0.6f;
} else {
k4 = 1.f;
k5 = 1.f;
}
variC[4] = max(0.0001f, k4 * variC[4]);
variC[5] = max(0.0001f, k5 * variC[5]);
variCb[4] = max(0.0001f, k4 * variCb[4]);
variCb[5] = max(0.0001f, k5 * variCb[5]);
if (cp.chromco < 4.f) {
k6 = 0.f;
} else if (cp.chromco < 5.f) {
k6 = 0.4f;
} else if (cp.chromco < 6.f) {
k6 = 0.7f;
} else {
k6 = 1.f;
}
variC[6] = max(0.0001f, k6 * variC[6]);
variCb[6] = max(0.0001f, k6 * variCb[6]);
float nvch = 0.6f;//high value
float nvcl = 0.1f;//low value
if (cp.chromco > 100.f) {
nvch = 0.8f;
nvcl = 0.4f;
}
float seuil = 4000.f;//low
float seuil2 = 15000.f;//high
//ac and bc for transition
float ac = (nvch - nvcl) / (seuil - seuil2);
float bc = nvch - seuil * ac;
int GW = labco->W;
int GH = labco->H;
float* noisevarchrom = new float[GH * GW];
//noisevarchrom in function chroma
int GW2 = (GW + 1) / 2;
float noisevarab_r = 100.f; //SQR(lp.noisecc / 10.0);
for (int ir = 0; ir < GH; ir++)
for (int jr = 0; jr < GW; jr++) {
float cN = sqrt(SQR(labco->a[ir][jr]) + SQR(labco->b[ir][jr]));
if (cN < seuil) {
noisevarchrom[(ir >> 1)*GW2 + (jr >> 1)] = nvch;
} else if (cN < seuil2) {
noisevarchrom[(ir >> 1)*GW2 + (jr >> 1)] = ac * cN + bc;
} else {
noisevarchrom[(ir >> 1)*GW2 + (jr >> 1)] = nvcl;
}
}
*/
//Flat curve for H=f(H) in residual image //Flat curve for H=f(H) in residual image
FlatCurve* hhCurve = new FlatCurve(params->wavelet.hhcurve); //curve H=f(H) FlatCurve* hhCurve = new FlatCurve(params->wavelet.hhcurve); //curve H=f(H)
bool hhutili = false; bool hhutili = false;
@ -971,7 +1185,7 @@ void ImProcFunctions::ip_wavelet(LabImage * lab, LabImage * dst, int kall, const
if (!adecomp->memoryAllocationFailed && !bdecomp->memoryAllocationFailed) { if (!adecomp->memoryAllocationFailed && !bdecomp->memoryAllocationFailed) {
Evaluate2(*adecomp, meanab, meanNab, sigmaab, sigmaNab, MaxPab, MaxNab); Evaluate2(*adecomp, meanab, meanNab, sigmaab, sigmaNab, MaxPab, MaxNab);
WaveletcontAllAB(labco, varhue, varchro, *adecomp,wavblcurve, waOpacityCurveW, cp, true, skip, meanab, sigmaab); WaveletcontAllAB(labco, varhue, varchro, *adecomp, wavblcurve, waOpacityCurveW, cp, true, skip, meanab, sigmaab);
Evaluate2(*bdecomp, meanab, meanNab, sigmaab, sigmaNab, MaxPab, MaxNab); Evaluate2(*bdecomp, meanab, meanNab, sigmaab, sigmaNab, MaxPab, MaxNab);
WaveletcontAllAB(labco, varhue, varchro, *bdecomp, wavblcurve, waOpacityCurveW, cp, false, skip, meanab, sigmaab); WaveletcontAllAB(labco, varhue, varchro, *bdecomp, wavblcurve, waOpacityCurveW, cp, false, skip, meanab, sigmaab);
WaveletAandBAllAB(*adecomp, *bdecomp, cp, hhCurve, hhutili); WaveletAandBAllAB(*adecomp, *bdecomp, cp, hhCurve, hhutili);
@ -983,6 +1197,8 @@ void ImProcFunctions::ip_wavelet(LabImage * lab, LabImage * dst, int kall, const
} }
} }
// delete[] noisevarchrom;
if (hhCurve) { if (hhCurve) {
delete hhCurve; delete hhCurve;
} }
@ -1350,51 +1566,54 @@ void ImProcFunctions::Evaluate2(const wavelet_decomposition &WaveletCoeffs_L,
void ImProcFunctions::calceffect(int level, float *mean, float *sigma, float *mea, float effect, float offs) void ImProcFunctions::calceffect(int level, float *mean, float *sigma, float *mea, float effect, float offs)
{ {
float rap = 0.f; float rap = 0.f;
float sig = 1.f; float sig = 1.f;
if(effect < 1.f) {
sig = effect;
}
if(effect <= 1.f) { if (effect < 1.f) {
rap = offs * mean[level] - sig * sigma[level]; sig = effect;
} }
if (rap > 0.f) { if (effect <= 1.f) {
mea[0] = rap; rap = offs * mean[level] - sig * sigma[level];
} else { }
mea[0] = mean[level] / 6.f;
}
rap = 0.f; if (rap > 0.f) {
if(effect <= 1.f) { mea[0] = rap;
rap = offs * mean[level] - 0.5f * sig * sigma[level]; } else {
} mea[0] = mean[level] / 6.f;
}
if (rap > 0.f) { rap = 0.f;
mea[1] = rap;
} else {
mea[1] = mean[level] / 4.f;
}
rap = 0.f; if (effect <= 1.f) {
if(effect <= 1.f) { rap = offs * mean[level] - 0.5f * sig * sigma[level];
rap = offs * mean[level] - 0.2f * sig * sigma[level]; }
}
if (rap > 0.f) { if (rap > 0.f) {
mea[2] = rap; mea[1] = rap;
} else { } else {
mea[2] = mean[level] / 2.f; mea[1] = mean[level] / 4.f;
} }
mea[3] = offs * mean[level]; // 50% data rap = 0.f;
mea[4] = offs * mean[level] + effect * sigma[level] / 2.f;
mea[5] = offs * mean[level] + effect * sigma[level]; //66% if (effect <= 1.f) {
mea[6] = offs * mean[level] + effect * 1.2f * sigma[level]; rap = offs * mean[level] - 0.2f * sig * sigma[level];
mea[7] = offs * mean[level] + effect * 1.5f * sigma[level]; // }
mea[8] = offs * mean[level] + effect * 2.f * sigma[level]; //95%
mea[9] = offs * mean[level] + effect * 2.5f * sigma[level]; //99% if (rap > 0.f) {
mea[2] = rap;
} else {
mea[2] = mean[level] / 2.f;
}
mea[3] = offs * mean[level]; // 50% data
mea[4] = offs * mean[level] + effect * sigma[level] / 2.f;
mea[5] = offs * mean[level] + effect * sigma[level]; //66%
mea[6] = offs * mean[level] + effect * 1.2f * sigma[level];
mea[7] = offs * mean[level] + effect * 1.5f * sigma[level]; //
mea[8] = offs * mean[level] + effect * 2.f * sigma[level]; //95%
mea[9] = offs * mean[level] + effect * 2.5f * sigma[level]; //99%
} }
void ImProcFunctions::Eval2(float ** WavCoeffs_L, int level, void ImProcFunctions::Eval2(float ** WavCoeffs_L, int level,
@ -1725,7 +1944,7 @@ void ImProcFunctions::WaveletcontAllL(LabImage * labco, float ** varhue, float *
#pragma omp parallel num_threads(wavNestedLevels) if(wavNestedLevels>1) #pragma omp parallel num_threads(wavNestedLevels) if(wavNestedLevels>1)
#endif #endif
{ {
if(contrast != 0.f && cp.resena && max0 > 0.f) { // contrast = 0.f means that all will be multiplied by 1.f, so we can skip this step if (contrast != 0.f && cp.resena && max0 > 0.f) { // contrast = 0.f means that all will be multiplied by 1.f, so we can skip this step
{ {
#ifdef _OPENMP #ifdef _OPENMP
@ -1784,54 +2003,54 @@ void ImProcFunctions::WaveletcontAllL(LabImage * labco, float ** varhue, float *
} }
#ifdef _OPENMP #ifdef _OPENMP
#pragma omp barrier #pragma omp barrier
#endif #endif
if((cp.conres != 0.f || cp.conresH != 0.f) && cp.resena && cp.oldsh) { // cp.conres = 0.f and cp.comresH = 0.f means that all will be multiplied by 1.f, so we can skip this step if ((cp.conres != 0.f || cp.conresH != 0.f) && cp.resena && cp.oldsh) { // cp.conres = 0.f and cp.comresH = 0.f means that all will be multiplied by 1.f, so we can skip this step
#ifdef _OPENMP #ifdef _OPENMP
#pragma omp for nowait #pragma omp for nowait
#endif #endif
for (int i = 0; i < W_L * H_L; i++) { for (int i = 0; i < W_L * H_L; i++) {
float LL = WavCoeffs_L0[i]; float LL = WavCoeffs_L0[i];
float LL100 = LL / 327.68f; float LL100 = LL / 327.68f;
float tran = 5.f;//transition float tran = 5.f;//transition
//shadow //shadow
float alp = 3.f; //increase contrast sahdow in lowlights between 1 and ?? float alp = 3.f; //increase contrast sahdow in lowlights between 1 and ??
if(cp.th > (100.f - tran)) { if (cp.th > (100.f - tran)) {
tran = 100.f - cp.th; tran = 100.f - cp.th;
} }
if(LL100 < cp.th) { if (LL100 < cp.th) {
float aalp = (1.f - alp) / cp.th; //no changes for LL100 = cp.th float aalp = (1.f - alp) / cp.th; //no changes for LL100 = cp.th
float kk = aalp * LL100 + alp; float kk = aalp * LL100 + alp;
WavCoeffs_L0[i] *= (1.f + kk * cp.conres / 200.f); WavCoeffs_L0[i] *= (1.f + kk * cp.conres / 200.f);
} else if(LL100 < cp.th + tran) { } else if (LL100 < cp.th + tran) {
float ath = -cp.conres / tran; float ath = -cp.conres / tran;
float bth = cp.conres - ath * cp.th; float bth = cp.conres - ath * cp.th;
WavCoeffs_L0[i] *= (1.f + (LL100 * ath + bth) / 200.f); WavCoeffs_L0[i] *= (1.f + (LL100 * ath + bth) / 200.f);
} }
//highlight //highlight
tran = 5.f; tran = 5.f;
if(cp.thH < (tran)) { if (cp.thH < (tran)) {
tran = cp.thH; tran = cp.thH;
} }
if(LL100 > cp.thH) { if (LL100 > cp.thH) {
WavCoeffs_L0[i] *= (1.f + cp.conresH / 200.f); WavCoeffs_L0[i] *= (1.f + cp.conresH / 200.f);
} else if(LL100 > (cp.thH - tran)) { } else if (LL100 > (cp.thH - tran)) {
float athH = cp.conresH / tran; float athH = cp.conresH / tran;
float bthH = cp.conresH - athH * cp.thH; float bthH = cp.conresH - athH * cp.thH;
WavCoeffs_L0[i] *= (1.f + (LL100 * athH + bthH) / 200.f); WavCoeffs_L0[i] *= (1.f + (LL100 * athH + bthH) / 200.f);
}
} }
} }
}
//Blur luma //Blur luma
if(cp.blurres != 0.f && cp.resena) { if (cp.blurres != 0.f && cp.resena) {
float rad = 0.7f * cp.blurres / skip; float rad = 0.7f * cp.blurres / skip;
float * bef = new float[W_L * H_L]; float * bef = new float[W_L * H_L];
float * aft = new float[W_L * H_L]; float * aft = new float[W_L * H_L];
@ -1839,6 +2058,7 @@ void ImProcFunctions::WaveletcontAllL(LabImage * labco, float ** varhue, float *
for (int i = 0; i < H_L * W_L; i++) { for (int i = 0; i < H_L * W_L; i++) {
bef[i] = WavCoeffs_L0[i]; bef[i] = WavCoeffs_L0[i];
} }
boxblur(bef, aft, rad, W_L, H_L, false); boxblur(bef, aft, rad, W_L, H_L, false);
for (int i = 0; i < H_L * W_L; i++) { for (int i = 0; i < H_L * W_L; i++) {
@ -1848,7 +2068,11 @@ void ImProcFunctions::WaveletcontAllL(LabImage * labco, float ** varhue, float *
delete[] bef; delete[] bef;
delete[] aft; delete[] aft;
} }
// //
int n0, n1, n2, n3, n4, n5, n6, n7, n8, n9, n10, n32;
n0 = n1 = n2 = n3 = n4 = n5 = n6 = n7 = n8 = n9 = n10 = n32 = 0;
#ifdef _OPENMP #ifdef _OPENMP
#pragma omp parallel num_threads(wavNestedLevels) if(wavNestedLevels>1) #pragma omp parallel num_threads(wavNestedLevels) if(wavNestedLevels>1)
#endif #endif
@ -1992,6 +2216,7 @@ void ImProcFunctions::WaveletcontAllL(LabImage * labco, float ** varhue, float *
// end // end
} }
bool wavcurvecomp = false;//not enable if 0.75 bool wavcurvecomp = false;//not enable if 0.75
if (wavblcurve) { if (wavblcurve) {
@ -2003,7 +2228,8 @@ void ImProcFunctions::WaveletcontAllL(LabImage * labco, float ** varhue, float *
} }
#ifdef _OPENMP #ifdef _OPENMP
#pragma omp for schedule(dynamic) collapse(2) // #pragma omp for schedule(dynamic) collapse(2)
#pragma omp for reduction(+:n0, n1, n2, n3, n4, n5, n6, n7, n8, n9, n10, n32) schedule(dynamic) collapse(2)
#endif #endif
for (int dir = 1; dir < 4; dir++) { for (int dir = 1; dir < 4; dir++) {
@ -2017,7 +2243,8 @@ void ImProcFunctions::WaveletcontAllL(LabImage * labco, float ** varhue, float *
ContAllL(koeLi, maxkoeLi, true, maxlvl, labco, varhue, varchrom, WavCoeffs_L, WavCoeffs_L0, lvl, dir, cp, Wlvl_L, Hlvl_L, skip, mean, sigma, MaxP, MaxN, wavCLVCcurve, waOpacityCurveW, ChCurve, Chutili); ContAllL(koeLi, maxkoeLi, true, maxlvl, labco, varhue, varchrom, WavCoeffs_L, WavCoeffs_L0, lvl, dir, cp, Wlvl_L, Hlvl_L, skip, mean, sigma, MaxP, MaxN, wavCLVCcurve, waOpacityCurveW, ChCurve, Chutili);
//blur level //blur level
float klev = 1.f; float klev = 1.f;
if(wavblcurve && wavcurvecomp && cp.blena) {
if (wavblcurve && wavcurvecomp && cp.blena) {
float mea[10]; float mea[10];
float effect = cp.bluwav; float effect = cp.bluwav;
float beta = 0.f; float beta = 0.f;
@ -2032,37 +2259,58 @@ void ImProcFunctions::WaveletcontAllL(LabImage * labco, float ** varhue, float *
bef[co] = WavCoeffs_L[dir][co]; bef[co] = WavCoeffs_L[dir][co];
float WavCL = std::fabs(WavCoeffs_L[dir][co]); float WavCL = std::fabs(WavCoeffs_L[dir][co]);
if (WavCL < mea[0]) { if (WavCL < mea[0]) {
beta = 0.05f; beta = 0.05f;
} else if (WavCL < mea[1]) { n0++;
beta = 0.2f;
} else if (WavCL < mea[2]) { if (WavCL < 32.7) {
beta = 0.7f; n32++;
} else if (WavCL < mea[3]) {
beta = 1.f; //standard
} else if (WavCL < mea[4]) {
beta = 1.f;
} else if (WavCL < mea[5]) {
beta = 0.8f; //+sigma
} else if (WavCL < mea[6]) {
beta = 0.6f;
} else if (WavCL < mea[7]) {
beta = 0.4f;
} else if (WavCL < mea[8]) {
beta = 0.2f; // + 2 sigma
} else if (WavCL < mea[9]) {
beta = 0.1f;
} else {
beta = 0.0f;
} }
} else if (WavCL < mea[1]) {
beta = 0.2f;
n1++;
} else if (WavCL < mea[2]) {
beta = 0.7f;
n2++;
} else if (WavCL < mea[3]) {
beta = 1.f; //standard
n3++;
} else if (WavCL < mea[4]) {
beta = 1.f;
n4++;
} else if (WavCL < mea[5]) {
beta = 0.8f; //+sigma
n5++;
} else if (WavCL < mea[6]) {
beta = 0.6f;
n6++;
} else if (WavCL < mea[7]) {
beta = 0.4f;
n7++;
} else if (WavCL < mea[8]) {
beta = 0.2f; // + 2 sigma
n8++;
} else if (WavCL < mea[9]) {
beta = 0.1f;
n9++;
} else {
beta = 0.01f;
n10++;
}
} }
if (settings->verbose) {
printf("lvl=%i n0=%i n32=%i n1=%i n2=%i n3=%i n4=%i n5=%i n6=%i n7=%i n8=%i n9=%i n10=%i\n", lvl, n0, n0 - n32, n1, n2, n3, n4, n5, n6, n7, n8, n9, n10);
}
klev = (wavblcurve[lvl * 55.5f]); klev = (wavblcurve[lvl * 55.5f]);
float lvr = lvl; float lvr = lvl;
if(lvr == 0) {
if (lvr == 0) {
lvr = 1; lvr = 1;
} }
klev *= beta * lvr * 100.f / skip; klev *= beta * lvr * 100.f / skip;
boxblur(bef, aft, klev, Wlvl_L, Hlvl_L, false); boxblur(bef, aft, klev, Wlvl_L, Hlvl_L, false);
@ -2274,34 +2522,35 @@ void ImProcFunctions::WaveletcontAllAB(LabImage * labco, float ** varhue, float
} }
//Blur chroma //Blur chroma
if(cp.blurcres != 0.f && cp.resena) { if (cp.blurcres != 0.f && cp.resena) {
float rad = 0.7f * cp.blurcres / skip; float rad = 0.7f * cp.blurcres / skip;
float * bef = new float[W_L * H_L]; float * bef = new float[W_L * H_L];
float * aft = new float[W_L * H_L]; float * aft = new float[W_L * H_L];
for (int i = 0; i < H_L * W_L; i++) { for (int i = 0; i < H_L * W_L; i++) {
bef[i] = WavCoeffs_ab0[i]; bef[i] = WavCoeffs_ab0[i];
} }
boxblur(bef, aft, rad, W_L, H_L, false);
for (int i = 0; i < H_L * W_L; i++) { boxblur(bef, aft, rad, W_L, H_L, false);
WavCoeffs_ab0[i] = aft[i];
} for (int i = 0; i < H_L * W_L; i++) {
WavCoeffs_ab0[i] = aft[i];
}
delete[] bef; delete[] bef;
delete[] aft; delete[] aft;
} }
bool wavcurvecomp = false;//not enable if 0.75 bool wavcurvecomp = false;//not enable if 0.75
if (wavblcurve) { if (wavblcurve) {
for (int i = 0; i < 500; i++) { for (int i = 0; i < 500; i++) {
if (wavblcurve[i] != 0.) { if (wavblcurve[i] != 0.) {
wavcurvecomp = true; wavcurvecomp = true;
}
} }
} }
}
#ifdef _OPENMP #ifdef _OPENMP
#pragma omp for schedule(dynamic) collapse(2) #pragma omp for schedule(dynamic) collapse(2)
@ -2316,7 +2565,7 @@ void ImProcFunctions::WaveletcontAllAB(LabImage * labco, float ** varhue, float
float ** WavCoeffs_ab = WaveletCoeffs_ab.level_coeffs(lvl); float ** WavCoeffs_ab = WaveletCoeffs_ab.level_coeffs(lvl);
ContAllAB(labco, maxlvl, varhue, varchrom, WavCoeffs_ab, WavCoeffs_ab0, lvl, dir, waOpacityCurveW, cp, Wlvl_ab, Hlvl_ab, useChannelA); ContAllAB(labco, maxlvl, varhue, varchrom, WavCoeffs_ab, WavCoeffs_ab0, lvl, dir, waOpacityCurveW, cp, Wlvl_ab, Hlvl_ab, useChannelA);
if(wavblcurve && wavcurvecomp && cp.blena && cp.chrwav > 0.f) { if (wavblcurve && wavcurvecomp && cp.blena && cp.chrwav > 0.f) {
float mea[10]; float mea[10];
float effect = cp.bluwav; float effect = cp.bluwav;
float beta = 0.f; float beta = 0.f;
@ -2327,39 +2576,42 @@ void ImProcFunctions::WaveletcontAllAB(LabImage * labco, float ** varhue, float
float * bef = new float[Wlvl_ab * Hlvl_ab]; float * bef = new float[Wlvl_ab * Hlvl_ab];
float * aft = new float[Wlvl_ab * Hlvl_ab]; float * aft = new float[Wlvl_ab * Hlvl_ab];
float klev; float klev;
for (int co = 0; co < Hlvl_ab * Wlvl_ab; co++) { for (int co = 0; co < Hlvl_ab * Wlvl_ab; co++) {
bef[co] = WavCoeffs_ab[dir][co]; bef[co] = WavCoeffs_ab[dir][co];
float WavCab = std::fabs(WavCoeffs_ab[dir][co]); float WavCab = std::fabs(WavCoeffs_ab[dir][co]);
if (WavCab < mea[0]) { if (WavCab < mea[0]) {
beta = 0.05f; beta = 0.05f;
} else if (WavCab < mea[1]) { } else if (WavCab < mea[1]) {
beta = 0.2f; beta = 0.2f;
} else if (WavCab < mea[2]) { } else if (WavCab < mea[2]) {
beta = 0.7f; beta = 0.7f;
} else if (WavCab < mea[3]) { } else if (WavCab < mea[3]) {
beta = 1.f; //standard beta = 1.f; //standard
} else if (WavCab < mea[4]) { } else if (WavCab < mea[4]) {
beta = 1.f; beta = 1.f;
} else if (WavCab < mea[5]) { } else if (WavCab < mea[5]) {
beta = 0.8f; //+sigma beta = 0.8f; //+sigma
} else if (WavCab < mea[6]) { } else if (WavCab < mea[6]) {
beta = 0.6f; beta = 0.6f;
} else if (WavCab < mea[7]) { } else if (WavCab < mea[7]) {
beta = 0.4f; beta = 0.4f;
} else if (WavCab < mea[8]) { } else if (WavCab < mea[8]) {
beta = 0.2f; // + 2 sigma beta = 0.2f; // + 2 sigma
} else if (WavCab < mea[9]) { } else if (WavCab < mea[9]) {
beta = 0.1f; beta = 0.1f;
} else { } else {
beta = 0.0f; beta = 0.0f;
} }
} }
klev = (wavblcurve[lvl * 55.5f]);
klev = (wavblcurve[lvl * 55.5f]);
float lvr = lvl; float lvr = lvl;
if(lvr == 0) {
if (lvr == 0) {
lvr = 1; lvr = 1;
} }
@ -2725,11 +2977,13 @@ void ImProcFunctions::ContAllL(float *koeLi[12], float *maxkoeLi, bool lipschitz
float mea[10]; float mea[10];
float beta = 1.f; float beta = 1.f;
if(cp.eff < 2.5f) {
if (cp.eff < 2.5f) {
float effect = cp.eff; float effect = cp.eff;
float offs = 1.f; float offs = 1.f;
calceffect(level, mean, sigma, mea, effect, offs); calceffect(level, mean, sigma, mea, effect, offs);
for (int co = 0; co < H_L * W_L; co++) { for (int co = 0; co < H_L * W_L; co++) {
float WavCL = std::fabs(WavCoeffs_L[dir][co]); float WavCL = std::fabs(WavCoeffs_L[dir][co]);
@ -2852,6 +3106,7 @@ void ImProcFunctions::ContAllL(float *koeLi[12], float *maxkoeLi, bool lipschitz
float atten01234 = 0.80f; float atten01234 = 0.80f;
value *= (atten01234 * scaleskip[1]); //for zoom < 100% reduce strength...I choose level 1...but!! value *= (atten01234 * scaleskip[1]); //for zoom < 100% reduce strength...I choose level 1...but!!
} }
value *= beta; value *= beta;
float edge = 1.f; float edge = 1.f;
float lim0 = 20.f; //arbitrary limit for low radius and level between 2 or 3 to 30 maxi float lim0 = 20.f; //arbitrary limit for low radius and level between 2 or 3 to 30 maxi
@ -2862,8 +3117,8 @@ void ImProcFunctions::ContAllL(float *koeLi[12], float *maxkoeLi, bool lipschitz
if (cp.reinforce != 2) { if (cp.reinforce != 2) {
const float brepart = const float brepart =
cp.reinforce == 1 cp.reinforce == 1
? 3.f ? 3.f
: 0.5f; : 0.5f;
const float arepart = -(brepart - 1.f) / (lim0 / 60.f); const float arepart = -(brepart - 1.f) / (lim0 / 60.f);
if (rad < lim0 / 60.f) { if (rad < lim0 / 60.f) {

View File

@ -2248,6 +2248,9 @@ WaveletParams::WaveletParams() :
bluemed(0), bluemed(0),
greenhigh(0), greenhigh(0),
bluehigh(0), bluehigh(0),
balchrom(0.),
chromfi(0.),
chromco(0.),
mergeL(40.), mergeL(40.),
mergeC(20.), mergeC(20.),
softrad(0.), softrad(0.),
@ -2320,7 +2323,7 @@ WaveletParams::WaveletParams() :
radius(40), radius(40),
skinprotect(0.0), skinprotect(0.0),
chrwav(0.), chrwav(0.),
bluwav(50.0), bluwav(1.0),
hueskin(-5, 25, 170, 120, false), hueskin(-5, 25, 170, 120, false),
hueskin2(-260, -250, -130, -140, false), hueskin2(-260, -250, -130, -140, false),
hllev(50, 75, 100, 98, false), hllev(50, 75, 100, 98, false),
@ -2358,6 +2361,9 @@ bool WaveletParams::operator ==(const WaveletParams& other) const
&& bluemed == other.bluemed && bluemed == other.bluemed
&& greenhigh == other.greenhigh && greenhigh == other.greenhigh
&& bluehigh == other.bluehigh && bluehigh == other.bluehigh
&& balchrom == other.balchrom
&& chromfi == other.chromfi
&& chromco == other.chromco
&& mergeL == other.mergeL && mergeL == other.mergeL
&& mergeC == other.mergeC && mergeC == other.mergeC
&& softrad == other.softrad && softrad == other.softrad
@ -3520,6 +3526,9 @@ int ProcParams::save(const Glib::ustring& fname, const Glib::ustring& fname2, bo
saveToKeyfile(!pedited || pedited->wavelet.bluehigh, "Wavelet", "CBbluehigh", wavelet.bluehigh, keyFile); saveToKeyfile(!pedited || pedited->wavelet.bluehigh, "Wavelet", "CBbluehigh", wavelet.bluehigh, keyFile);
saveToKeyfile(!pedited || pedited->wavelet.bluemed, "Wavelet", "CBbluemed", wavelet.bluemed, keyFile); saveToKeyfile(!pedited || pedited->wavelet.bluemed, "Wavelet", "CBbluemed", wavelet.bluemed, keyFile);
saveToKeyfile(!pedited || pedited->wavelet.bluelow, "Wavelet", "CBbluelow", wavelet.bluelow, keyFile); saveToKeyfile(!pedited || pedited->wavelet.bluelow, "Wavelet", "CBbluelow", wavelet.bluelow, keyFile);
saveToKeyfile(!pedited || pedited->wavelet.balchrom, "Wavelet", "Balchrom", wavelet.balchrom, keyFile);
saveToKeyfile(!pedited || pedited->wavelet.chromfi, "Wavelet", "Chromfine", wavelet.chromfi, keyFile);
saveToKeyfile(!pedited || pedited->wavelet.chromco, "Wavelet", "Chromcoarse", wavelet.chromco, keyFile);
saveToKeyfile(!pedited || pedited->wavelet.mergeL, "Wavelet", "MergeL", wavelet.mergeL, keyFile); saveToKeyfile(!pedited || pedited->wavelet.mergeL, "Wavelet", "MergeL", wavelet.mergeL, keyFile);
saveToKeyfile(!pedited || pedited->wavelet.mergeC, "Wavelet", "MergeC", wavelet.mergeC, keyFile); saveToKeyfile(!pedited || pedited->wavelet.mergeC, "Wavelet", "MergeC", wavelet.mergeC, keyFile);
saveToKeyfile(!pedited || pedited->wavelet.softrad, "Wavelet", "Softrad", wavelet.softrad, keyFile); saveToKeyfile(!pedited || pedited->wavelet.softrad, "Wavelet", "Softrad", wavelet.softrad, keyFile);
@ -4690,6 +4699,9 @@ int ProcParams::load(const Glib::ustring& fname, ParamsEdited* pedited)
assignFromKeyfile(keyFile, "Wavelet", "CBbluehigh", pedited, wavelet.bluehigh, pedited->wavelet.bluehigh); assignFromKeyfile(keyFile, "Wavelet", "CBbluehigh", pedited, wavelet.bluehigh, pedited->wavelet.bluehigh);
assignFromKeyfile(keyFile, "Wavelet", "CBbluemed", pedited, wavelet.bluemed, pedited->wavelet.bluemed); assignFromKeyfile(keyFile, "Wavelet", "CBbluemed", pedited, wavelet.bluemed, pedited->wavelet.bluemed);
assignFromKeyfile(keyFile, "Wavelet", "CBbluelow", pedited, wavelet.bluelow, pedited->wavelet.bluelow); assignFromKeyfile(keyFile, "Wavelet", "CBbluelow", pedited, wavelet.bluelow, pedited->wavelet.bluelow);
assignFromKeyfile(keyFile, "Wavelet", "Balchrom", pedited, wavelet.balchrom, pedited->wavelet.balchrom);
assignFromKeyfile(keyFile, "Wavelet", "Chromfine", pedited, wavelet.chromfi, pedited->wavelet.chromfi);
assignFromKeyfile(keyFile, "Wavelet", "Chromcoarse", pedited, wavelet.chromco, pedited->wavelet.chromco);
assignFromKeyfile(keyFile, "Wavelet", "MergeL", pedited, wavelet.mergeL, pedited->wavelet.mergeL); assignFromKeyfile(keyFile, "Wavelet", "MergeL", pedited, wavelet.mergeL, pedited->wavelet.mergeL);
assignFromKeyfile(keyFile, "Wavelet", "MergeC", pedited, wavelet.mergeC, pedited->wavelet.mergeC); assignFromKeyfile(keyFile, "Wavelet", "MergeC", pedited, wavelet.mergeC, pedited->wavelet.mergeC);
assignFromKeyfile(keyFile, "Wavelet", "Softrad", pedited, wavelet.softrad, pedited->wavelet.softrad); assignFromKeyfile(keyFile, "Wavelet", "Softrad", pedited, wavelet.softrad, pedited->wavelet.softrad);

View File

@ -1205,6 +1205,9 @@ struct WaveletParams {
int bluemed; int bluemed;
int greenhigh; int greenhigh;
int bluehigh; int bluehigh;
double balchrom;
double chromfi;
double chromco;
double mergeL; double mergeL;
double mergeC; double mergeC;
double softrad; double softrad;

View File

@ -486,6 +486,9 @@ void ParamsEdited::set(bool v)
wavelet.bluemed = v; wavelet.bluemed = v;
wavelet.bluelow = v; wavelet.bluelow = v;
wavelet.lipst = v; wavelet.lipst = v;
wavelet.balchrom = v;
wavelet.chromfi = v;
wavelet.chromco = v;
wavelet.mergeL = v; wavelet.mergeL = v;
wavelet.mergeC = v; wavelet.mergeC = v;
wavelet.softrad = v; wavelet.softrad = v;
@ -1093,6 +1096,9 @@ void ParamsEdited::initFrom(const std::vector<rtengine::procparams::ProcParams>&
wavelet.bluelow = wavelet.bluelow && p.wavelet.bluelow == other.wavelet.bluelow; wavelet.bluelow = wavelet.bluelow && p.wavelet.bluelow == other.wavelet.bluelow;
wavelet.lipst = wavelet.lipst && p.wavelet.lipst == other.wavelet.lipst; wavelet.lipst = wavelet.lipst && p.wavelet.lipst == other.wavelet.lipst;
wavelet.bluehigh = wavelet.bluehigh && p.wavelet.bluehigh == other.wavelet.bluehigh; wavelet.bluehigh = wavelet.bluehigh && p.wavelet.bluehigh == other.wavelet.bluehigh;
wavelet.balchrom = wavelet.balchrom && p.wavelet.balchrom == other.wavelet.balchrom;
wavelet.chromfi = wavelet.chromfi && p.wavelet.chromfi == other.wavelet.chromfi;
wavelet.chromco = wavelet.chromco && p.wavelet.chromco == other.wavelet.chromco;
wavelet.mergeL = wavelet.mergeL && p.wavelet.mergeL == other.wavelet.mergeL; wavelet.mergeL = wavelet.mergeL && p.wavelet.mergeL == other.wavelet.mergeL;
wavelet.mergeC = wavelet.mergeC && p.wavelet.mergeC == other.wavelet.mergeC; wavelet.mergeC = wavelet.mergeC && p.wavelet.mergeC == other.wavelet.mergeC;
wavelet.softrad = wavelet.softrad && p.wavelet.softrad == other.wavelet.softrad; wavelet.softrad = wavelet.softrad && p.wavelet.softrad == other.wavelet.softrad;
@ -2929,6 +2935,18 @@ void ParamsEdited::combine(rtengine::procparams::ProcParams& toEdit, const rteng
toEdit.wavelet.bluelow = mods.wavelet.bluelow; toEdit.wavelet.bluelow = mods.wavelet.bluelow;
} }
if (wavelet.balchrom) {
toEdit.wavelet.balchrom = mods.wavelet.balchrom;
}
if (wavelet.chromfi) {
toEdit.wavelet.chromfi = mods.wavelet.chromfi;
}
if (wavelet.chromco) {
toEdit.wavelet.chromco = mods.wavelet.chromco;
}
if (wavelet.mergeL) { if (wavelet.mergeL) {
toEdit.wavelet.mergeL = mods.wavelet.mergeL; toEdit.wavelet.mergeL = mods.wavelet.mergeL;
} }

View File

@ -586,6 +586,9 @@ struct WaveletParamsEdited {
bool bluemed; bool bluemed;
bool greenhigh; bool greenhigh;
bool bluehigh; bool bluehigh;
bool balchrom;
bool chromfi;
bool chromco;
bool mergeL; bool mergeL;
bool mergeC; bool mergeC;
bool softrad; bool softrad;

View File

@ -130,6 +130,9 @@ Wavelet::Wavelet() :
edgedetectthr2(Gtk::manage(new Adjuster(M("TP_WAVELET_EDGEDETECTTHR2"), -10, 100, 1, 0))), edgedetectthr2(Gtk::manage(new Adjuster(M("TP_WAVELET_EDGEDETECTTHR2"), -10, 100, 1, 0))),
edgesensi(Gtk::manage(new Adjuster(M("TP_WAVELET_EDGESENSI"), 0, 100, 1, 60))), edgesensi(Gtk::manage(new Adjuster(M("TP_WAVELET_EDGESENSI"), 0, 100, 1, 60))),
edgeampli(Gtk::manage(new Adjuster(M("TP_WAVELET_EDGEAMPLI"), 0, 100, 1, 10))), edgeampli(Gtk::manage(new Adjuster(M("TP_WAVELET_EDGEAMPLI"), 0, 100, 1, 10))),
balchrom(Gtk::manage(new Adjuster(M("TP_WAVELET_BALCHROM"), -100., 100., 1., 0., Gtk::manage(new RTImage("circle-blue-small.png")), Gtk::manage(new RTImage("circle-red-small.png"))))),
chromfi(Gtk::manage(new Adjuster(M("TP_WAVELET_CHROMFI"), 0, 100, 1, 0))),
chromco(Gtk::manage(new Adjuster(M("TP_WAVELET_CHROMCO"), 0, 100, 1, 0))),
mergeL(Gtk::manage(new Adjuster(M("TP_WAVELET_MERGEL"), -50, 100, 1, 40))), mergeL(Gtk::manage(new Adjuster(M("TP_WAVELET_MERGEL"), -50, 100, 1, 40))),
mergeC(Gtk::manage(new Adjuster(M("TP_WAVELET_MERGEC"), -50, 100, 1, 20))), mergeC(Gtk::manage(new Adjuster(M("TP_WAVELET_MERGEC"), -50, 100, 1, 20))),
softrad(Gtk::manage(new Adjuster(M("TP_WAVELET_SOFTRAD"), 0.0, 100., 0.5, 0.))), softrad(Gtk::manage(new Adjuster(M("TP_WAVELET_SOFTRAD"), 0.0, 100., 0.5, 0.))),
@ -157,6 +160,7 @@ Wavelet::Wavelet() :
contFrame(Gtk::manage(new Gtk::Frame(M("TP_WAVELET_CONTFRAME")))), contFrame(Gtk::manage(new Gtk::Frame(M("TP_WAVELET_CONTFRAME")))),
blurFrame(Gtk::manage(new Gtk::Frame(M("TP_WAVELET_BLURFRAME")))), blurFrame(Gtk::manage(new Gtk::Frame(M("TP_WAVELET_BLURFRAME")))),
chromaFrame(Gtk::manage(new Gtk::Frame(M("TP_WAVELET_CHROMAFRAME")))), chromaFrame(Gtk::manage(new Gtk::Frame(M("TP_WAVELET_CHROMAFRAME")))),
chroFrame(Gtk::manage(new Gtk::Frame(M("TP_WAVELET_CHROFRAME")))),
wavLabels(Gtk::manage(new Gtk::Label("---", Gtk::ALIGN_CENTER))), wavLabels(Gtk::manage(new Gtk::Label("---", Gtk::ALIGN_CENTER))),
labmC(Gtk::manage(new Gtk::Label(M("TP_WAVELET_CTYPE") + ":"))), labmC(Gtk::manage(new Gtk::Label(M("TP_WAVELET_CTYPE") + ":"))),
labmNP(Gtk::manage(new Gtk::Label(M("TP_WAVELET_NPTYPE") + ":"))), labmNP(Gtk::manage(new Gtk::Label(M("TP_WAVELET_NPTYPE") + ":"))),
@ -179,6 +183,9 @@ Wavelet::Wavelet() :
auto m = ProcEventMapper::getInstance(); auto m = ProcEventMapper::getInstance();
EvWavenaclari = m->newEvent(DIRPYREQUALIZER, "HISTORY_MSG_WAVCLARI"); EvWavenaclari = m->newEvent(DIRPYREQUALIZER, "HISTORY_MSG_WAVCLARI");
EvWavushamet = m->newEvent(DIRPYREQUALIZER, "HISTORY_MSG_WAVUSHAMET"); EvWavushamet = m->newEvent(DIRPYREQUALIZER, "HISTORY_MSG_WAVUSHAMET");
EvWavbalchrom = m->newEvent(DIRPYREQUALIZER, "HISTORY_MSG_WAVBALCHROM");
EvWavchromfi = m->newEvent(DIRPYREQUALIZER, "HISTORY_MSG_WAVCHROMFI");
EvWavchromco = m->newEvent(DIRPYREQUALIZER, "HISTORY_MSG_WAVCHROMCO");
EvWavmergeL = m->newEvent(DIRPYREQUALIZER, "HISTORY_MSG_WAVMERGEL"); EvWavmergeL = m->newEvent(DIRPYREQUALIZER, "HISTORY_MSG_WAVMERGEL");
EvWavmergeC = m->newEvent(DIRPYREQUALIZER, "HISTORY_MSG_WAVMERGEC"); EvWavmergeC = m->newEvent(DIRPYREQUALIZER, "HISTORY_MSG_WAVMERGEC");
EvWavsoftrad = m->newEvent(DIRPYREQUALIZER, "HISTORY_MSG_WAVSOFTRAD"); EvWavsoftrad = m->newEvent(DIRPYREQUALIZER, "HISTORY_MSG_WAVSOFTRAD");
@ -523,6 +530,19 @@ Wavelet::Wavelet() :
noiseBox->pack_start(*level2noise, Gtk::PACK_SHRINK, 0); noiseBox->pack_start(*level2noise, Gtk::PACK_SHRINK, 0);
noiseBox->pack_start(*level3noise, Gtk::PACK_SHRINK, 0); noiseBox->pack_start(*level3noise, Gtk::PACK_SHRINK, 0);
balchrom->setAdjusterListener(this);
chromfi->setAdjusterListener(this);
chromco->setAdjusterListener(this);
chroFrame->set_label_align(0.025, 0.5);
ToolParamBlock* const chroBox = Gtk::manage(new ToolParamBlock());
chroBox->pack_start(*balchrom);
chroBox->pack_start(*chromfi);
chroBox->pack_start(*chromco);
chroFrame->add(*chroBox);
// noiseBox->pack_start(*chroFrame);
//Clarity //Clarity
mergeL->setAdjusterListener(this); mergeL->setAdjusterListener(this);
mergeC->setAdjusterListener(this); mergeC->setAdjusterListener(this);
@ -1383,6 +1403,9 @@ void Wavelet::read(const ProcParams* pp, const ParamsEdited* pedited)
softrad->setValue(pp->wavelet.softrad); softrad->setValue(pp->wavelet.softrad);
softradend->setValue(pp->wavelet.softradend); softradend->setValue(pp->wavelet.softradend);
balchrom->setValue(pp->wavelet.balchrom);
chromfi->setValue(pp->wavelet.chromfi);
chromco->setValue(pp->wavelet.chromco);
level0noise->setValue<double>(pp->wavelet.level0noise); level0noise->setValue<double>(pp->wavelet.level0noise);
level1noise->setValue<double>(pp->wavelet.level1noise); level1noise->setValue<double>(pp->wavelet.level1noise);
level2noise->setValue<double>(pp->wavelet.level2noise); level2noise->setValue<double>(pp->wavelet.level2noise);
@ -1528,6 +1551,10 @@ void Wavelet::read(const ProcParams* pp, const ParamsEdited* pedited)
softrad->setEditedState(pedited->wavelet.softrad ? Edited : UnEdited); softrad->setEditedState(pedited->wavelet.softrad ? Edited : UnEdited);
softradend->setEditedState(pedited->wavelet.softradend ? Edited : UnEdited); softradend->setEditedState(pedited->wavelet.softradend ? Edited : UnEdited);
balchrom->setEditedState(pedited->wavelet.balchrom ? Edited : UnEdited);
chromfi->setEditedState(pedited->wavelet.chromfi ? Edited : UnEdited);
chromco->setEditedState(pedited->wavelet.chromco ? Edited : UnEdited);
median->set_inconsistent(!pedited->wavelet.median); median->set_inconsistent(!pedited->wavelet.median);
medianlev->set_inconsistent(!pedited->wavelet.medianlev); medianlev->set_inconsistent(!pedited->wavelet.medianlev);
linkedg->set_inconsistent(!pedited->wavelet.linkedg); linkedg->set_inconsistent(!pedited->wavelet.linkedg);
@ -1746,6 +1773,9 @@ void Wavelet::write(ProcParams* pp, ParamsEdited* pedited)
pp->wavelet.satlev = satlev->getValue<int> (); pp->wavelet.satlev = satlev->getValue<int> ();
pp->wavelet.strength = (int) strength->getValue(); pp->wavelet.strength = (int) strength->getValue();
pp->wavelet.balance = (int) balance->getValue(); pp->wavelet.balance = (int) balance->getValue();
pp->wavelet.balchrom = balchrom->getValue();
pp->wavelet.chromfi = chromfi->getValue();
pp->wavelet.chromco = chromco->getValue();
pp->wavelet.greenlow = greenlow->getValue(); pp->wavelet.greenlow = greenlow->getValue();
pp->wavelet.bluelow = bluelow->getValue(); pp->wavelet.bluelow = bluelow->getValue();
@ -1865,6 +1895,9 @@ void Wavelet::write(ProcParams* pp, ParamsEdited* pedited)
pedited->wavelet.bluemed = bluemed->getEditedState(); pedited->wavelet.bluemed = bluemed->getEditedState();
pedited->wavelet.greenhigh = greenhigh->getEditedState(); pedited->wavelet.greenhigh = greenhigh->getEditedState();
pedited->wavelet.bluehigh = bluehigh->getEditedState(); pedited->wavelet.bluehigh = bluehigh->getEditedState();
pedited->wavelet.balchrom = balchrom->getEditedState();
pedited->wavelet.chromfi = chromfi->getEditedState();
pedited->wavelet.chromco = chromco->getEditedState();
pedited->wavelet.mergeL = mergeL->getEditedState(); pedited->wavelet.mergeL = mergeL->getEditedState();
pedited->wavelet.mergeC = mergeC->getEditedState(); pedited->wavelet.mergeC = mergeC->getEditedState();
pedited->wavelet.softrad = softrad->getEditedState(); pedited->wavelet.softrad = softrad->getEditedState();
@ -2096,6 +2129,9 @@ void Wavelet::setDefaults(const ProcParams* defParams, const ParamsEdited* pedit
level1noise->setDefault<double> (defParams->wavelet.level1noise); level1noise->setDefault<double> (defParams->wavelet.level1noise);
level2noise->setDefault<double> (defParams->wavelet.level2noise); level2noise->setDefault<double> (defParams->wavelet.level2noise);
level3noise->setDefault<double> (defParams->wavelet.level3noise); level3noise->setDefault<double> (defParams->wavelet.level3noise);
balchrom->setDefault(defParams->wavelet.balchrom);
chromfi->setDefault(defParams->wavelet.chromfi);
chromco->setDefault(defParams->wavelet.chromco);
greenlow->setDefault(defParams->wavelet.greenlow); greenlow->setDefault(defParams->wavelet.greenlow);
bluelow->setDefault(defParams->wavelet.bluelow); bluelow->setDefault(defParams->wavelet.bluelow);
@ -2119,6 +2155,9 @@ void Wavelet::setDefaults(const ProcParams* defParams, const ParamsEdited* pedit
mergeC->setDefaultEditedState(pedited->wavelet.mergeC ? Edited : UnEdited); mergeC->setDefaultEditedState(pedited->wavelet.mergeC ? Edited : UnEdited);
softrad->setDefaultEditedState(pedited->wavelet.softrad ? Edited : UnEdited); softrad->setDefaultEditedState(pedited->wavelet.softrad ? Edited : UnEdited);
softradend->setDefaultEditedState(pedited->wavelet.softradend ? Edited : UnEdited); softradend->setDefaultEditedState(pedited->wavelet.softradend ? Edited : UnEdited);
balchrom->setDefaultEditedState(pedited->wavelet.balchrom ? Edited : UnEdited);
chromfi->setDefaultEditedState(pedited->wavelet.chromfi ? Edited : UnEdited);
chromco->setDefaultEditedState(pedited->wavelet.chromco ? Edited : UnEdited);
sigma->setDefault(defParams->wavelet.sigma); sigma->setDefault(defParams->wavelet.sigma);
offset->setDefault(defParams->wavelet.offset); offset->setDefault(defParams->wavelet.offset);
@ -2912,6 +2951,12 @@ void Wavelet::adjusterChanged(Adjuster* a, double newval)
listener->panelChanged(EvWavgreenhigh, greenhigh->getTextValue()); listener->panelChanged(EvWavgreenhigh, greenhigh->getTextValue());
} else if (a == bluehigh) { } else if (a == bluehigh) {
listener->panelChanged(EvWavbluehigh, bluehigh->getTextValue()); listener->panelChanged(EvWavbluehigh, bluehigh->getTextValue());
} else if (a == balchrom) {
listener->panelChanged(EvWavbalchrom, balchrom->getTextValue());
} else if (a == chromfi) {
listener->panelChanged(EvWavchromfi, chromfi->getTextValue());
} else if (a == chromco) {
listener->panelChanged(EvWavchromco, chromco->getTextValue());
} else if (a == mergeL) { } else if (a == mergeL) {
listener->panelChanged(EvWavmergeL, mergeL->getTextValue()); listener->panelChanged(EvWavmergeL, mergeL->getTextValue());
} else if (a == mergeC) { } else if (a == mergeC) {

View File

@ -70,6 +70,9 @@ public:
private: private:
rtengine::ProcEvent EvWavenaclari; rtengine::ProcEvent EvWavenaclari;
rtengine::ProcEvent EvWavushamet; rtengine::ProcEvent EvWavushamet;
rtengine::ProcEvent EvWavbalchrom;
rtengine::ProcEvent EvWavchromfi;
rtengine::ProcEvent EvWavchromco;
rtengine::ProcEvent EvWavmergeL; rtengine::ProcEvent EvWavmergeL;
rtengine::ProcEvent EvWavmergeC; rtengine::ProcEvent EvWavmergeC;
rtengine::ProcEvent EvWavsoftrad; rtengine::ProcEvent EvWavsoftrad;
@ -241,6 +244,9 @@ private:
Adjuster* const edgedetectthr2; Adjuster* const edgedetectthr2;
Adjuster* const edgesensi; Adjuster* const edgesensi;
Adjuster* const edgeampli; Adjuster* const edgeampli;
Adjuster* const balchrom;
Adjuster* const chromfi;
Adjuster* const chromco;
Adjuster* const mergeL; Adjuster* const mergeL;
Adjuster* const mergeC; Adjuster* const mergeC;
Adjuster* const softrad; Adjuster* const softrad;
@ -285,6 +291,7 @@ private:
Gtk::Frame* const contFrame; Gtk::Frame* const contFrame;
Gtk::Frame* const blurFrame; Gtk::Frame* const blurFrame;
Gtk::Frame* const chromaFrame; Gtk::Frame* const chromaFrame;
Gtk::Frame* const chroFrame;
Gtk::Label* const wavLabels; Gtk::Label* const wavLabels;
Gtk::Label* const labmC; Gtk::Label* const labmC;