⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 dc1394_bayer.c

📁 This library provides functionality to control any camera that conforms to the 1394-Based Digital C
💻 C
📖 第 1 页 / 共 5 页
字号:
	    for (j = 1; j < sx - 1; j += 2) {		base = i * sx + j;		tmp = ((bayer[base] + bayer[base + 1 + sx]) >> 1);		CLIP16(tmp, outG[(base) * 3], bits);		tmp = bayer[base + sx];		CLIP16(tmp, outR[(base) * 3], bits);		tmp = bayer[base + 1];		CLIP16(tmp, outB[(base) * 3], bits);	    }	}	break;    case DC1394_COLOR_FILTER_BGGR:	//---------------------------------------------------------    case DC1394_COLOR_FILTER_RGGB:	for (i = 0; i < sy - 1; i += 2) {	    for (j = 0; j < sx - 1; j += 2) {		base = i * sx + j;		tmp = ((bayer[base + sx] + bayer[base + 1]) >> 1);		CLIP16(tmp, outG[base * 3], bits);		tmp = bayer[base + sx + 1];		CLIP16(tmp, outR[base * 3], bits);		tmp = bayer[base];		CLIP16(tmp, outB[base * 3], bits);	    }	}	for (i = 1; i < sy - 1; i += 2) {	    for (j = 0; j < sx - 1; j += 2) {		base = i * sx + j;		tmp = ((bayer[base] + bayer[base + 1 + sx]) >> 1);		CLIP16(tmp, outG[(base) * 3], bits);		tmp = bayer[base + 1];		CLIP16(tmp, outR[(base) * 3], bits);		tmp = bayer[base + sx];		CLIP16(tmp, outB[(base) * 3], bits);	    }	}	for (i = 0; i < sy - 1; i += 2) {	    for (j = 1; j < sx - 1; j += 2) {		base = i * sx + j;		tmp = ((bayer[base] + bayer[base + sx + 1]) >> 1);		CLIP16(tmp, outG[base * 3], bits);		tmp = bayer[base + sx];		CLIP16(tmp, outR[base * 3], bits);		tmp = bayer[base + 1];		CLIP16(tmp, outB[base * 3], bits);	    }	}	for (i = 1; i < sy - 1; i += 2) {	    for (j = 1; j < sx - 1; j += 2) {		base = i * sx + j;		tmp = ((bayer[base + 1] + bayer[base + sx]) >> 1);		CLIP16(tmp, outG[(base) * 3], bits);		tmp = bayer[base];		CLIP16(tmp, outR[(base) * 3], bits);		tmp = bayer[base + 1 + sx];		CLIP16(tmp, outB[(base) * 3], bits);	    }	}	break;    default:			//---------------------------------------------------------	fprintf(stderr, "Bad bayer pattern ID: %d\n", tile);	return;	break;    }    /* add black border */    for (i = sx * (sy - 1) * 3; i < sx * sy * 3; i++) {	rgb[i] = 0;    }    for (i = (sx - 1) * 3; i < sx * sy * 3; i += (sx - 1) * 3) {	rgb[i++] = 0;	rgb[i++] = 0;	rgb[i++] = 0;    }}/* Variable Number of Gradients, from dcraw <http://www.cybercom.net/~dcoffin/dcraw/> *//* Ported to libdc1394 by Frederic Devernay */#define ABS(x) (((int)(x) ^ ((int)(x) >> 31)) - ((int)(x) >> 31))/*   In order to inline this calculation, I make the risky   assumption that all filter patterns can be described   by a repeating pattern of eight rows and two columns   Return values are either 0/1/2/3 = G/M/C/Y or 0/1/2/3 = R/G1/B/G2 */#define FC(row,col) \	(filters >> ((((row) << 1 & 14) + ((col) & 1)) << 1) & 3)/*   This algorithm is officially called:   "Interpolation using a Threshold-based variable number of gradients"   described in http://www-ise.stanford.edu/~tingchen/algodep/vargra.html   I've extended the basic idea to work with non-Bayer filter arrays.   Gradients are numbered clockwise from NW=0 to W=7. */static const signed char bayervng_terms[] = {    -2,-2,+0,-1,0,0x01, -2,-2,+0,+0,1,0x01, -2,-1,-1,+0,0,0x01,    -2,-1,+0,-1,0,0x02, -2,-1,+0,+0,0,0x03, -2,-1,+0,+1,1,0x01,    -2,+0,+0,-1,0,0x06, -2,+0,+0,+0,1,0x02, -2,+0,+0,+1,0,0x03,    -2,+1,-1,+0,0,0x04, -2,+1,+0,-1,1,0x04, -2,+1,+0,+0,0,0x06,    -2,+1,+0,+1,0,0x02, -2,+2,+0,+0,1,0x04, -2,+2,+0,+1,0,0x04,    -1,-2,-1,+0,0,0x80, -1,-2,+0,-1,0,0x01, -1,-2,+1,-1,0,0x01,    -1,-2,+1,+0,1,0x01, -1,-1,-1,+1,0,0x88, -1,-1,+1,-2,0,0x40,    -1,-1,+1,-1,0,0x22, -1,-1,+1,+0,0,0x33, -1,-1,+1,+1,1,0x11,    -1,+0,-1,+2,0,0x08, -1,+0,+0,-1,0,0x44, -1,+0,+0,+1,0,0x11,    -1,+0,+1,-2,1,0x40, -1,+0,+1,-1,0,0x66, -1,+0,+1,+0,1,0x22,    -1,+0,+1,+1,0,0x33, -1,+0,+1,+2,1,0x10, -1,+1,+1,-1,1,0x44,    -1,+1,+1,+0,0,0x66, -1,+1,+1,+1,0,0x22, -1,+1,+1,+2,0,0x10,    -1,+2,+0,+1,0,0x04, -1,+2,+1,+0,1,0x04, -1,+2,+1,+1,0,0x04,    +0,-2,+0,+0,1,0x80, +0,-1,+0,+1,1,0x88, +0,-1,+1,-2,0,0x40,    +0,-1,+1,+0,0,0x11, +0,-1,+2,-2,0,0x40, +0,-1,+2,-1,0,0x20,    +0,-1,+2,+0,0,0x30, +0,-1,+2,+1,1,0x10, +0,+0,+0,+2,1,0x08,    +0,+0,+2,-2,1,0x40, +0,+0,+2,-1,0,0x60, +0,+0,+2,+0,1,0x20,    +0,+0,+2,+1,0,0x30, +0,+0,+2,+2,1,0x10, +0,+1,+1,+0,0,0x44,    +0,+1,+1,+2,0,0x10, +0,+1,+2,-1,1,0x40, +0,+1,+2,+0,0,0x60,    +0,+1,+2,+1,0,0x20, +0,+1,+2,+2,0,0x10, +1,-2,+1,+0,0,0x80,    +1,-1,+1,+1,0,0x88, +1,+0,+1,+2,0,0x08, +1,+0,+2,-1,0,0x40,    +1,+0,+2,+1,0,0x10}, bayervng_chood[] = { -1,-1, -1,0, -1,+1, 0,+1, +1,+1, +1,0, +1,-1, 0,-1 };static voiddc1394_bayer_VNG(const uint8_t *restrict bayer,		 uint8_t *restrict dst, int sx, int sy,		 dc1394color_filter_t pattern){  const int height = sy, width = sx;  static const signed char *cp;  /* the following has the same type as the image */  uint8_t (*brow[5])[3], *pix;          /* [FD] */  int code[8][2][320], *ip, gval[8], gmin, gmax, sum[4];  int row, col, x, y, x1, x2, y1, y2, t, weight, grads, color, diag;  int g, diff, thold, num, c;  uint32_t filters;                     /* [FD] */    /* first, use bilinear bayer decoding */  dc1394_bayer_Bilinear(bayer, dst, sx, sy, pattern);  switch(pattern) {      case DC1394_COLOR_FILTER_BGGR:          filters = 0x16161616;          break;      case DC1394_COLOR_FILTER_GRBG:          filters = 0x61616161;          break;      case DC1394_COLOR_FILTER_RGGB:          filters = 0x94949494;          break;      case DC1394_COLOR_FILTER_GBRG:          filters = 0x49494949;          break;      default:          return;  }        for (row=0; row < 8; row++) {		/* Precalculate for VNG */    for (col=0; col < 2; col++) {      ip = code[row][col];      for (cp=bayervng_terms, t=0; t < 64; t++) {	y1 = *cp++;  x1 = *cp++;	y2 = *cp++;  x2 = *cp++;	weight = *cp++;	grads = *cp++;	color = FC(row+y1,col+x1);	if (FC(row+y2,col+x2) != color) continue;	diag = (FC(row,col+1) == color && FC(row+1,col) == color) ? 2:1;	if (abs(y1-y2) == diag && abs(x1-x2) == diag) continue;	*ip++ = (y1*width + x1)*3 + color; /* [FD] */	*ip++ = (y2*width + x2)*3 + color; /* [FD] */	*ip++ = weight;	for (g=0; g < 8; g++)	  if (grads & 1<<g) *ip++ = g;	*ip++ = -1;      }      *ip++ = INT_MAX;      for (cp=bayervng_chood, g=0; g < 8; g++) {	y = *cp++;  x = *cp++;	*ip++ = (y*width + x) * 3;      /* [FD] */	color = FC(row,col);	if (FC(row+y,col+x) != color && FC(row+y*2,col+x*2) == color)	  *ip++ = (y*width + x) * 6 + color; /* [FD] */	else	  *ip++ = 0;      }    }  }  brow[4] = calloc (width*3, sizeof **brow);  //merror (brow[4], "vng_interpolate()");  for (row=0; row < 3; row++)    brow[row] = brow[4] + row*width;  for (row=2; row < height-2; row++) {		/* Do VNG interpolation */    for (col=2; col < width-2; col++) {        pix = dst + (row*width+col)*3;  /* [FD] */      ip = code[row & 7][col & 1];      memset (gval, 0, sizeof gval);      while ((g = ip[0]) != INT_MAX) {		/* Calculate gradients */	diff = ABS(pix[g] - pix[ip[1]]) << ip[2];	gval[ip[3]] += diff;	ip += 5;	if ((g = ip[-1]) == -1) continue;	gval[g] += diff;	while ((g = *ip++) != -1)	  gval[g] += diff;      }      ip++;      gmin = gmax = gval[0];			/* Choose a threshold */      for (g=1; g < 8; g++) {	if (gmin > gval[g]) gmin = gval[g];	if (gmax < gval[g]) gmax = gval[g];      }      if (gmax == 0) {          memcpy (brow[2][col], pix, 3 * sizeof *dst); /* [FD] */	continue;      }      thold = gmin + (gmax >> 1);      memset (sum, 0, sizeof sum);      color = FC(row,col);      for (num=g=0; g < 8; g++,ip+=2) {		/* Average the neighbors */	if (gval[g] <= thold) {	  for (c=0; c < 3; c++)         /* [FD] */	    if (c == color && ip[1])	      sum[c] += (pix[c] + pix[ip[1]]) >> 1;	    else	      sum[c] += pix[ip[0] + c];	  num++;	}      }      for (c=0; c < 3; c++) {           /* [FD] Save to buffer */	t = pix[color];	if (c != color)	  t += (sum[c] - sum[color]) / num;	CLIP(t,brow[2][col][c]);        /* [FD] */      }    }    if (row > 3)				/* Write buffer to image */        memcpy (dst + 3*((row-2)*width+2), brow[0]+2, (width-4)*3*sizeof *dst); /* [FD] */    for (g=0; g < 4; g++)      brow[(g-1) & 3] = brow[g];  }  memcpy (dst + 3*((row-2)*width+2), brow[0]+2, (width-4)*3*sizeof *dst);  memcpy (dst + 3*((row-1)*width+2), brow[1]+2, (width-4)*3*sizeof *dst);  free (brow[4]);}static voiddc1394_bayer_VNG_uint16(const uint16_t *restrict bayer,			uint16_t *restrict dst, int sx, int sy,			dc1394color_filter_t pattern, int bits){  const int height = sy, width = sx;  static const signed char *cp;  /* the following has the same type as the image */  uint16_t (*brow[5])[3], *pix;          /* [FD] */  int code[8][2][320], *ip, gval[8], gmin, gmax, sum[4];  int row, col, x, y, x1, x2, y1, y2, t, weight, grads, color, diag;  int g, diff, thold, num, c;  uint32_t filters;                     /* [FD] */    /* first, use bilinear bayer decoding */    dc1394_bayer_Bilinear_uint16(bayer, dst, sx, sy, pattern, bits);  switch(pattern) {      case DC1394_COLOR_FILTER_BGGR:          filters = 0x16161616;          break;      case DC1394_COLOR_FILTER_GRBG:          filters = 0x61616161;          break;      case DC1394_COLOR_FILTER_RGGB:          filters = 0x94949494;          break;      case DC1394_COLOR_FILTER_GBRG:          filters = 0x49494949;          break;      default:          return;  }        for (row=0; row < 8; row++) {		/* Precalculate for VNG */    for (col=0; col < 2; col++) {      ip = code[row][col];      for (cp=bayervng_terms, t=0; t < 64; t++) {	y1 = *cp++;  x1 = *cp++;	y2 = *cp++;  x2 = *cp++;	weight = *cp++;	grads = *cp++;	color = FC(row+y1,col+x1);	if (FC(row+y2,col+x2) != color) continue;	diag = (FC(row,col+1) == color && FC(row+1,col) == color) ? 2:1;	if (abs(y1-y2) == diag && abs(x1-x2) == diag) continue;	*ip++ = (y1*width + x1)*3 + color; /* [FD] */	*ip++ = (y2*width + x2)*3 + color; /* [FD] */	*ip++ = weight;	for (g=0; g < 8; g++)	  if (grads & 1<<g) *ip++ = g;	*ip++ = -1;      }      *ip++ = INT_MAX;      for (cp=bayervng_chood, g=0; g < 8; g++) {	y = *cp++;  x = *cp++;	*ip++ = (y*width + x) * 3;      /* [FD] */	color = FC(row,col);	if (FC(row+y,col+x) != color && FC(row+y*2,col+x*2) == color)	  *ip++ = (y*width + x) * 6 + color; /* [FD] */	else	  *ip++ = 0;      }    }  }  brow[4] = calloc (width*3, sizeof **brow);  //merror (brow[4], "vng_interpolate()");  for (row=0; row < 3; row++)    brow[row] = brow[4] + row*width;  for (row=2; row < height-2; row++) {		/* Do VNG interpolation */    for (col=2; col < width-2; col++) {        pix = dst + (row*width+col)*3;  /* [FD] */      ip = code[row & 7][col & 1];      memset (gval, 0, sizeof gval);      while ((g = ip[0]) != INT_MAX) {		/* Calculate gradients */	diff = ABS(pix[g] - pix[ip[1]]) << ip[2];	gval[ip[3]] += diff;	ip += 5;	if ((g = ip[-1]) == -1) continue;	gval[g] += diff;	while ((g = *ip++) != -1)	  gval[g] += diff;      }      ip++;      gmin = gmax = gval[0];			/* Choose a threshold */      for (g=1; g < 8; g++) {	if (gmin > gval[g]) gmin = gval[g];	if (gmax < gval[g]) gmax = gval[g];      }      if (gmax == 0) {          memcpy (brow[2][col], pix, 3 * sizeof *dst); /* [FD] */	continue;      }      thold = gmin + (gmax >> 1);      memset (sum, 0, sizeof sum);      color = FC(row,col);      for (num=g=0; g < 8; g++,ip+=2) {		/* Average the neighbors */	if (gval[g] <= thold) {	  for (c=0; c < 3; c++)         /* [FD] */	    if (c == color && ip[1])	      sum[c] += (pix[c] + pix[ip[1]]) >> 1;	    else	      sum[c] += pix[ip[0] + c];	  num++;	}      }      for (c=0; c < 3; c++) {           /* [FD] Save to buffer */	t = pix[color];	if (c != color)	  t += (sum[c] - sum[color]) / num;	CLIP16(t,brow[2][col][c],bits);        /* [FD] */      }    }    if (row > 3)				/* Write buffer to image */        memcpy (dst + 3*((row-2)*width+2), brow[0]+2, (width-4)*3*sizeof *dst); /* [FD] */    for (g=0; g < 4; g++)      brow[(g-1) & 3] = brow[g];  }  memcpy (dst + 3*((row-2)*width+2), brow[0]+2, (width-4)*3*sizeof *dst);  memcpy (dst + 3*((row-1)*width+2), brow[1]+2, (width-4)*3*sizeof *dst);  free (brow[4]);}dc1394error_tdc1394_bayer_decoding_8bit(const uchar_t *restrict bayer, uchar_t *restrict rgb, uint_t sx, uint_t sy, uint_t tile, uint_t method){  switch (method) {  case DC1394_BAYER_METHOD_NEAREST:    dc1394_bayer_NearestNeighbor(bayer, rgb, sx, sy, tile);    return DC1394_SUCCESS;  case DC1394_BAYER_METHOD_SIMPLE:    dc1394_bayer_Simple(bayer, rgb, sx, sy, tile);    return DC1394_SUCCESS;  case DC1394_BAYER_METHOD_BILINEAR:    dc1394_bayer_Bilinear(bayer, rgb, sx, sy, tile);    return DC1394_SUCCESS;  case DC1394_BAYER_METHOD_HQLINEAR:    dc1394_bayer_HQLinear(bayer, rgb, sx, sy, tile);    return DC1394_SUCCESS;  case DC1394_BAYER_METHOD_DOWNSAMPLE:    dc1394_bayer_Downsample(bayer, rgb, sx, sy, tile);    return DC1394_SUCCESS;  case DC1394_BAYER_METHOD_EDGESENSE:    dc1394_bayer_EdgeSense(bayer, rgb, sx, sy, tile);    return DC1394_SUCCESS;  case DC1394_BAYER_METHOD_VNG:    dc1394_bayer_VNG(bayer, rgb, sx, sy, tile);    return DC1394_SUCCESS;  }  return DC1394_INVALID_BAYER_METHOD;}dc1394error_tdc1394_bayer_decoding_16bit(const uint16_t *restrict bayer, uint16_t *restrict rgb, uint_t sx, uint_t sy, uint_t tile, uint_t bits, uint_t method){  switch (method) {  case DC1394_BAYER_METHOD_NEAREST:    dc1394_bayer_NearestNeighbor_uint16(bayer, rgb, sx, sy, tile, bits);    return DC1394_SUCCESS;  case DC1394_BAYER_METHOD_SIMPLE:    dc1394_bayer_Simple_uint16(bayer, rgb, sx, sy, tile, bits);    return DC1394_SUCCESS;  case DC1394_BAYER_METHOD_BILINEAR:    dc1394_bayer_Bilinear_uint16(bayer, rgb, sx, sy, tile, bits);    return DC1394_SUCCESS;  case DC1394_BAYER_METHOD_HQLINEAR:    dc1394_bayer_HQLinear_uint16(bayer, rgb, sx, sy, tile, bits);    return DC1394_SUCCESS;  case DC1394_BAYER_METHOD_DOWNSAMPLE:    dc1394_bayer_Downsample_uint16(bayer, rgb, sx, sy, tile, bits);    return DC1394_SUCCESS;  case DC1394_BAYER_METHOD_EDGESENSE:    dc1394_bayer_EdgeSense_uint16(bayer, rgb, sx, sy, tile, bits);    return DC1394_SUCCESS;  case DC1394_BAYER_METHOD_VNG:    dc1394_bayer_VNG_uint16(bayer, rgb, sx, sy, tile, bits);    return DC1394_SUCCESS;  }  return DC1394_INVALID_BAYER_METHOD;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -