Clean and optimize local chroma denoise

This commit is contained in:
Desmis 2017-12-15 15:48:35 +01:00
parent 540b0be80a
commit 1faa7d7d08
3 changed files with 105 additions and 58 deletions

View File

@ -1172,6 +1172,7 @@ SSEFUNCTION void ImProcFunctions::RGB_denoise(int kall, Imagefloat * src, Imagef
} else {
madL[lvl][dir - 1] = SQR(MadRgb(WavCoeffs_L[dir], Wlvl_L * Hlvl_L));
}
}
}
}
@ -2531,7 +2532,7 @@ bool ImProcFunctions::WaveletDenoiseAllL(wavelet_decomposition &WaveletCoeffs_L,
int maxlvl = min(WaveletCoeffs_L.maxlevel(), 5);
if (edge == 1 || edge == 3) {
maxlvl = 4; //for refine denoise edge wavelet
maxlvl = 4; //for refine denoise edge wavelet
}
if (edge == 2) {
@ -2744,7 +2745,7 @@ SSEFUNCTION void ImProcFunctions::ShrinkAllL(wavelet_decomposition &WaveletCoeff
SSEFUNCTION void ImProcFunctions::ShrinkAllAB(wavelet_decomposition &WaveletCoeffs_L, 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, bool useNoiseCCurve, bool autoch,
bool denoiseMethodRgb, float * madL, float * variC, int local, float * madaab, bool madCalculated)
{
@ -2777,14 +2778,18 @@ SSEFUNCTION void ImProcFunctions::ShrinkAllAB(wavelet_decomposition &WaveletCoef
madab = SQR(MadRgb(WavCoeffs_ab[dir], W_ab * H_ab));
}
}
float noisevarfc;
if ((local == 2 || local == 3) && variC) {
useNoiseCCurve = true;
noisevarfc = variC[level];
} else {
noisevarfc = noisevar_ab;
}
if (noisevarfc > 0.001f) {//noisevar_ab
// madab = useNoiseCCurve ? madab : madab * noisevar_ab;
//madab = useNoiseCCurve ? madab : madab * noisevar_ab;
madab = useNoiseCCurve ? madab : madab * noisevarfc;
#ifdef __SSE2__
__m128 onev = _mm_set1_ps(1.f);

View File

@ -369,7 +369,7 @@ public:
const bool useNoiseCCurve, bool autoch, bool denoiseMethodRgb);
void ShrinkAllL(wavelet_decomposition &WaveletCoeffs_L, float **buffer, int level, int dir, float *noisevarlum, float * madL, float * vari, int edge);
void ShrinkAllAB(wavelet_decomposition &WaveletCoeffs_L, 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 * variC, int local, float * madaab = nullptr, bool madCalculated = false);
float *noisevarchrom, float noisevar_ab, bool useNoiseCCurve, bool autoch, bool denoiseMethodRgb, float * madL, float * variC, int local, float * madaab = nullptr, bool madCalculated = false);
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,
float &maxchred, float &maxchblue, float &minchred, float &minchblue, int &nb, float &chau, float &chred, float &chblue, bool denoiseMethodRgb);

View File

@ -1861,6 +1861,7 @@ void ImProcFunctions::addGaNoise(LabImage *lab, LabImage *dst, const float mean,
void ImProcFunctions::DeNoise_Local(int call, const struct local_params& lp, LabImage* original, LabImage* transformed, const LabImage &tmp1, int cx, int cy)
{
// local denoise
//simple algo , perhaps we can improve as the others, but noise is here and not good for hue detection
// BENCHFUN
const float ach = (float)lp.trans / 100.f;
@ -1888,6 +1889,7 @@ void ImProcFunctions::DeNoise_Local(int call, const struct local_params& lp, Lab
calcTransition(lox, loy, ach, lp, zone, localFactor);
int begx = int (lp.xc - lp.lxL);
int begy = int (lp.yc - lp.lyT);
float factnoise = (1.f + (lp.noisecf + lp.noisecc) / 300.f);
switch (zone) {
case 0: { // outside selection and outside transition zone => no effect, keep original values
@ -1914,10 +1916,10 @@ void ImProcFunctions::DeNoise_Local(int call, const struct local_params& lp, Lab
difL *= factorx;
difa *= factorx;
difb *= factorx;
difb *= factorx ;
transformed->L[y][x] = original->L[y][x] + difL;
transformed->a[y][x] = original->a[y][x] + difa;
transformed->b[y][x] = original->b[y][x] + difb;
transformed->a[y][x] = original->a[y][x] + difa * factnoise;
transformed->b[y][x] = original->b[y][x] + difb * factnoise;
break;
}
@ -1936,8 +1938,8 @@ void ImProcFunctions::DeNoise_Local(int call, const struct local_params& lp, Lab
}
transformed->L[y][x] = original->L[y][x] + difL;
transformed->a[y][x] = original->a[y][x] + difa;
transformed->b[y][x] = original->b[y][x] + difb;
transformed->a[y][x] = original->a[y][x] + difa * factnoise;
transformed->b[y][x] = original->b[y][x] + difb * factnoise;
}
}
}
@ -8572,7 +8574,7 @@ void ImProcFunctions::Lab_Local(int call, float** shbuffer, LabImage * original,
wavelet_decomposition bdecomp(tmp1.b[0], tmp1.W, tmp1.H, levwavL, 1, skip, numThreads, DaubLen);
float madL[8][3];
// float madC[8][3];
// float madC[8][3];
int edge = 2;
if (!Ldecomp.memoryAllocationFailed) {
@ -8653,23 +8655,6 @@ void ImProcFunctions::Lab_Local(int call, float** shbuffer, LabImage * original,
float variC[levred];
if (!adecomp.memoryAllocationFailed && !bdecomp.memoryAllocationFailed) {
/*
#pragma omp parallel for collapse(2) schedule(dynamic,1)
for (int lvl = 0; lvl < levred; ++lvl) {
// compute median absolute deviation (MAD) of detail coefficients as robust noise estimator
for (int dir = 1; dir < 4; ++dir) {
int Wlvl_ab = adecomp.level_W(lvl);//approximation with only "a" (better than L
int Hlvl_ab = adecomp.level_H(lvl);
float ** WavCoeffs_ab = adecomp.level_coeffs(lvl);
madC[lvl][dir - 1] = SQR(Mad(WavCoeffs_ab[dir], Wlvl_ab * Hlvl_ab));
}
}
*/
if (levred == 7) {
edge = 2;
@ -8703,17 +8688,51 @@ void ImProcFunctions::Lab_Local(int call, float** shbuffer, LabImage * original,
variC[3] = max(minic, variC[3]);
if (levred == 7) {
float k6 = 0.f;
variC[4] = max(0.0001f, variC[4]);
variC[5] = max(0.0001f, variC[5]);
variC[6] = max(0.0001f, variC[6]);
if (lp.noisecc < 20.f) {
k6 = 0.f;
} else if (lp.noisecc < 50.f) {
k6 = 0.4f;
} else if (lp.noisecc < 70.f) {
k6 = 0.7f;
} else {
k6 = 1.f;
}
variC[6] = max(0.0001f, k6 * variC[6]);
}
float* noisevarchrom = new float[GH * GW];
//noisevarchrom in function chroma
int GW2 = (GW + 1) / 2;
float nvch = 50.f;//high value
float nvcl = 8.f;//low value
float seuil = 3000.f;//low
float seuil2 = 20000.f;//high
//ac and bc for transition
float ac = (nvch - nvcl) / (seuil - seuil2);
float bc = nvch - seuil * ac;
#ifdef _OPENMP
#pragma omp parallel for
#endif
for (int ir = 0; ir < GH; ir++)
for (int jr = 0; jr < GW; jr++) {
float cN = sqrt(SQR(tmp1.a[ir][jr]) + SQR(tmp1.b[ir][jr]));
if (cN < seuil) {
noisevarchrom[(ir >> 1)*GW2 + (jr >> 1)] = 1.f * SQR(nvch);
} else if (cN < seuil2) {
noisevarchrom[(ir >> 1)*GW2 + (jr >> 1)] = 1.f * SQR(ac * cN + bc);
} else {
noisevarchrom[(ir >> 1)*GW2 + (jr >> 1)] = 1.f * SQR(nvcl);
}
}
for (int q = 0; q < GH * GW; q++) {
noisevarchrom[q] = 50.f;
}
float noisevarab_r = 100.f; //SQR(lp.noisecc / 10.0);
WaveletDenoiseAllAB(Ldecomp, adecomp, noisevarchrom, madL, variC, edge, noisevarab_r, false, false, false, numThreads);
@ -8725,6 +8744,10 @@ void ImProcFunctions::Lab_Local(int call, float** shbuffer, LabImage * original,
if (!Ldecomp.memoryAllocationFailed) {
Lin = new array2D<float>(GW, GH);
#ifdef _OPENMP
#pragma omp parallel for
#endif
for (int i = 0; i < GH; ++i) {
for (int j = 0; j < GW; ++j) {
@ -8754,7 +8777,7 @@ void ImProcFunctions::Lab_Local(int call, float** shbuffer, LabImage * original,
int masterThread = omp_get_thread_num();
#endif
#ifdef _OPENMP
#pragma omp parallel //num_threads(denoiseNestedLevels) if (denoiseNestedLevels>1)
#pragma omp parallel
#endif
{
#ifdef _OPENMP
@ -9081,23 +9104,6 @@ void ImProcFunctions::Lab_Local(int call, float** shbuffer, LabImage * original,
float variC[levred];
if (!adecomp.memoryAllocationFailed && !bdecomp.memoryAllocationFailed) {
/*
float madC[8][3];
#pragma omp parallel for collapse(2) schedule(dynamic,1)
for (int lvl = 0; lvl < levred; ++lvl) {
// compute median absolute deviation (MAD) of detail coefficients as robust noise estimator
for (int dir = 1; dir < 4; ++dir) {
int Wlvl_ab = adecomp.level_W(lvl);//approximation with only "a" (better than L
int Hlvl_ab = adecomp.level_H(lvl);
float ** WavCoeffs_ab = adecomp.level_coeffs(lvl);
madC[lvl][dir - 1] = SQR(Mad(WavCoeffs_ab[dir], Wlvl_ab * Hlvl_ab));
}
}
*/
if (levred == 7) {
edge = 2;
variC[0] = SQR(lp.noisecf / 10.0);
@ -9129,17 +9135,50 @@ void ImProcFunctions::Lab_Local(int call, float** shbuffer, LabImage * original,
variC[3] = max(minic, variC[3]);
if (levred == 7) {
float k6 = 0.f;
variC[4] = max(0.0001f, variC[4]);
variC[5] = max(0.0001f, variC[5]);
variC[6] = max(0.0001f, variC[6]);
if (lp.noisecc < 20.f) {
k6 = 0.f;
} else if (lp.noisecc < 50.f) {
k6 = 0.4f;
} else if (lp.noisecc < 70.f) {
k6 = 0.7f;
} else {
k6 = 1.f;
}
variC[6] = max(0.0001f, k6 * variC[6]);
}
float* noisevarchrom = new float[bfh * bfw];
int bfw2 = (bfw + 1) / 2;
float nvch = 50.f;//high value
float nvcl = 8.f;//low value
float seuil = 3000.f;//low
float seuil2 = 20000.f;//high
//ac and bc for transition
float ac = (nvch - nvcl) / (seuil - seuil2);
float bc = nvch - seuil * ac;
#ifdef _OPENMP
#pragma omp parallel for
#endif
for (int ir = 0; ir < bfh; ir++)
for (int jr = 0; jr < bfw; jr++) {
float cN = sqrt(SQR(bufwv.a[ir][jr]) + SQR(bufwv.b[ir][jr]));
if (cN < seuil) {
noisevarchrom[(ir >> 1)*bfw2 + (jr >> 1)] = 0.5f * SQR(nvch);
} else if (cN < seuil2) {
noisevarchrom[(ir >> 1)*bfw2 + (jr >> 1)] = 0.5f * SQR(ac * cN + bc);
} else {
noisevarchrom[(ir >> 1)*bfw2 + (jr >> 1)] = 0.5f * SQR(nvcl);
}
}
for (int q = 0; q < bfh * bfw; q++) {
noisevarchrom[q] = 50.f;
}
float noisevarab_r = 100.f; //SQR(lp.noisecc / 10.0);
@ -9152,8 +9191,11 @@ void ImProcFunctions::Lab_Local(int call, float** shbuffer, LabImage * original,
if (!Ldecomp.memoryAllocationFailed) {
Lin = new array2D<float>(bfw, bfh);
// #pragma omp parallel for num_threads(numThreads) if (numThreads>1)
#ifdef _OPENMP
#pragma omp parallel for
#endif
for (int i = 0; i < bfh; ++i) {
for (int j = 0; j < bfw; ++j) {
@ -9185,7 +9227,7 @@ void ImProcFunctions::Lab_Local(int call, float** shbuffer, LabImage * original,
int masterThread = omp_get_thread_num();
#endif
#ifdef _OPENMP
#pragma omp parallel //num_threads(denoiseNestedLevels) if (denoiseNestedLevels>1)
#pragma omp parallel
#endif
{
#ifdef _OPENMP
@ -9302,7 +9344,7 @@ void ImProcFunctions::Lab_Local(int call, float** shbuffer, LabImage * original,
//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
#ifdef _OPENMP
#pragma omp parallel for //num_threads(denoiseNestedLevels) if (denoiseNestedLevels>1)
#pragma omp parallel for
#endif
for (int i = 0; i < bfh; ++i) {