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

📄 cam_test.c

📁 这是一个用c语言编写的摄像头驱动程序
💻 C
字号:
#include <stdio.h>#include <stdlib.h>#include <string.h>#include <getopt.h>#include <sys/types.h>#include <sys/stat.h>#include <sys/ioctl.h>#include <sys/mman.h>#include <sys/time.h>	/* gettimeofday() */#include <fcntl.h>#include <unistd.h>#include <linux/types.h>#include "/usr/include/jpeglib.h"/*#define	YCbCrtoR(Y,Cb,Cr)	(Y + 1.402*(Cr-128))
#define YCbCrtoG(Y,Cb,Cr)	(Y - 0.34414*(Cb-128) - 0.71414*(Cr-128))
#define	YCbCrtoB(Y,Cb,Cr)	(Y + 1.772*(Cb-128))*//*#define	YCbCrtoR(Y,Cb,Cr)	(1000*Y + 1371*(Cr-128))/1000
#define YCbCrtoG(Y,Cb,Cr)	(1000*Y - 336*(Cb-128) - 698*(Cr-128))/1000
#define	YCbCrtoB(Y,Cb,Cr)	(1000*Y + 1732*(Cb-128))/1000
*/#define YCbCrtoR(Y,U,V)		1.164 * (Y - 16) + 2.018 * (U - 128)#define YCbCrtoG(Y,U,V)		1.164 * (Y - 16) - 0.38 * (U - 128) - 0.813 * (V - 128)#define YCbCrtoB(Y,U,V) 	1.164 * (Y - 16) + 1.159 * (V - 128)
#define CAMDEVICE "/dev/video" #define LIMIT(x) ((x)>0xffffff?0xff: ((x)<=0xffff?0:((x)>>16)))static inline voidv4l_copy_422_block (int yTL, int yTR, int u, int v, 	int rowPixels, unsigned char * rgb, int bits){	const int rvScale = 91881;	const int guScale = -22553;	const int gvScale = -46801;	const int buScale = 116129;	const int yScale  = 65536;	int r, g, b;	g = guScale * u + gvScale * v;	r = rvScale * v;	b = buScale * u;	yTL *= yScale; yTR *= yScale;	if (bits == 24) {		/* Write out top two pixels */		rgb[0] = LIMIT(b+yTL); rgb[1] = LIMIT(g+yTL); rgb[2] = LIMIT(r+yTL);		rgb[3] = LIMIT(b+yTR); rgb[4] = LIMIT(g+yTR); rgb[5] = LIMIT(r+yTR);	} else if (bits == 16) {		/* Write out top two pixels */		rgb[0] = ((LIMIT(b+yTL) >> 3) & 0x1F) | ((LIMIT(g+yTL) << 3) & 0xE0);		rgb[1] = ((LIMIT(g+yTL) >> 5) & 0x07) | (LIMIT(r+yTL) & 0xF8);		rgb[2] = ((LIMIT(b+yTR) >> 3) & 0x1F) | ((LIMIT(g+yTR) << 3) & 0xE0);		rgb[3] = ((LIMIT(g+yTR) >> 5) & 0x07) | (LIMIT(r+yTR) & 0xF8);	}}intv4l_yuv422p2rgb (unsigned char *rgb_out, unsigned char *yuv_in,		int width, int height, int bits){	const int numpix = width * height;	const unsigned int bytes = bits >> 3;	int h, w, y00, y01, u, v;	unsigned char *pY = yuv_in;	unsigned char *pU = pY + numpix;	unsigned char *pV = pU + numpix / 2;	unsigned char *pOut = rgb_out;	if (!rgb_out || !yuv_in)		return -1;	for (h = 0; h < height; h += 1) {		for (w = 0; w <= width - 2; w += 2) {			y00 = *(pY);			y01 = *(pY + 1);			u = (*pU++) - 128;			v = (*pV++) - 128;			v4l_copy_422_block (y00, y01, u, v, width, pOut, bits);				pY += 2;			pOut += bytes << 1;		}		//pY += width;		//pOut += width * bytes;	}	return 0;}voidput_image_ppm (FILE *out, char *image, int width, int height, int binary){	int x, y, ls=0;	unsigned char *p = (unsigned char *)image;	if (!binary) {		fprintf (out, "P3\n%d %d\n%d\n", width, height, 255);		for (x = 0; x < width; x++) {			for (y = 0; y < height; y++) {				fprintf (out, "%03d %03d %03d  ", p[2], p[1], p[0]);				p += 3;				if (ls++ > 4) {					fprintf (out, "\n");					ls = 0;				}			}		}		fprintf (out, "\n");	} else {		unsigned char buff[3];		fprintf (out, "P6\n%d %d\n%d\n", width, height, 255);		for (x = 0; x < width * height; x++) {			buff[0] = p[0];			buff[1] = p[1];			buff[2] = p[2];			fwrite (buff, 1, 3, out);			p += 3;		}	}	printf("succ\n");	fflush (out);}
int CompressJPEG(char * filename,unsigned char *image_buffer,int image_width,int image_height,int quality){  struct jpeg_compress_struct cinfo;  /* This struct represents a JPEG error handler.  It is declared separately   * because applications often want to supply a specialized error handler   * (see the second half of this file for an example).  But here we just   * take the easy way out and use the standard error handler, which will   * print a message on stderr and call exit() if compression fails.   * Note that this struct must live as long as the main JPEG parameter   * struct, to avoid dangling-pointer problems.   */  struct jpeg_error_mgr jerr;  /* More stuff */  FILE * outfile;		/* target file */  JSAMPROW row_pointer[1];	/* pointer to JSAMPLE row[s] */  int row_stride;		/* physical row width in image buffer */  /* Step 1: allocate and initialize JPEG compression object */  /* We have to set up the error handler first, in case the initialization   * step fails.  (Unlikely, but it could happen if you are out of memory.)   * This routine fills in the contents of struct jerr, and returns jerr's   * address which we place into the link field in cinfo.   */  cinfo.err = jpeg_std_error(&jerr);  /* Now we can initialize the JPEG compression object. */  jpeg_create_compress(&cinfo);  /* Step 2: specify data destination (eg, a file) */  /* Note: steps 2 and 3 can be done in either order. */  /* Here we use the library-supplied code to send compressed data to a   * stdio stream.  You can also write your own code to do something else.   * VERY IMPORTANT: use "b" option to fopen() if you are on a machine that   * requires it in order to write binary files.   */  if ((outfile = fopen(filename, "wb")) == NULL) {    fprintf(stderr, "can't open %s\n", filename);    return 0;  }  jpeg_stdio_dest(&cinfo, outfile);  /* Step 3: set parameters for compression */  /* First we supply a description of the input image.   * Four fields of the cinfo struct must be filled in:   */  cinfo.image_width = image_width; 	/* image width and height, in pixels */  cinfo.image_height = image_height;  cinfo.input_components = 3;		/* # of color components per pixel */  cinfo.in_color_space = JCS_RGB; 	/* colorspace of input image */  /* Now use the library's routine to set default compression parameters.   * (You must set at least cinfo.in_color_space before calling this,   * since the defaults depend on the source color space.)   */  jpeg_set_defaults(&cinfo);  /* Now you can set any non-default parameters you wish to.   * Here we just illustrate the use of quality (quantization table) scaling:   */  jpeg_set_quality(&cinfo, quality, TRUE /* limit to baseline-JPEG values */);  /* Step 4: Start compressor */  /* TRUE ensures that we will write a complete interchange-JPEG file.   * Pass TRUE unless you are very sure of what you're doing.   */  jpeg_start_compress(&cinfo, TRUE);  /* Step 5: while (scan lines remain to be written) */  /*           jpeg_write_scanlines(...); */  /* Here we use the library's state variable cinfo.next_scanline as the   * loop counter, so that we don't have to keep track ourselves.   * To keep things simple, we pass one scanline per call; you can pass   * more if you wish, though.   */  row_stride = image_width * 3;	/* JSAMPLEs per row in image_buffer */  while (cinfo.next_scanline < cinfo.image_height) {    /* jpeg_write_scanlines expects an array of pointers to scanlines.     * Here the array is only one element long, but you could pass     * more than one scanline at a time if that's more convenient.     */    row_pointer[0] = & image_buffer[(image_height-cinfo.next_scanline-1) * row_stride];    (void) jpeg_write_scanlines(&cinfo, row_pointer, 1);  }  /* Step 6: Finish compression */  jpeg_finish_compress(&cinfo);  /* After finish_compress, we can close the output file. */  fclose(outfile);  /* Step 7: release JPEG compression object */  /* This is an important step since it will release a good deal of memory. */  jpeg_destroy_compress(&cinfo);  return 1;  /* And we're done! */}
unsigned int Conv_YCbCr_Rgb(unsigned char y0, unsigned char y1, unsigned char cb0, unsigned char cr0)  // second solution... by junon
{
	// bit order is
	// YCbCr = [Cr0 Y1 Cb0 Y0], RGB=[R1,G1,B1,R0,G0,B0].
	
	int r0, g0, b0, r1, g1, b1;
	unsigned int rgb0, rgb1, rgb;
 
	#if 1 // 4 frames/s @192MHz, 12MHz ; 6 frames/s @450MHz, 12MHz
	r0 = YCbCrtoR(y0, cb0, cr0);
	g0 = YCbCrtoG(y0, cb0, cr0);
	b0 = YCbCrtoB(y0, cb0, cr0);
	r1 = YCbCrtoR(y1, cb0, cr0);
	g1 = YCbCrtoG(y1, cb0, cr0);
	b1 = YCbCrtoB(y1, cb0, cr0);
	#endif

	if (r0>255 ) r0 = 255;
	if (r0<0) r0 = 0;
	if (g0>255 ) g0 = 255;
	if (g0<0) g0 = 0;
	if (b0>255 ) b0 = 255;
	if (b0<0) b0 = 0;

	if (r1>255 ) r1 = 255;
	if (r1<0) r1 = 0;
	if (g1>255 ) g1 = 255;
	if (g1<0) g1 = 0;
	if (b1>255 ) b1 = 255;
	if (b1<0) b1 = 0;
	
	// 5:6:5 16bit format
	rgb0 = (((unsigned short int)r0>>3)<<11) | (((unsigned short int)g0>>2)<<5) | (((unsigned short int)b0>>3)<<0);	//RGB565.
	rgb1 = (((unsigned short int)r1>>3)<<11) | (((unsigned short int)g1>>2)<<5) | (((unsigned short int)b1>>3)<<0);	//RGB565.

	rgb = (rgb1<<16) | rgb0;

	return(rgb);
}

int main() 
{
  int fd,i;  unsigned char *YData, *CbData, *CrData;  //unsigned char *RGBData;
  unsigned char *buf=malloc(720*540*2);  unsigned char *rgb=malloc(720*540*3);  //char *base=malloc(720*540*3);  long c;  FILE *out;  memset(buf,0,720*540*2);  memset(rgb,0,720*540*3);  //memset(base,0,720*540*3);
  printf("now,cam test program begining!\n");   
  fd=open(CAMDEVICE,O_RDWR);   getchar();
  printf("%u bytes read!\n",read(fd,buf,720*540*2));  YData=buf;  CbData=buf+720*540;  CrData=buf+720*540*3/2;  //RGBData=(unsigned int *)rgb; out=fopen("yuv_data.txt","wb");  for (i=0; i<720*540; i++)  {  	unsigned char y,cb,cr;	unsigned int r, g, b;  	y=*(YData+i);  	cb=*(CbData+i/2);  	cr=*(CrData+i/2);  	if (i % 5==0)  			fprintf(out,"\n");	fprintf(out,"0x%2x,0x%2x,0x%2x|",y,cb,cr);
	r = YCbCrtoR(y, cb, cr);
	g = YCbCrtoG(y, cb, cr);
	b = YCbCrtoB(y, cb, cr);


	if (r>255 ) r = 255;
	if (r<0) r = 0;
	if (g>255 ) g = 255;
	if (g<0) g = 0;
	if (b>255 ) b = 255;
	if (b<0) b = 0;  	*(rgb+3*i)=(unsigned char)r;  	*(rgb+3*i+1)=(unsigned char)g;  	*(rgb+3*i+2)=(unsigned char)b;  }  fclose(out);  printf("yuv_data.txt output!\n");  c=0;  out=fopen("rgb_data.txt","wb");  for (i=0; i<720*540; i++)  {  		if (*(rgb+3*i)!=0 || *(rgb+3*i+1)!=0 || *(rgb+3*i+2)!=0)  			c++;  		if (i % 5==0)  			fprintf(out,"\n");  		fprintf(out,"0x%2x,0x%2x,0x%2x|",*(rgb+3*i),*(rgb+3*i+1),*(rgb+3*i+2));  }  fclose(out);  printf("%ld\n",c);  //CompressJPEG("cuijinbird.jpg",rgb,320,240,80);  out=fopen("cuijinbird.ppm", "wb");  put_image_ppm (out, rgb, 720, 540, 1);  fclose(out);  v4l_yuv422p2rgb(rgb,buf,720,540,24);  out=fopen("cuijinbird01.ppm", "wb");  put_image_ppm (out, rgb, 720, 540, 1);  fclose(out);  return 0;
} 

⌨️ 快捷键说明

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