Пример #1
0
/* ----------------------------------------------------------------------------
 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];
}
Пример #2
0
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];
  }
}
Пример #4
0
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];
}
Пример #7
0
/* ----------------------------------------------------------------------------
 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];
}
Пример #8
0
/* ----------------------------------------------------------------------------
 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];
}
Пример #9
0
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]) ;
}
Пример #10
0
/**
    \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;
}
Пример #11
0
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
}
Пример #12
0
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]) ;
}