From a9f2594602cfc5969c21afdc612d31ba23c5a12f Mon Sep 17 00:00:00 2001 From: Emil Martinec Date: Sat, 17 Jul 2010 16:28:50 -0500 Subject: [PATCH] Bugfix for AMaZE. --- rtengine/amaze_interpolate_RT.cc | 523 ++++++++++++++++++------------- 1 file changed, 310 insertions(+), 213 deletions(-) diff --git a/rtengine/amaze_interpolate_RT.cc b/rtengine/amaze_interpolate_RT.cc index e3b3a6ad2..d7d66a631 100644 --- a/rtengine/amaze_interpolate_RT.cc +++ b/rtengine/amaze_interpolate_RT.cc @@ -28,18 +28,14 @@ void RawImageSource::amaze_demosaic_RT() { -#undef MAX -#undef MIN -#undef CLIP - #define SQR(x) ((x)*(x)) -#define MIN(a,b) ((a) < (b) ? (a) : (b)) -#define MAX(a,b) ((a) > (b) ? (a) : (b)) + //#define MIN(a,b) ((a) < (b) ? (a) : (b)) + //#define MAX(a,b) ((a) > (b) ? (a) : (b)) #define LIM(x,min,max) MAX(min,MIN(x,max)) #define ULIM(x,y,z) ((y) < (z) ? LIM(x,y,z) : LIM(x,z,y)) -#define CLIP(x) LIM(x,0,65535) - - + //#define CLIP(x) LIM(x,0,65535) + + //allocate outpute arrays int width=W, height=H; red = new unsigned short*[H]; for (int i=0; isetProgressStr ("AMaZE Demosaicing..."); plistener->setProgress (0.0); } - + // %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - - + + //determine GRBG coset; (ey,ex) is the offset of the R subarray if (FC(0,0)==1) {//first pixel is G if (FC(0,1)==0) {ey=0; ex=1;} else {ey=1; ex=0;} } else {//first pixel is R or B if (FC(0,0)==0) {ey=0; ex=0;} else {ey=1; ex=1;} } - + // Main algorithm: Tile loop //#pragma omp parallel for shared(ri->data,height,width,red,green,blue) private(top,left) schedule(dynamic) //code is openmp ready; just have to pull local tile variable declarations inside the tile loop for (top=-16; top < height; top += TS-32) for (left=-16; left < width; left += TS-32) { + //location of tile bottom edge int bottom = MIN( top+TS,height+16); + //location of tile right edge int right = MIN(left+TS, width+16); + //tile width (=TS except for right edge of image) int rr1 = bottom - top; + //tile height (=TS except for bottom edge of image) int cc1 = right - left; - + //tile vars + //counters for pixel location in the image int row, col; + //min and max row/column in the tile int rrmin, rrmax, ccmin, ccmax; - int rr, cc, c, indx, indx1, dir, i, j, sgn; - - float crse, crnw, crne, crsw, rbse, rbnw, rbne, rbsw, wtse, wtnw, wtsw, wtne; - float pmwtalt; - + //counters for pixel location within the tile + int rr, cc; + //color index 0=R, 1=G, 2=B + int c; + //pointer counters within the tile + int indx, indx1; + //direction counter for nbrs[] + int dir; + //dummy indices + int i, j; + // +1 or -1 + int sgn; + + //color ratios in up/down/left/right directions float cru, crd, crl, crr; - float vwt, hwt, pwt, mwt, Gintv, Ginth; - float guar, gdar, glar, grar, guha, gdha, glha, grha, Ginthar, Ginthha, Gintvar, Gintvha, hcdaltvar, vcdaltvar; + //adaptive weights for vertical/horizontal/plus/minus directions + float vwt, hwt, pwt, mwt; + //vertical and horizontal G interpolations + float Gintv, Ginth; + //G interpolated in vert/hor directions using adaptive ratios + float guar, gdar, glar, grar; + //G interpolated in vert/hor directions using Hamilton-Adams method + float guha, gdha, glha, grha; + //interpolated G from fusing left/right or up/down + float Ginthar, Ginthha, Gintvar, Gintvha; + //color difference (G-R or G-B) variance in up/down/left/right directions float Dgrbvvaru, Dgrbvvard, Dgrbhvarl, Dgrbhvarr; - float sumh, sumv, sumsqh, sumsqv, areawt; - float nyqtest, vcdvar, hcdvar, hvwtalt, vo, ve, gradp, gradm, gradv, gradh, gradpm, gradhv; - float vcdvar1, hcdvar1, varwt, diffwt; - float rbvarp, rbvarm; + //gradients in various directions + float gradp, gradm, gradv, gradh, gradpm, gradhv; + //color difference variances in vertical and horizontal directions + float vcdvar, hcdvar, vcdvar1, hcdvar1, hcdaltvar, vcdaltvar; + //adaptive interpolation weight using variance of color differences + float varwt; + //adaptive interpolation weight using difference of left-right and up-down G interpolations + float diffwt; + //alternative adaptive weight for combining horizontal/vertical interpolations + float hvwtalt; + //temporary variables for combining interpolation weights at R and B sites + float vo, ve; + //interpolation of G in four directions float gu, gd, gl, gr; - float gvarh, gvarv; - + //variance of G in vertical/horizontal directions + float gvarh, gvarv; + + //Nyquist texture test + float nyqtest; + //accumulators for Nyquist texture interpolation + float sumh, sumv, sumsqh, sumsqv, areawt; + + //color ratios in diagonal directions + float crse, crnw, crne, crsw; + //color differences in diagonal directions + float rbse, rbnw, rbne, rbsw; + //adaptive weights for combining diagonal interpolations + float wtse, wtnw, wtsw, wtne; + //alternate weight for combining diagonal interpolations + float pmwtalt; + //variance of R-B in plus/minus directions + float rbvarp, rbvarm; + + // %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% /* char *buffer; // TS*TS*168 @@ -252,10 +346,10 @@ void RawImageSource::amaze_demosaic_RT() { float (*pmwt); // TS*TS*4 float (*rbp); // TS*TS*4 float (*rbm); // TS*TS*4 - + int (*nyquist); // TS*TS*4 - - + + // assign working space buffer = (char *) malloc(35*sizeof(float)*TS*TS); //merror(buffer,"amaze_interpolate()"); @@ -291,15 +385,18 @@ void RawImageSource::amaze_demosaic_RT() { pmwt = (float (*)) (buffer + 31*sizeof(float)*TS*TS); rbp = (float (*)) (buffer + 32*sizeof(float)*TS*TS); rbm = (float (*)) (buffer + 33*sizeof(float)*TS*TS); - + nyquist = (int (*)) (buffer + 34*sizeof(float)*TS*TS); */ // %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - - + + // rgb from input CFA data // rgb values should be floating point number between 0 and 1 // after white balance multipliers are applied + // a 16 pixel border is added to each side of the image + + // bookkeeping for borders if (top<0) {rrmin=16;} else {rrmin=0;} if (left<0) {ccmin=16;} else {ccmin=0;} if (bottom>height) {rrmax=height-top;} else {rrmax=rr1;} @@ -390,10 +487,10 @@ void RawImageSource::amaze_demosaic_RT() { cfa[(rrmax+rr)*TS+cc] = rgb[(rrmax+rr)*TS+cc][c]; } } - + //end of border fill // %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - + for (rr=1; rr < rr1-1; rr++) for (cc=1, indx=(rr)*TS+cc; cc < cc1-1; cc++, indx++) { @@ -405,7 +502,7 @@ void RawImageSource::amaze_demosaic_RT() { delm[indx] = fabs(cfa[indx+m1]-cfa[indx-m1]); } - + for (rr=2; rr < rr1-2; rr++) for (cc=2,indx=(rr)*TS+cc; cc < cc1-2; cc++, indx++) { @@ -422,44 +519,44 @@ void RawImageSource::amaze_demosaic_RT() { Dgrbmsq1[indx]=(SQR(cfa[indx]-cfa[indx-m1])+SQR(cfa[indx]-cfa[indx+m1])); } } - + //t2_init += clock()-t1_init; // end of tile initialization // %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - + //interpolate vertical and horizontal color differences //t1_vcdhcd = clock(); - + for (rr=4; rr0) { if (3*hcd[indx] > (Ginth+cfa[indx])) { hcd[indx]=-ULIM(Ginth,cfa[indx-1],cfa[indx+1])+cfa[indx]; @@ -517,12 +614,12 @@ void RawImageSource::amaze_demosaic_RT() { if (Gintv > 1) vcd[indx]=-ULIM(Gintv,cfa[indx-v1],cfa[indx+v1])+cfa[indx]; //if (Ginth > pre_mul[c]) hcd[indx]=-ULIM(Ginth,cfa[indx-1],cfa[indx+1])+cfa[indx];//for dcraw implementation //if (Gintv > pre_mul[c]) vcd[indx]=-ULIM(Gintv,cfa[indx-v1],cfa[indx+v1])+cfa[indx]; - + } else { - + Ginth = hcd[indx]+cfa[indx];//interpolated G Gintv = vcd[indx]+cfa[indx]; - + if (hcd[indx]<0) { if (3*hcd[indx] < -(Ginth+cfa[indx])) { hcd[indx]=ULIM(Ginth,cfa[indx-1],cfa[indx+1])-cfa[indx]; @@ -539,7 +636,7 @@ void RawImageSource::amaze_demosaic_RT() { vcd[indx]=vwt*vcd[indx] + (1-vwt)*(ULIM(Gintv,cfa[indx-v1],cfa[indx+v1])-cfa[indx]); } } - + if (Ginth > 1) hcd[indx]=ULIM(Ginth,cfa[indx-1],cfa[indx+1])-cfa[indx];//for RT implementation if (Gintv > 1) vcd[indx]=ULIM(Gintv,cfa[indx-v1],cfa[indx+v1])-cfa[indx]; //if (Ginth > pre_mul[c]) hcd[indx]=ULIM(Ginth,cfa[indx-1],cfa[indx+1])-cfa[indx];//for dcraw implementation @@ -550,49 +647,49 @@ void RawImageSource::amaze_demosaic_RT() { hcdsq[indx] = SQR(hcd[indx]); cddiffsq[indx] = SQR(vcd[indx]-hcd[indx]); } - + for (rr=6; rr0 && fabs(0.5-diffwt)0) {nyquist[indx]=1;}//nyquist=1 for nyquist region } - + for (rr=8; rr 1) rbp[indx]=ULIM(rbp[indx],cfa[indx-p1],cfa[indx+p1]);//for RT implementation if (rbm[indx] > 1) rbm[indx]=ULIM(rbm[indx],cfa[indx-m1],cfa[indx+m1]); //c=FC(rr,cc);//for dcraw implementation @@ -854,13 +951,13 @@ void RawImageSource::amaze_demosaic_RT() { // %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% //rbint[indx] = 0.5*(cfa[indx] + (rbp*rbvarm+rbm*rbvarp)/(rbvarp+rbvarm));//this is R+B, interpolated - } - - - + } + + + for (rr=10; rr 1) Ginth=ULIM(Ginth,cfa[indx-1],cfa[indx+1]);//for RT implementation if (Gintv > 1) Gintv=ULIM(Gintv,cfa[indx-v1],cfa[indx+v1]); //c=FC(rr,cc);//for dcraw implementation @@ -937,7 +1034,7 @@ void RawImageSource::amaze_demosaic_RT() { //t2_diag += clock() - t1_diag; // %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% // %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - + //t1_chroma = clock(); //fancy chrominance interpolation //(ey,ex) is location of R site @@ -952,16 +1049,16 @@ void RawImageSource::amaze_demosaic_RT() { wtne=1.0/(eps+fabs(Dgrb[indx+p1][c]-Dgrb[indx-p1][c])+fabs(Dgrb[indx+p1][c]-Dgrb[indx+p3][c])+fabs(Dgrb[indx-p1][c]-Dgrb[indx+p3][c])); wtsw=1.0/(eps+fabs(Dgrb[indx-p1][c]-Dgrb[indx+p1][c])+fabs(Dgrb[indx-p1][c]-Dgrb[indx+m3][c])+fabs(Dgrb[indx+p1][c]-Dgrb[indx-p3][c])); wtse=1.0/(eps+fabs(Dgrb[indx+m1][c]-Dgrb[indx-m1][c])+fabs(Dgrb[indx+m1][c]-Dgrb[indx-p3][c])+fabs(Dgrb[indx-m1][c]-Dgrb[indx+m3][c])); - + Dgrb[indx][c]=(wtnw*Dgrb[indx-m1][c]+wtne*Dgrb[indx+p1][c]+wtsw*Dgrb[indx-p1][c]+wtse*Dgrb[indx+m1][c])/(wtnw+wtne+wtsw+wtse); } for (rr=12; rrsetProgress(fabs((float)top/height)); - } - + } + // %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% - - - + + + // clean up free(buffer); - + // done #undef TS