/* ---------------------------------------------------------------------------- Function : PyOptMed3() In : pointer to array of 3 pixel values Out : a pixel value Job : optimized search of the median of 3 pixel values Notice : found on sci.image.processing cannot go faster unless assumptions are made on the nature of the input signal. Code adapted from Nicolas Devillard. --------------------------------------------------------------------------- */ float PyOptMed3(float* p) { PyDoc_STRVAR(PyOptMed3__doc__, "PyOptMed3(a) -> float\n\n" "Get the median of array a of length 3 using a search tree."); PIX_SORT(p[0], p[1]); PIX_SORT(p[1], p[2]); PIX_SORT(p[0], p[1]); return p[1]; }
static void median_5 (unsigned char *src, unsigned char *dest, int width, int height) { int nLastRow; int nLastCol; unsigned char p[9]; int i, j, k; nLastCol = width - 1; nLastRow = height - 1; /*copy the top and bottom rows into the result array */ for (i = 0; i < width; i++) { dest[i] = src[i]; dest[nLastRow * width + i] = src[nLastRow * width + i]; } dest[i] = src[i]; nLastCol--; nLastRow--; /* process the interior pixels */ i = width + 1; for (k = 0; k < nLastRow; k++) { for (j = 0; j < nLastCol; j++, i++) { p[0] = src[i - width]; p[1] = src[i - 1]; p[2] = src[i]; p[3] = src[i + 1]; p[4] = src[i + width]; PIX_SORT (p[0], p[1]); PIX_SORT (p[3], p[4]); PIX_SORT (p[0], p[3]); PIX_SORT (p[1], p[4]); PIX_SORT (p[1], p[2]); PIX_SORT (p[2], p[3]); PIX_SORT (p[1], p[2]); dest[i] = p[2]; } dest[i] = src[i]; i++; dest[i] = src[i]; i++; } dest[i] = src[i]; i++; }
static void median_5 (guint8 * dest, gint dstride, const guint8 * src, gint sstride, gint width, gint height) { unsigned char p[5]; int i, j, k; /* copy the top and bottom rows into the result array */ for (i = 0; i < width; i++) { dest[i] = src[i]; dest[(height - 1) * dstride + i] = src[(height - 1) * sstride + i]; } /* process the interior pixels */ for (k = 2; k < height; k++) { dest += dstride; src += sstride; dest[0] = src[0]; for (j = 2, i = 1; j < width; j++, i++) { p[0] = src[i - sstride]; p[1] = src[i - 1]; p[2] = src[i]; p[3] = src[i + 1]; p[4] = src[i + sstride]; PIX_SORT (p[0], p[1]); PIX_SORT (p[3], p[4]); PIX_SORT (p[0], p[3]); PIX_SORT (p[1], p[4]); PIX_SORT (p[1], p[2]); PIX_SORT (p[2], p[3]); PIX_SORT (p[1], p[2]); dest[i] = p[2]; } dest[i] = src[i]; } }
float findMedian(float a0, float a1, float a2, float a3, float a4, float a5, float a6) { PIX_SORT(a0, a5) ; PIX_SORT(a0, a3) ; PIX_SORT(a1, a6) ; PIX_SORT(a2, a4) ; PIX_SORT(a0, a1) ; PIX_SORT(a3, a5) ; PIX_SORT(a2, a6) ; PIX_SORT(a2, a3) ; PIX_SORT(a3, a6) ; PIX_SORT(a4, a5) ; PIX_SORT(a1, a4) ; PIX_SORT(a1, a3) ; PIX_SORT(a3, a4) ; return (a3) ; };
//________________________________________________________________________ uint8_t ADMVideoLargeMedian::doLine(uint8_t *pred2,uint8_t *pred1, uint8_t *cur, uint8_t *next1,uint8_t *next2, uint8_t *out, uint32_t w) { static uint8_t box[5][5]; static uint8_t box2[5][5]; uint32_t col; uint8_t temp; uint32_t inbox; // prefill box for(uint32_t x=0;x<4;x++) { box[0][x+1]=*(pred2+x); box[1][x+1]=*(pred1+x); box[2][x+1]=*(cur+x); box[3][x+1]=*(next1+x); box[4][x+1]=*(next2+x); } col=0; *out=*cur; *(out+1)=*(cur+1); *(out+w-1)=*(cur+w-1); *(out+w-2)=*(cur+w-2); out+=2; next1+=4; next2+=4; pred1+=4; pred2+=4; cur+=4; while(w>4) { // fill box[0][col]=*pred2++; box[1][col]=*pred1++; box[2][col]=*cur++; box[3][col]=*next1++; box[4][col]=*next2++; col++; col%=5; // copy & sort memcpy(box2,box,5*5); uint8_t *p=(uint8_t *)box2; inbox=0; #define PIX_SORT(a,b) { if ((a)>(b)) PIX_SWAP((a),(b)); } #define PIX_SWAP(a,b) { temp=(a);(a)=(b);(b)=temp; } PIX_SORT(p[0], p[1]) ; PIX_SORT(p[3], p[4]) ; PIX_SORT(p[2], p[4]) ; PIX_SORT(p[2], p[3]) ; PIX_SORT(p[6], p[7]) ; PIX_SORT(p[5], p[7]) ; PIX_SORT(p[5], p[6]) ; PIX_SORT(p[9], p[10]) ; PIX_SORT(p[8], p[10]) ; PIX_SORT(p[8], p[9]) ; PIX_SORT(p[12], p[13]) ; PIX_SORT(p[11], p[13]) ; PIX_SORT(p[11], p[12]) ; PIX_SORT(p[15], p[16]) ; PIX_SORT(p[14], p[16]) ; PIX_SORT(p[14], p[15]) ; PIX_SORT(p[18], p[19]) ; PIX_SORT(p[17], p[19]) ; PIX_SORT(p[17], p[18]) ; PIX_SORT(p[21], p[22]) ; PIX_SORT(p[20], p[22]) ; PIX_SORT(p[20], p[21]) ; PIX_SORT(p[23], p[24]) ; PIX_SORT(p[2], p[5]) ; PIX_SORT(p[3], p[6]) ; PIX_SORT(p[0], p[6]) ; PIX_SORT(p[0], p[3]) ; PIX_SORT(p[4], p[7]) ; PIX_SORT(p[1], p[7]) ; PIX_SORT(p[1], p[4]) ; PIX_SORT(p[11], p[14]) ; PIX_SORT(p[8], p[14]) ; PIX_SORT(p[8], p[11]) ; PIX_SORT(p[12], p[15]) ; PIX_SORT(p[9], p[15]) ; PIX_SORT(p[9], p[12]) ; PIX_SORT(p[13], p[16]) ; PIX_SORT(p[10], p[16]) ; PIX_SORT(p[10], p[13]) ; PIX_SORT(p[20], p[23]) ; PIX_SORT(p[17], p[23]) ; PIX_SORT(p[17], p[20]) ; PIX_SORT(p[21], p[24]) ; PIX_SORT(p[18], p[24]) ; PIX_SORT(p[18], p[21]) ; PIX_SORT(p[19], p[22]) ; PIX_SORT(p[8], p[17]) ; PIX_SORT(p[9], p[18]) ; PIX_SORT(p[0], p[18]) ; PIX_SORT(p[0], p[9]) ; PIX_SORT(p[10], p[19]) ; PIX_SORT(p[1], p[19]) ; PIX_SORT(p[1], p[10]) ; PIX_SORT(p[11], p[20]) ; PIX_SORT(p[2], p[20]) ; PIX_SORT(p[2], p[11]) ; PIX_SORT(p[12], p[21]) ; PIX_SORT(p[3], p[21]) ; PIX_SORT(p[3], p[12]) ; PIX_SORT(p[13], p[22]) ; PIX_SORT(p[4], p[22]) ; PIX_SORT(p[4], p[13]) ; PIX_SORT(p[14], p[23]) ; PIX_SORT(p[5], p[23]) ; PIX_SORT(p[5], p[14]) ; PIX_SORT(p[15], p[24]) ; PIX_SORT(p[6], p[24]) ; PIX_SORT(p[6], p[15]) ; PIX_SORT(p[7], p[16]) ; PIX_SORT(p[7], p[19]) ; PIX_SORT(p[13], p[21]) ; PIX_SORT(p[15], p[23]) ; PIX_SORT(p[7], p[13]) ; PIX_SORT(p[7], p[15]) ; PIX_SORT(p[1], p[9]) ; PIX_SORT(p[3], p[11]) ; PIX_SORT(p[5], p[17]) ; PIX_SORT(p[11], p[17]) ; PIX_SORT(p[9], p[17]) ; PIX_SORT(p[4], p[10]) ; PIX_SORT(p[6], p[12]) ; PIX_SORT(p[7], p[14]) ; PIX_SORT(p[4], p[6]) ; PIX_SORT(p[4], p[7]) ; PIX_SORT(p[12], p[14]) ; PIX_SORT(p[10], p[14]) ; PIX_SORT(p[6], p[7]) ; PIX_SORT(p[10], p[12]) ; PIX_SORT(p[6], p[10]) ; PIX_SORT(p[6], p[17]) ; PIX_SORT(p[12], p[17]) ; PIX_SORT(p[7], p[17]) ; PIX_SORT(p[7], p[10]) ; PIX_SORT(p[12], p[18]) ; PIX_SORT(p[7], p[12]) ; PIX_SORT(p[10], p[18]) ; PIX_SORT(p[12], p[20]) ; PIX_SORT(p[10], p[20]) ; PIX_SORT(p[10], p[12]) ; *out++=p[12]; w--; } return 1; }
uint16_t ADS7843AsyncTouchScreen::fastMedian(uint16_t *samples) const { // do a fast median selection (reference code available on internet). This code basically // avoids sorting the entire samples array #define PIX_SORT(a,b) { if ((a)>(b)) PIX_SWAP((a),(b)); } #define PIX_SWAP(a,b) { uint16_t temp=(a);(a)=(b);(b)=temp; } PIX_SORT(samples[0], samples[5]) ; PIX_SORT(samples[0], samples[3]) ; PIX_SORT(samples[1], samples[6]) ; PIX_SORT(samples[2], samples[4]) ; PIX_SORT(samples[0], samples[1]) ; PIX_SORT(samples[3], samples[5]) ; PIX_SORT(samples[2], samples[6]) ; PIX_SORT(samples[2], samples[3]) ; PIX_SORT(samples[3], samples[6]) ; PIX_SORT(samples[4], samples[5]) ; PIX_SORT(samples[1], samples[4]) ; PIX_SORT(samples[1], samples[3]) ; PIX_SORT(samples[3], samples[4]) ; return samples[3]; }
/* ---------------------------------------------------------------------------- Function : PyOptMed25() In : pointer to an array of 25 pixel values Out : a pixel value Job : optimized search of the median of 25 pixel values Notice : in theory, cannot go faster without assumptions on the signal. Code taken from Graphic Gems. Code adapted from Nicolas Devillard. --------------------------------------------------------------------------- */ float PyOptMed25(float* p) { PyDoc_STRVAR(PyOptMed25__doc__, "PyOptMed25(a) -> float\n\n" "Get the median of array a of length 25 using a search tree."); PIX_SORT(p[0], p[1]); PIX_SORT(p[3], p[4]); PIX_SORT(p[2], p[4]); PIX_SORT(p[2], p[3]); PIX_SORT(p[6], p[7]); PIX_SORT(p[5], p[7]); PIX_SORT(p[5], p[6]); PIX_SORT(p[9], p[10]); PIX_SORT(p[8], p[10]); PIX_SORT(p[8], p[9]); PIX_SORT(p[12], p[13]); PIX_SORT(p[11], p[13]); PIX_SORT(p[11], p[12]); PIX_SORT(p[15], p[16]); PIX_SORT(p[14], p[16]); PIX_SORT(p[14], p[15]); PIX_SORT(p[18], p[19]); PIX_SORT(p[17], p[19]); PIX_SORT(p[17], p[18]); PIX_SORT(p[21], p[22]); PIX_SORT(p[20], p[22]); PIX_SORT(p[20], p[21]); PIX_SORT(p[23], p[24]); PIX_SORT(p[2], p[5]); PIX_SORT(p[3], p[6]); PIX_SORT(p[0], p[6]); PIX_SORT(p[0], p[3]); PIX_SORT(p[4], p[7]); PIX_SORT(p[1], p[7]); PIX_SORT(p[1], p[4]); PIX_SORT(p[11], p[14]); PIX_SORT(p[8], p[14]); PIX_SORT(p[8], p[11]); PIX_SORT(p[12], p[15]); PIX_SORT(p[9], p[15]); PIX_SORT(p[9], p[12]); PIX_SORT(p[13], p[16]); PIX_SORT(p[10], p[16]); PIX_SORT(p[10], p[13]); PIX_SORT(p[20], p[23]); PIX_SORT(p[17], p[23]); PIX_SORT(p[17], p[20]); PIX_SORT(p[21], p[24]); PIX_SORT(p[18], p[24]); PIX_SORT(p[18], p[21]); PIX_SORT(p[19], p[22]); PIX_SORT(p[8], p[17]); PIX_SORT(p[9], p[18]); PIX_SORT(p[0], p[18]); PIX_SORT(p[0], p[9]); PIX_SORT(p[10], p[19]); PIX_SORT(p[1], p[19]); PIX_SORT(p[1], p[10]); PIX_SORT(p[11], p[20]); PIX_SORT(p[2], p[20]); PIX_SORT(p[2], p[11]); PIX_SORT(p[12], p[21]); PIX_SORT(p[3], p[21]); PIX_SORT(p[3], p[12]); PIX_SORT(p[13], p[22]); PIX_SORT(p[4], p[22]); PIX_SORT(p[4], p[13]); PIX_SORT(p[14], p[23]); PIX_SORT(p[5], p[23]); PIX_SORT(p[5], p[14]); PIX_SORT(p[15], p[24]); PIX_SORT(p[6], p[24]); PIX_SORT(p[6], p[15]); PIX_SORT(p[7], p[16]); PIX_SORT(p[7], p[19]); PIX_SORT(p[13], p[21]); PIX_SORT(p[15], p[23]); PIX_SORT(p[7], p[13]); PIX_SORT(p[7], p[15]); PIX_SORT(p[1], p[9]); PIX_SORT(p[3], p[11]); PIX_SORT(p[5], p[17]); PIX_SORT(p[11], p[17]); PIX_SORT(p[9], p[17]); PIX_SORT(p[4], p[10]); PIX_SORT(p[6], p[12]); PIX_SORT(p[7], p[14]); PIX_SORT(p[4], p[6]); PIX_SORT(p[4], p[7]); PIX_SORT(p[12], p[14]); PIX_SORT(p[10], p[14]); PIX_SORT(p[6], p[7]); PIX_SORT(p[10], p[12]); PIX_SORT(p[6], p[10]); PIX_SORT(p[6], p[17]); PIX_SORT(p[12], p[17]); PIX_SORT(p[7], p[17]); PIX_SORT(p[7], p[10]); PIX_SORT(p[12], p[18]); PIX_SORT(p[7], p[12]); PIX_SORT(p[10], p[18]); PIX_SORT(p[12], p[20]); PIX_SORT(p[10], p[20]); PIX_SORT(p[10], p[12]); return p[12]; }
/* ---------------------------------------------------------------------------- Function : PyOptMed9() In : pointer to an array of 9 pixel values Out : a pixel value Job : optimized search of the median of 9 pixel values Notice : in theory, cannot go faster without assumptions on the signal. Formula from: XILINX XCELL magazine, vol. 23 by John L. Smith The input array is modified in the process The result array is guaranteed to contain the median value in middle position, but other elements are NOT sorted. Code adapted from Nicolas Devillard. --------------------------------------------------------------------------- */ float PyOptMed9(float* p) { PyDoc_STRVAR(PyOptMed9__doc__, "PyOptMed9(a) -> float\n\n" "Get the median of array a of length 9 using a search tree."); PIX_SORT(p[1], p[2]); PIX_SORT(p[4], p[5]); PIX_SORT(p[7], p[8]); PIX_SORT(p[0], p[1]); PIX_SORT(p[3], p[4]); PIX_SORT(p[6], p[7]); PIX_SORT(p[1], p[2]); PIX_SORT(p[4], p[5]); PIX_SORT(p[7], p[8]); PIX_SORT(p[0], p[3]); PIX_SORT(p[5], p[8]); PIX_SORT(p[4], p[7]); PIX_SORT(p[3], p[6]); PIX_SORT(p[1], p[4]); PIX_SORT(p[2], p[5]); PIX_SORT(p[4], p[7]); PIX_SORT(p[4], p[2]); PIX_SORT(p[6], p[4]); PIX_SORT(p[4], p[2]); return p[4]; }
int opt_med9(){ PIX_SORT(p[1], p[2]) ; PIX_SORT(p[4], p[5]) ; PIX_SORT(p[7], p[8]) ; PIX_SORT(p[0], p[1]) ; PIX_SORT(p[3], p[4]) ; PIX_SORT(p[6], p[7]) ; PIX_SORT(p[1], p[2]) ; PIX_SORT(p[4], p[5]) ; PIX_SORT(p[7], p[8]) ; PIX_SORT(p[0], p[3]) ; PIX_SORT(p[5], p[8]) ; PIX_SORT(p[4], p[7]) ; PIX_SORT(p[3], p[6]) ; PIX_SORT(p[1], p[4]) ; PIX_SORT(p[2], p[5]) ; PIX_SORT(p[4], p[7]) ; PIX_SORT(p[4], p[2]) ; PIX_SORT(p[6], p[4]) ; PIX_SORT(p[4], p[2]) ; return(p[4]) ; }
/** \fn doLine */ uint8_t AVDMFastVideoMedian::doLine(uint8_t *pred, uint8_t *cur, uint8_t *next, uint8_t *out, uint32_t w) { uint8_t a1,a2,a3; uint8_t b1,b2,b3; uint8_t c1,c2,c3; //,i; //int32_t o; uint8_t temp; static uint8_t tab[9]; a2=*pred++;a3=*pred++; b2=*cur++;b3=*cur++; c2=*next++;c3=*next++; *out++=b2; w--; while(w>1) { tab[0]=a1=a2; tab[1]=a2=a3; tab[2]=a3=*pred++; tab[3]=b1=b2; tab[4]=b2=b3; tab[5]=b3=*cur++; tab[6]=c1=c2; tab[7]=c2=c3; tab[8]=c3=*next++; #define PIX_SORT(a,b) { if ((a)>(b)) PIX_SWAP((a),(b)); } #define PIX_SWAP(a,b) { temp=(a);(a)=(b);(b)=temp; } uint8_t *p=(uint8_t *)tab; PIX_SORT(p[1], p[2]) ; PIX_SORT(p[4], p[5]) ; PIX_SORT(p[7], p[8]) ; PIX_SORT(p[0], p[1]) ; PIX_SORT(p[3], p[4]) ; PIX_SORT(p[6], p[7]) ; PIX_SORT(p[1], p[2]) ; PIX_SORT(p[4], p[5]) ; PIX_SORT(p[7], p[8]) ; PIX_SORT(p[0], p[3]) ; PIX_SORT(p[5], p[8]) ; PIX_SORT(p[4], p[7]) ; PIX_SORT(p[3], p[6]) ; PIX_SORT(p[1], p[4]) ; PIX_SORT(p[2], p[5]) ; PIX_SORT(p[4], p[7]) ; PIX_SORT(p[4], p[2]) ; PIX_SORT(p[6], p[4]) ; PIX_SORT(p[4], p[2]) ; *out++=tab[4]; w--; } *out++=b3; return 1; }
void CLASS lmmse_interpolate(int gamma_apply) { ushort (*pix)[4]; int row, col, c, d, w1, w2, w3, w4, ii, ba, rr1, cc1, rr, cc, pass; float h0, h1, h2, h3, h4, hs; float p1, p2, p3, p4, p5, p6, p7, p8, p9, temp; float Y, v0, mu, vx, vn, xh, vh, xv, vv; float (*rix)[6], (*qix)[6]; float (*glut); char *buffer; clock_t t1, t2; double dt; #ifdef DCRAW_VERBOSE if (verbose) fprintf(stderr,_("LMMSE interpolation...\n")); #endif t1 = clock(); // allocate work with boundary ba = 10; rr1 = height + 2*ba; cc1 = width + 2*ba; if (gamma_apply) buffer = (char *)calloc(rr1*cc1*6*sizeof(float)+65536*sizeof(float),1); else buffer = (char *)calloc(rr1*cc1*6*sizeof(float),1); merror(buffer,"lmmse_interpolate()"); qix = (float (*)[6])buffer; if (gamma_apply) { glut = (float *)(buffer + rr1*cc1*24); for (ii=0; ii < 65536; ii++) { v0 = (float)ii / 65535.0; if (v0 <= 0.0031308) glut[ii] = v0*12.92; else glut[ii] = 1.055*pow((double)v0,1./2.4) - 0.055; } } // indices w1 = cc1; w2 = 2*w1; w3 = 3*w1; w4 = 4*w1; // define low pass filter (sigma=2, L=4) h0 = 1.0; h1 = exp( -1.0/8.0); h2 = exp( -4.0/8.0); h3 = exp( -9.0/8.0); h4 = exp(-16.0/8.0); hs = h0 + 2.0*(h1 + h2 + h3 + h4); h0 /= hs; h1 /= hs; h2 /= hs; h3 /= hs; h4 /= hs; // copy CFA values for (rr=0; rr < rr1; rr++) for (cc=0, row=rr-ba; cc < cc1; cc++) { col = cc - ba; rix = qix + rr*cc1 + cc; if ((row >= 0) & (row < height) & (col >= 0) & (col < width)) if (gamma_apply) rix[0][4] = glut[image[row*width+col][FC(row,col)]]; else rix[0][4] = (double)image[row*width+col][FC(row,col)]/65535.0; else rix[0][4] = 0; } // G-R(B) for (rr=2; rr < rr1-2; rr++) { // G-R(B) at R(B) location for (cc=2+(FC(rr,2)&1); cc < cc1-2; cc+=2) { rix = qix + rr*cc1 + cc; // v0 = 0.25R + 0.25B, Y = 0.25R + 0.5B + 0.25B v0 = 0.0625*(rix[-w1-1][4]+rix[-w1+1][4]+rix[w1-1][4]+rix[w1+1][4]) + 0.25*rix[0][4]; // horizontal rix[0][0] = -0.25*(rix[ -2][4] + rix[ 2][4]) + 0.5*(rix[ -1][4] + rix[0][4] + rix[ 1][4]); Y = v0 + 0.5*rix[0][0]; if (rix[0][4] > 1.75*Y) rix[0][0] = ULIM(rix[0][0],rix[ -1][4],rix[ 1][4]); else rix[0][0] = LIM(rix[0][0],0.0,1.0); rix[0][0] -= rix[0][4]; // vertical rix[0][1] = -0.25*(rix[-w2][4] + rix[w2][4]) + 0.5*(rix[-w1][4] + rix[0][4] + rix[w1][4]); Y = v0 + 0.5*rix[0][1]; if (rix[0][4] > 1.75*Y) rix[0][1] = ULIM(rix[0][1],rix[-w1][4],rix[w1][4]); else rix[0][1] = LIM(rix[0][1],0.0,1.0); rix[0][1] -= rix[0][4]; } // G-R(B) at G location for (cc=2+(FC(rr,3)&1); cc < cc1-2; cc+=2) { rix = qix + rr*cc1 + cc; rix[0][0] = 0.25*(rix[ -2][4] + rix[ 2][4]) - 0.5*(rix[ -1][4] + rix[0][4] + rix[ 1][4]); rix[0][1] = 0.25*(rix[-w2][4] + rix[w2][4]) - 0.5*(rix[-w1][4] + rix[0][4] + rix[w1][4]); rix[0][0] = LIM(rix[0][0],-1.0,0.0) + rix[0][4]; rix[0][1] = LIM(rix[0][1],-1.0,0.0) + rix[0][4]; } } // apply low pass filter on differential colors for (rr=4; rr < rr1-4; rr++) for (cc=4; cc < cc1-4; cc++) { rix = qix + rr*cc1 + cc; rix[0][2] = h0*rix[0][0] + h1*(rix[ -1][0] + rix[ 1][0]) + h2*(rix[ -2][0] + rix[ 2][0]) + h3*(rix[ -3][0] + rix[ 3][0]) + h4*(rix[ -4][0] + rix[ 4][0]); rix[0][3] = h0*rix[0][1] + h1*(rix[-w1][1] + rix[w1][1]) + h2*(rix[-w2][1] + rix[w2][1]) + h3*(rix[-w3][1] + rix[w3][1]) + h4*(rix[-w4][1] + rix[w4][1]); } // interpolate G-R(B) at R(B) for (rr=4; rr < rr1-4; rr++) for (cc=4+(FC(rr,4)&1); cc < cc1-4; cc+=2) { rix = qix + rr*cc1 + cc; // horizontal mu = (rix[-4][2] + rix[-3][2] + rix[-2][2] + rix[-1][2] + rix[0][2]+ rix[ 1][2] + rix[ 2][2] + rix[ 3][2] + rix[ 4][2]) / 9.0; p1 = rix[-4][2] - mu; p2 = rix[-3][2] - mu; p3 = rix[-2][2] - mu; p4 = rix[-1][2] - mu; p5 = rix[ 0][2] - mu; p6 = rix[ 1][2] - mu; p7 = rix[ 2][2] - mu; p8 = rix[ 3][2] - mu; p9 = rix[ 4][2] - mu; vx = 1e-7+p1*p1+p2*p2+p3*p3+p4*p4+p5*p5+p6*p6+p7*p7+p8*p8+p9*p9; p1 = rix[-4][0] - rix[-4][2]; p2 = rix[-3][0] - rix[-3][2]; p3 = rix[-2][0] - rix[-2][2]; p4 = rix[-1][0] - rix[-1][2]; p5 = rix[ 0][0] - rix[ 0][2]; p6 = rix[ 1][0] - rix[ 1][2]; p7 = rix[ 2][0] - rix[ 2][2]; p8 = rix[ 3][0] - rix[ 3][2]; p9 = rix[ 4][0] - rix[ 4][2]; vn = 1e-7+p1*p1+p2*p2+p3*p3+p4*p4+p5*p5+p6*p6+p7*p7+p8*p8+p9*p9; xh = (rix[0][0]*vx + rix[0][2]*vn)/(vx + vn); vh = vx*vn/(vx + vn); // vertical mu = (rix[-w4][3] + rix[-w3][3] + rix[-w2][3] + rix[-w1][3] + rix[0][3]+ rix[ w1][3] + rix[ w2][3] + rix[ w3][3] + rix[ w4][3]) / 9.0; p1 = rix[-w4][3] - mu; p2 = rix[-w3][3] - mu; p3 = rix[-w2][3] - mu; p4 = rix[-w1][3] - mu; p5 = rix[ 0][3] - mu; p6 = rix[ w1][3] - mu; p7 = rix[ w2][3] - mu; p8 = rix[ w3][3] - mu; p9 = rix[ w4][3] - mu; vx = 1e-7+p1*p1+p2*p2+p3*p3+p4*p4+p5*p5+p6*p6+p7*p7+p8*p8+p9*p9; p1 = rix[-w4][1] - rix[-w4][3]; p2 = rix[-w3][1] - rix[-w3][3]; p3 = rix[-w2][1] - rix[-w2][3]; p4 = rix[-w1][1] - rix[-w1][3]; p5 = rix[ 0][1] - rix[ 0][3]; p6 = rix[ w1][1] - rix[ w1][3]; p7 = rix[ w2][1] - rix[ w2][3]; p8 = rix[ w3][1] - rix[ w3][3]; p9 = rix[ w4][1] - rix[ w4][3]; vn = 1e-7+p1*p1+p2*p2+p3*p3+p4*p4+p5*p5+p6*p6+p7*p7+p8*p8+p9*p9; xv = (rix[0][1]*vx + rix[0][3]*vn)/(vx + vn); vv = vx*vn/(vx + vn); // interpolated G-R(B) rix[0][4] = (xh*vv + xv*vh)/(vh + vv); } // copy CFA values for (rr=0; rr < rr1; rr++) for (cc=0, row=rr-ba; cc < cc1; cc++) { col=cc-ba; rix = qix + rr*cc1 + cc; c = FC(rr,cc); if ((row >= 0) & (row < height) & (col >= 0) & (col < width)) if (gamma_apply) rix[0][c] = glut[image[row*width+col][c]]; else rix[0][c] = (double)image[row*width+col][c]/65535.0; else rix[0][c] = 0; if (c != 1) rix[0][1] = rix[0][c] + rix[0][4]; } // bilinear interpolation for R/B // interpolate R/B at G location for (rr=1; rr < rr1-1; rr++) for (cc=1+(FC(rr,2)&1), c=FC(rr,cc+1); cc < cc1-1; cc+=2) { rix = qix + rr*cc1 + cc; rix[0][c] = rix[0][1] + 0.5*(rix[ -1][c] - rix[ -1][1] + rix[ 1][c] - rix[ 1][1]); c = 2 - c; rix[0][c] = rix[0][1] + 0.5*(rix[-w1][c] - rix[-w1][1] + rix[w1][c] - rix[w1][1]); c = 2 - c; } // interpolate R/B at B/R location for (rr=1; rr < rr1-1; rr++) for (cc=1+(FC(rr,1)&1), c=2-FC(rr,cc); cc < cc1-1; cc+=2) { rix = qix + rr*cc1 + cc; rix[0][c] = rix[0][1] + 0.25*(rix[-w1][c] - rix[-w1][1] + rix[ -1][c] - rix[ -1][1]+ rix[ 1][c] - rix[ 1][1] + rix[ w1][c] - rix[ w1][1]); } // median filter for (pass=1; pass <= 3; pass++) { for (c=0; c < 3; c+=2) { // Compute median(R-G) and median(B-G) d = c + 3; for (ii=0; ii < rr1*cc1; ii++) qix[ii][d] = qix[ii][c] - qix[ii][1]; // Apply 3x3 median fileter for (rr=1; rr < rr1-1; rr++) for (cc=1; cc < cc1-1; cc++) { rix = qix + rr*cc1 + cc; // Assign 3x3 differential color values p1 = rix[-w1-1][d]; p2 = rix[-w1][d]; p3 = rix[-w1+1][d]; p4 = rix[ -1][d]; p5 = rix[ 0][d]; p6 = rix[ 1][d]; p7 = rix[ w1-1][d]; p8 = rix[ w1][d]; p9 = rix[ w1+1][d]; // Sort for median of 9 values PIX_SORT(p2,p3); PIX_SORT(p5,p6); PIX_SORT(p8,p9); PIX_SORT(p1,p2); PIX_SORT(p4,p5); PIX_SORT(p7,p8); PIX_SORT(p2,p3); PIX_SORT(p5,p6); PIX_SORT(p8,p9); PIX_SORT(p1,p4); PIX_SORT(p6,p9); PIX_SORT(p5,p8); PIX_SORT(p4,p7); PIX_SORT(p2,p5); PIX_SORT(p3,p6); PIX_SORT(p5,p8); PIX_SORT(p5,p3); PIX_SORT(p7,p5); PIX_SORT(p5,p3); rix[0][4] = p5; } for (ii=0; ii < rr1*cc1; ii++) qix[ii][d] = qix[ii][4]; } // red/blue at GREEN pixel locations for (rr=0; rr < rr1; rr++) for (cc=(FC(rr,1)&1), c=FC(rr,cc+1); cc < cc1; cc+=2) { rix = qix + rr*cc1 + cc; rix[0][0] = rix[0][1] + rix[0][3]; rix[0][2] = rix[0][1] + rix[0][5]; } // red/blue and green at BLUE/RED pixel locations for (rr=0; rr < rr1; rr++) for (cc=(FC(rr,0)&1), c=2-FC(rr,cc), d=c+3; cc < cc1; cc+=2) { rix = qix + rr*cc1 + cc; rix[0][c] = rix[0][1] + rix[0][d]; rix[0][1] = 0.5*(rix[0][0] - rix[0][3] + rix[0][2] - rix[0][5]); } } // copy result back to image matrix for (row=0; row < height; row++) for (col=0, rr=row+ba; col < width; col++) { cc = col+ba; pix = image + row*width + col; rix = qix + rr*cc1 + cc; c = FC(row,col); if (gamma_apply) { for (ii=0; ii < 3; ii++) if (ii != c) { v0 = rix[0][ii]; if (v0 <= 0.04045) v0 /= 12.92; else v0 = pow((v0 + 0.055)/1.055,2.4); pix[0][ii] = CLIP((int)(65535.0*v0 + 0.5)); } } else for (ii=0; ii < 3; ii++) if (ii != c) pix[0][ii] = CLIP((int)(65535.0*rix[0][ii] + 0.5)); } // Done free(buffer); t2 = clock(); dt = ((double)(t2-t1)) / CLOCKS_PER_SEC; #ifdef DCRAW_VERBOSE if (verbose) fprintf(stderr,_("\telapsed time = %5.3fs\n"),dt); #endif }
static inline int median9(int *p) { PIX_SORT(p[1], p[2]) ; PIX_SORT(p[4], p[5]) ; PIX_SORT(p[7], p[8]) ; PIX_SORT(p[0], p[1]) ; PIX_SORT(p[3], p[4]) ; PIX_SORT(p[6], p[7]) ; PIX_SORT(p[1], p[2]) ; PIX_SORT(p[4], p[5]) ; PIX_SORT(p[7], p[8]) ; PIX_SORT(p[0], p[3]) ; PIX_SORT(p[5], p[8]) ; PIX_SORT(p[4], p[7]) ; PIX_SORT(p[3], p[6]) ; PIX_SORT(p[1], p[4]) ; PIX_SORT(p[2], p[5]) ; PIX_SORT(p[4], p[7]) ; PIX_SORT(p[4], p[2]) ; PIX_SORT(p[6], p[4]) ; PIX_SORT(p[4], p[2]) ; return(p[4]) ; }