📄 cam_test.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 + -