From 9ee47c29a3d826bbb422cac2a45ec7e76d248177 Mon Sep 17 00:00:00 2001 From: heckflosse Date: Sun, 17 Mar 2019 19:45:46 +0100 Subject: [PATCH] Small speedup for denoise (mainly for preview mode), #5225 --- rtengine/FTblockDN.cc | 85 +++++++++---------------------------------- rtengine/improcfun.h | 7 ++-- 2 files changed, 20 insertions(+), 72 deletions(-) diff --git a/rtengine/FTblockDN.cc b/rtengine/FTblockDN.cc index 62483c3d7..12344a25b 100644 --- a/rtengine/FTblockDN.cc +++ b/rtengine/FTblockDN.cc @@ -2112,52 +2112,7 @@ void ImProcFunctions::RGBoutput_tile_row(float *bloxrow_L, float ** Ldetail, flo #undef epsilon */ -//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% -//%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - -float ImProcFunctions::MadMax(float * DataList, int & max, int datalen) -{ - - //computes Median Absolute Deviation and Maximum of DataList - //DataList values should mostly have abs val < 65535 - - int * histo = new int[65536]; - - //memset(histo, 0, 65536*sizeof(histo)); - for (int i = 0; i < 65536; ++i) { - histo[i] = 0; - } - - //calculate histogram of absolute values of HH wavelet coeffs - for (int i = 0; i < datalen; ++i) { - histo[MAX(0, MIN(65535, abs((int)DataList[i])))]++; - } - - //find median of histogram - int median = 0, count = 0; - - while (count < datalen / 2) { - count += histo[median]; - ++median; - } - - //find max of histogram - max = 65535; - - while (histo[max] == 0) { - max--; - } - - int count_ = count - histo[median - 1]; - - delete[] histo; - - // interpolate - return (((median - 1) + (datalen / 2 - count_) / (static_cast(count - count_))) / 0.6745); - -} - -float ImProcFunctions::Mad(float * DataList, const int datalen) +float ImProcFunctions::Mad(const float * DataList, const int datalen) { if (datalen <= 1) { // Avoid possible buffer underrun return 0; @@ -2169,7 +2124,7 @@ float ImProcFunctions::Mad(float * DataList, const int datalen) //calculate histogram of absolute values of wavelet coeffs for (int i = 0; i < datalen; ++i) { - histo[min(255, abs(static_cast(DataList[i])))]++; + histo[static_cast(rtengine::min(255.f, fabsf(DataList[i])))]++; } //find median of histogram @@ -2186,7 +2141,7 @@ float ImProcFunctions::Mad(float * DataList, const int datalen) return (((median - 1) + (datalen / 2 - count_) / (static_cast(count - count_))) / 0.6745); } -float ImProcFunctions::MadRgb(float * DataList, const int datalen) +float ImProcFunctions::MadRgb(const float * DataList, const int datalen) { if (datalen <= 1) { // Avoid possible buffer underrun return 0; @@ -2201,10 +2156,8 @@ float ImProcFunctions::MadRgb(float * DataList, const int datalen) } //calculate histogram of absolute values of wavelet coeffs - int i; - - for (i = 0; i < datalen; ++i) { - histo[min(65535, abs(static_cast(DataList[i])))]++; + for (int i = 0; i < datalen; ++i) { + histo[static_cast(rtengine::min(65535.f, fabsf(DataList[i])))]++; } //find median of histogram @@ -2224,27 +2177,23 @@ float ImProcFunctions::MadRgb(float * DataList, const int datalen) -void ImProcFunctions::Noise_residualAB(wavelet_decomposition &WaveletCoeffs_ab, float &chresid, float &chmaxresid, bool denoiseMethodRgb) +void ImProcFunctions::Noise_residualAB(const wavelet_decomposition &WaveletCoeffs_ab, float &chresid, float &chmaxresid, bool denoiseMethodRgb) { - int maxlvl = WaveletCoeffs_ab.maxlevel(); + float resid = 0.f; - float madC; float maxresid = 0.f; - for (int lvl = 0; lvl < maxlvl; ++lvl) { +#ifdef _OPENMP + #pragma omp parallel for schedule(dynamic) collapse(2) reduction(+:resid) reduction(max:maxresid) num_threads(denoiseNestedLevels) if (denoiseNestedLevels>1) +#endif + for (int lvl = 0; lvl < WaveletCoeffs_ab.maxlevel(); ++lvl) { // compute median absolute deviation (MAD) of detail coefficients as robust noise estimator - - int Wlvl_ab = WaveletCoeffs_ab.level_W(lvl); - int Hlvl_ab = WaveletCoeffs_ab.level_H(lvl); - - float ** WavCoeffs_ab = WaveletCoeffs_ab.level_coeffs(lvl); - for (int dir = 1; dir < 4; ++dir) { - if (denoiseMethodRgb) { - madC = SQR(MadRgb(WavCoeffs_ab[dir], Wlvl_ab * Hlvl_ab)); - } else { - madC = SQR(Mad(WavCoeffs_ab[dir], Wlvl_ab * Hlvl_ab)); - } + const int Wlvl_ab = WaveletCoeffs_ab.level_W(lvl); + const int Hlvl_ab = WaveletCoeffs_ab.level_H(lvl); + + float ** WavCoeffs_ab = WaveletCoeffs_ab.level_coeffs(lvl); + const float madC = SQR(denoiseMethodRgb ? MadRgb(WavCoeffs_ab[dir], Wlvl_ab * Hlvl_ab) : Mad(WavCoeffs_ab[dir], Wlvl_ab * Hlvl_ab)); resid += madC; @@ -2624,7 +2573,7 @@ bool ImProcFunctions::WaveletDenoiseAllAB(wavelet_decomposition &WaveletCoeffs_L if (!memoryAllocationFailed) { #ifdef _OPENMP - #pragma omp for schedule(dynamic) collapse(2) + #pragma omp for schedule(dynamic) collapse(2) nowait #endif for (int lvl = 0; lvl < maxlvl; ++lvl) { diff --git a/rtengine/improcfun.h b/rtengine/improcfun.h index 75e8341b9..e3e798b9e 100644 --- a/rtengine/improcfun.h +++ b/rtengine/improcfun.h @@ -326,11 +326,10 @@ public: 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); - void Noise_residualAB(wavelet_decomposition &WaveletCoeffs_ab, float &chresid, float &chmaxresid, bool denoiseMethodRgb); + void Noise_residualAB(const wavelet_decomposition &WaveletCoeffs_ab, float &chresid, float &chmaxresid, bool denoiseMethodRgb); void 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 MadMax(float * DataList, int &max, int datalen); - float Mad(float * DataList, const int datalen); - float MadRgb(float * DataList, const int datalen); + float Mad(const float * DataList, const int datalen); + float MadRgb(const float * DataList, const int datalen); // pyramid wavelet void dirpyr_equalizer(float ** src, float ** dst, int srcwidth, int srcheight, float ** l_a, float ** l_b, const double * mult, const double dirpyrThreshold, const double skinprot, float b_l, float t_l, float t_r, int scale); //Emil's directional pyramid wavelet