Fixed some bugs in Noise Reduction, Issue 2557 #254

This commit is contained in:
Ingo 2015-02-05 01:08:43 +01:00
parent b05fa5d6a1
commit 9e3ea2924c
2 changed files with 44 additions and 27 deletions

View File

@ -379,8 +379,8 @@ SSEFUNCTION void ImProcFunctions::RGB_denoise(int kall, Imagefloat * src, Imagef
//#endif //#endif
if (dnparams.luma==0 && dnparams.chroma==0 && !dnparams.median && !noiseLCurve && !noiseCCurve) { if (dnparams.luma==0 && dnparams.chroma==0 && !dnparams.median && !noiseLCurve && !noiseCCurve) {
//nothing to do; copy src to dst or do nothing in case src == dst //nothing to do; copy src to dst or do nothing in case src == dst
if(src != dst) if(src != dst)
memcpy(dst->data,src->data,dst->width*dst->height*3*sizeof(float)); src->copyData(dst);
if(calclum) { if(calclum) {
delete calclum; delete calclum;
calclum = NULL; calclum = NULL;
@ -420,10 +420,10 @@ SSEFUNCTION void ImProcFunctions::RGB_denoise(int kall, Imagefloat * src, Imagef
const float noiseluma=(float) dnparams.luma; const float noiseluma=(float) dnparams.luma;
const float noisevarL = (useNoiseLCurve && (denoiseMethodRgb || !isRAW)) ? (float) (SQR(((noiseluma+1.0)/125.0)*(10.+ (noiseluma+1.0)/25.0))) : (float) (SQR((noiseluma/125.0)*(1.0+ noiseluma/25.0))); const float noisevarL = (useNoiseLCurve && (denoiseMethodRgb || !isRAW)) ? (float) (SQR(((noiseluma+1.0)/125.0)*(10.+ (noiseluma+1.0)/25.0))) : (float) (SQR((noiseluma/125.0)*(1.0+ noiseluma/25.0)));
const bool denoiseLuminance = (noisevarL > 0.00001f); const bool denoiseLuminance = (noisevarL > 0.00001f);
if(useNoiseLCurve || useNoiseCCurve) { if(useNoiseLCurve || useNoiseCCurve) {
int hei=calclum->height; int hei=calclum->height;
int wid=calclum->width; int wid=calclum->width;
TMatrix wprofi = iccStore->workingSpaceMatrix (params->icm.working); TMatrix wprofi = iccStore->workingSpaceMatrix (params->icm.working);
const float wpi[3][3] = { const float wpi[3][3] = {
@ -479,7 +479,7 @@ SSEFUNCTION void ImProcFunctions::RGB_denoise(int kall, Imagefloat * src, Imagef
} }
delete calclum; delete calclum;
calclum = NULL; calclum = NULL;
} }
const short int imheight=src->height, imwidth=src->width; const short int imheight=src->height, imwidth=src->width;
@ -593,9 +593,16 @@ do {
if(numtiles == 1) if(numtiles == 1)
dsttmp = dst; dsttmp = dst;
else { else {
dsttmp = new Imagefloat(imwidth,imheight); dsttmp = new Imagefloat(imwidth,imheight);
for (int n=0; n<3*imwidth*imheight; n++) #ifdef _OPENMP
dsttmp->data[n] = 0; #pragma omp parallel for
#endif
for(int i=0;i<imheight;i++)
for(int j=0;j<imwidth;j++) {
dsttmp->r(i,j) = 0.f;
dsttmp->g(i,j) = 0.f;
dsttmp->b(i,j) = 0.f;
}
} }
//now we have tile dimensions, overlaps //now we have tile dimensions, overlaps
@ -685,7 +692,7 @@ do {
int pos; int pos;
float* noisevarlum; float* noisevarlum;
float* noisevarchrom; float* noisevarchrom;
if(numtiles == 1 && isRAW) { if(numtiles == 1 && isRAW && (useNoiseCCurve || useNoiseLCurve)) {
noisevarlum = lumcalcBuffer; noisevarlum = lumcalcBuffer;
noisevarchrom = ccalcBuffer; noisevarchrom = ccalcBuffer;
} else { } else {
@ -705,7 +712,7 @@ do {
int tilebottom = MIN(imheight,tiletop+tileheight); int tilebottom = MIN(imheight,tiletop+tileheight);
int width = tileright-tileleft; int width = tileright-tileleft;
int height = tilebottom-tiletop; int height = tilebottom-tiletop;
int width2 = (width+1)/2; int width2 = (width+1)/2;
float realred, realblue; float realred, realblue;
float interm_med =(float) dnparams.chroma/10.0; float interm_med =(float) dnparams.chroma/10.0;
float intermred, intermblue; float intermred, intermblue;
@ -904,7 +911,13 @@ do {
else levwav=8;//maximum ==> I have increase Maxlevel in cplx_wavelet_dec.h from 8 to 9 else levwav=8;//maximum ==> I have increase Maxlevel in cplx_wavelet_dec.h from 8 to 9
if(nrQuality == QUALITY_HIGH) if(nrQuality == QUALITY_HIGH)
levwav += settings->nrwavlevel;//increase level for enhanced mode levwav += settings->nrwavlevel;//increase level for enhanced mode
if(levwav>8) levwav=8; if(levwav>8) levwav=8;
int minsizetile=min(tilewidth, tileheight);
int maxlev2=8;
if(minsizetile < 256) maxlev2 = 7;
if(minsizetile < 128) maxlev2 = 6;
if(minsizetile < 64) maxlev2 = 5;
levwav=min(maxlev2,levwav);
// if (settings->verbose) printf("levwavelet=%i noisevarA=%f noisevarB=%f \n",levwav, noisevarab_r, noisevarab_b ); // if (settings->verbose) printf("levwavelet=%i noisevarA=%f noisevarB=%f \n",levwav, noisevarab_r, noisevarab_b );
Ldecomp = new wavelet_decomposition (labdn->L[0], labdn->W, labdn->H, levwav, 1, 1, max(1,denoiseNestedLevels)); Ldecomp = new wavelet_decomposition (labdn->L[0], labdn->W, labdn->H, levwav, 1, 1, max(1,denoiseNestedLevels));
@ -1400,7 +1413,7 @@ do {
}//end of tile row }//end of tile row
}//end of tile loop }//end of tile loop
if(numtiles > 1 || !isRAW) { if(numtiles > 1 || !isRAW || (!useNoiseCCurve && !useNoiseLCurve)) {
delete [] noisevarlum; delete [] noisevarlum;
delete [] noisevarchrom; delete [] noisevarchrom;
} }
@ -1418,20 +1431,23 @@ omp_set_nested(oldNested);
#endif #endif
//copy denoised image to output //copy denoised image to output
if(numtiles>1) { if(numtiles>1) {
if(!memoryAllocationFailed) if(!memoryAllocationFailed)
memcpy (dst->data, dsttmp->data, 3*dst->width*dst->height*sizeof(float)); dsttmp->copyData(dst);
else if(dst != src) else if(dst != src)
memcpy (dst->data, src->data, 3*dst->width*dst->height*sizeof(float)); src->copyData(dst);
delete dsttmp; delete dsttmp;
} }
if (!isRAW && !memoryAllocationFailed) {//restore original image gamma if (!isRAW && !memoryAllocationFailed) {//restore original image gamma
#ifdef _OPENMP #ifdef _OPENMP
#pragma omp parallel for #pragma omp parallel for
#endif #endif
for (int i=0; i<3*dst->width*dst->height; i++) { for(int i=0;i<dst->height;i++)
dst->data[i] = Color::gammatab_srgb[ dst->data[i] ]; for(int j=0;j<dst->width;j++) {
} dst->r(i,j) = Color::gammatab_srgb[ dst->r(i,j) ];
} dst->g(i,j) = Color::gammatab_srgb[ dst->g(i,j) ];
dst->b(i,j) = Color::gammatab_srgb[ dst->b(i,j) ];
}
}
if(denoiseLuminance) { if(denoiseLuminance) {
// destroy the plans // destroy the plans
@ -1749,7 +1765,7 @@ SSEFUNCTION void ImProcFunctions::RGBtile_denoise (float * fLblox, int hblproc,
int histo[256] ALIGNED64 = {0}; int histo[256] ALIGNED64 = {0};
//calculate histogram of absolute values of wavelet coeffs //calculate histogram of absolute values of wavelet coeffs
for (int i=0; i<datalen; i++) { for (int i=0; i<datalen; i++) {
histo[min(255,abs((int)DataList[i]))]++; histo[min(255,abs((int)DataList[i]))]++;
} }
@ -2108,7 +2124,7 @@ SSEFUNCTION bool ImProcFunctions::WaveletDenoiseAll_BiShrinkAB(wavelet_decomposi
maxWL = WaveletCoeffs_L.level_W(lvl); maxWL = WaveletCoeffs_L.level_W(lvl);
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;
#ifdef _OPENMP #ifdef _OPENMP
#pragma omp parallel num_threads(denoiseNestedLevels) if(denoiseNestedLevels>1) #pragma omp parallel num_threads(denoiseNestedLevels) if(denoiseNestedLevels>1)

View File

@ -519,9 +519,10 @@ namespace rtengine {
int rowstride; // Plan size, in bytes (all padding bytes included) int rowstride; // Plan size, in bytes (all padding bytes included)
int planestride; // Row length, in bytes (padding bytes included) int planestride; // Row length, in bytes (padding bytes included)
protected:
public:
T* data; T* data;
public:
PlanarPtr<T> r; PlanarPtr<T> r;
PlanarPtr<T> g; PlanarPtr<T> g;
PlanarPtr<T> b; PlanarPtr<T> b;