📄 cam2tft.c
字号:
void usage(FILE * fp, int rc){ fprintf(fp, "Usage: cam2tft [-d] [-R] [-m mode] [-w width] [-h height] [-?v] [-c count] [-r REG -a REGVALUE] [BMP output filename]\n"); fprintf(fp, " -d Display on TFT LCD\n"); fprintf(fp, " -R Reset CAM setting\n"); fprintf(fp, " -w width Capture Image Size\n"); fprintf(fp, " -h height Capture Image Size\n"); fprintf(fp, " -c count repeat count times\n"); fprintf(fp, " -r REG I2C register\n"); fprintf(fp, " -a VAL I2C value\n"); fprintf(fp, " -? this help\n"); fprintf(fp, " -v print version info\n"); fprintf(fp, " -m mode\n" " mode 0 or don't use mode: Manual\n" " mode 1: Display on TFT at SVGA\n" " mode 2: Mode 1 at UXGA\n" " mode 3: Capture to file at UXGA\n" " mode 4: Mode 3 at SVGA\n" " mode 5: Display on TFT at SVGA for 10s, then capture 1 frame at UXGA, then back to live video at SVGA\n" " mode 6: Mode 5 to file\n"); exit(rc);}int main(int argc, char *argv[]){ int width, height; int fd, i, c, delay, cnt = 1; int detail = 0, mode = 0, reset = 0; unsigned char *buffer, *filename; u_char addr; u_short value, display, sendi2c = 0; struct timeval o, t; long delta, usec, offset; int RAW10 = 1, RGB565 = 0; /* Check the passed arg */ display = 0; while ((c = getopt(argc, argv, "vd?DRr:a:c:w:h:m:")) > 0) { switch (c) { case 'D': detail = 1; break; case 'w': if(display) video_width = atoi(optarg); else capture_width = atoi(optarg); break; case 'h': if(display) video_height = atoi(optarg); else capture_height = atoi(optarg); break; case 'R': reset++; break; case 'm': mode = atoi(optarg); break; case 'r': sendi2c++; addr = atoi(optarg); break; case 'a': sendi2c++; value = atoi(optarg); break; case 'c': cnt = atoi(optarg); break; case 'v': printf("%s: version %s\n", argv[0], VERSION); exit(0); case 'd': display++; break; case '?': usage(stdout, 0); break; default: fprintf(stderr, "ERROR: unkown option '%c'\n", c); usage(stderr, 1); break; } } if(display) { width = video_width; height = video_height; } else { width = capture_width; height = capture_height; } int BYTES_PER_PIXEL = 1; // default: RAW10// if (RAW10)// BYTES_PER_PIXEL = 1; if (RGB565) BYTES_PER_PIXEL = 2; /******************************************************************************//* CM-BF561 with OV2640FSL *//******************************************************************************/ if (sendi2c == 2) { i2c_write_register(I2C_DEVICE, DEVID, addr, value); exit(0); } else if (sendi2c == 1) { printf("Register 0x%2x: 0x%2x\n", addr, i2c_read_register(I2C_DEVICE, DEVID, addr)); exit(0); } else { if (mode) { i2c_write_register(I2C_DEVICE, DEVID, 0xFF, 0x01); i2c_write_register(I2C_DEVICE, DEVID, CAM_REG_RESET, CAM_MASK_RESET_BIT); usleep(1000); // CAM config CAM_raw_init(); if (mode == 1 || mode == 4) { width = SVGA_WIDTH; height = SVGA_HEIGHT; CAM_raw_preview(); } else if (mode == 2 || mode == 3) { width = UXGA_WIDTH; height = UXGA_HEIGHT; CAM_raw_capture(); } else { width = UXGA_WIDTH; height = UXGA_HEIGHT; CAM_raw_preview(); } CAM_raw_EC(); } else if (reset) { i2c_write_register(I2C_DEVICE, DEVID, 0xFF, 0x01); i2c_write_register(I2C_DEVICE, DEVID, CAM_REG_RESET, CAM_MASK_RESET_BIT); usleep(1000); // CAM config CAM_init(); if (RAW10) CAM_init_RAW10(); else if (RGB565) CAM_init_RGB565(); if (width == SVGA_WIDTH && height == SVGA_HEIGHT) CAM_SVGA_resolution(); else if (width == CIF_WIDTH && height == CIF_HEIGHT) CAM_CIF_resolution(); } } printf("CAM configured. Wait for stable.\n"); sleep(1);if(detail) { i2c_write_register(I2C_DEVICE, DEVID, 0xFF, 0x00); i2c_dump_register(I2C_DEVICE,DEVID,0,256); i2c_write_register(I2C_DEVICE, DEVID, 0xFF, 0x01); i2c_dump_register(I2C_DEVICE,DEVID,0,256);} /* Allocate meory for the raw image */ buffer = (unsigned char *)malloc(BYTES_PER_PIXEL*IMAGESIZE); /* Open /dev/ppi */ fd = open(PPI_DEVICE, O_RDONLY, 0); if (fd == -1) { printf("Could not open dev\/ppi : %d \n", errno); free(buffer); exit(1); } printf("Set frame %dx%d.\n", width, height); if (mode) { if (mode == 1 || mode == 2) { ioctl(fd, CMD_PPI_SET_PIXELS_PER_LINE, BYTES_PER_PIXEL*width); ioctl(fd, CMD_PPI_SET_LINES_PER_FRAME, height); TFT_Init(); struct timeval cur_tim; while (1) { read(fd, buffer, BYTES_PER_PIXEL*IMAGESIZE); //Multiple with 2 for store each pixel in 16-bits data TFT565_DirectDisplay(buffer, width, height, tft_width, tft_height); gettimeofday(&cur_tim, NULL); printf("%d.%d\n", cur_tim.tv_sec, cur_tim.tv_usec);// unsigned char *RGBbuffer = (unsigned char *)malloc(3*IMAGESIZE);// ConvertRaw8ToRGB(RGBbuffer, buffer, width, height);// TFT_Display(RGBbuffer, width, height, tft_width, tft_height);// free(RGBbuffer); } } else if (mode == 3 || mode == 4) { ioctl(fd, CMD_PPI_SET_PIXELS_PER_LINE, BYTES_PER_PIXEL*width); ioctl(fd, CMD_PPI_SET_LINES_PER_FRAME, height); read(fd, buffer, BYTES_PER_PIXEL*IMAGESIZE); //Multiple with 2 for store each pixel in 16-bits data unsigned char *bitmap; int filesize; unsigned char *RGBbuffer = (unsigned char *)malloc(3*IMAGESIZE); ConvertRaw8ToRGB(RGBbuffer, buffer, width, height); free(buffer); bitmap = (unsigned char *)malloc(3*IMAGESIZE+54); filesize = ConvertRGBToWindowsBmp(width, height, width, height, RGBbuffer, bitmap); free(RGBbuffer); fd = open("img.bmp", O_WRONLY | O_CREAT | O_TRUNC, 0666); if (fd == -1) { (void)printf("%s: failed to open \"%s\"", argv[0], filename); free(bitmap); } else { int bytes_out = write(fd, bitmap, filesize); (void)close(fd); free(bitmap); printf ("*******************************************************************************\n"); printf("Saved: img.bmp \nSize : %d\n", bytes_out); printf ("*******************************************************************************\n"); } /* Close PPI */ close(fd); exit(0); } else { width = SVGA_WIDTH; height = SVGA_HEIGHT; ioctl(fd, CMD_PPI_SET_PIXELS_PER_LINE, BYTES_PER_PIXEL*width); ioctl(fd, CMD_PPI_SET_LINES_PER_FRAME, height); TFT_Init(); struct timeval cur_tim; gettimeofday(&cur_tim, NULL); int start = cur_tim.tv_sec; while (cur_tim.tv_sec < start+10) { // Capture new image read(fd, buffer, BYTES_PER_PIXEL*IMAGESIZE); //Multiple with 2 for store each pixel in 16-bits data TFT565_DirectDisplay(buffer, width, height, tft_width, tft_height);// unsigned char *RGBbuffer = (unsigned char *)malloc(3*IMAGESIZE);// ConvertRaw8ToRGB(RGBbuffer, buffer, width, height);// TFT_Display(RGBbuffer, width, height, tft_width, tft_height);// free(RGBbuffer); gettimeofday(&cur_tim, NULL); } printf("Start capture at: %d.%d\n", cur_tim.tv_sec, cur_tim.tv_usec); width = UXGA_WIDTH; height = UXGA_HEIGHT; CAM_raw_capture(); ioctl(fd, CMD_PPI_SET_PIXELS_PER_LINE, BYTES_PER_PIXEL*width); ioctl(fd, CMD_PPI_SET_LINES_PER_FRAME, height); read(fd, buffer, BYTES_PER_PIXEL*IMAGESIZE); //Multiple with 2 for store each pixel in 16-bits data if (mode == 6) { unsigned char *bitmap; int filesize; unsigned char *RGBbuffer = (unsigned char *)malloc(3*IMAGESIZE); ConvertRaw8ToRGB(RGBbuffer, buffer, width, height); bitmap = (unsigned char *)malloc(3*IMAGESIZE+54); filesize = ConvertRGBToWindowsBmp(width, height, width, height, RGBbuffer, bitmap); free(RGBbuffer); fd = open("img.bmp", O_WRONLY | O_CREAT | O_TRUNC, 0666); if (fd == -1) { (void)printf("%s: failed to open \"%s\"", argv[0], filename); free(bitmap); } else { int bytes_out = write(fd, bitmap, filesize); (void)close(fd); free(bitmap); printf ("*******************************************************************************\n"); printf("Saved: img.bmp \nSize : %d\n", bytes_out); printf ("*******************************************************************************\n"); } } gettimeofday(&cur_tim, NULL); printf("Capture successful at: %d.%d\n", cur_tim.tv_sec, cur_tim.tv_usec); width = SVGA_WIDTH; height = SVGA_HEIGHT; CAM_raw_preview(); ioctl(fd, CMD_PPI_SET_PIXELS_PER_LINE, BYTES_PER_PIXEL*width); ioctl(fd, CMD_PPI_SET_LINES_PER_FRAME, height); while (1) { read(fd, buffer, BYTES_PER_PIXEL*IMAGESIZE); //Multiple with 2 for store each pixel in 16-bits data TFT565_DirectDisplay(buffer, width, height, tft_width, tft_height);// unsigned char *RGBbuffer = (unsigned char *)malloc(3*IMAGESIZE);// ConvertRaw8ToRGB(RGBbuffer, buffer, width, height);// TFT_Display(RGBbuffer, width, height, tft_width, tft_height);// free(RGBbuffer); } } } else { // if mode == 0 ioctl(fd, CMD_PPI_SET_PIXELS_PER_LINE, BYTES_PER_PIXEL*width); ioctl(fd, CMD_PPI_SET_LINES_PER_FRAME, height); /* Read the raw image data from the PPI */ for (i = 0; i < cnt; i++) { gettimeofday(&o, NULL); read(fd, buffer, BYTES_PER_PIXEL*IMAGESIZE); //Multiple with 2 for store each pixel in 16-bits data gettimeofday(&t, NULL); //sleep(1); delta = tvdelta(&o, &t); printf ("Read Start:\t\t\t%lu.%06lu\nRead End:\t\t\t%lu.%06lu\nTotal Frame Capture Time:\t%ld usec\n\n", o.tv_sec, o.tv_usec, t.tv_sec, t.tv_usec, delta - offset); } if (display) { TFT_Init(); struct timeval cur_tim; while (1) { // usleep(700000); // Convert the captured image if(RAW10) { TFT565_DirectDisplay(buffer, width, height, tft_width, tft_height); gettimeofday(&cur_tim, NULL); printf("%d.%d\n", cur_tim.tv_sec, cur_tim.tv_usec); // unsigned char *RGBbuffer = (unsigned char *)malloc(3*IMAGESIZE); // ConvertRaw8ToRGB(RGBbuffer, buffer, width, height); // TFT_Display(RGBbuffer, width, height, tft_width, tft_height); // free(RGBbuffer); } else if(RGB565) { TFT565_Display(buffer, width, tft_width, tft_height); } // Capture new image // free(buffer); // buffer = (unsigned char *)malloc(BYTES_PER_PIXEL*IMAGESIZE); read(fd, buffer, BYTES_PER_PIXEL*IMAGESIZE); //Multiple with 2 for store each pixel in 16-bits data } } /* Close PPI */ close(fd); /* When data is transmitted from a CMOS camera that uses the Bayer Color Filter Array (Bayer CFA) we get a stream of alternating values of Red (R) Green (G) for odd rows and alternating values of Green (G) and Blue (B) for even rows. In order to construct an RGB picture, we need to calculate Green and Blue values for each Red pixel, Blue and Red values for each Green pixel and Red and Green values for each Blue pixel. http://www.helicontech.co.il/whitepapers/bayer-rgb.html */ /*For CFA Sensors: cfa2rgb( buffer+sizeof(bmphead) ); */ /* Write image back to file */ filename = argv[optind]; if (filename) { // Convert the captured image unsigned char *bitmap; int filesize; if(RAW10) { unsigned char *RGBbuffer = (unsigned char *)malloc(3*IMAGESIZE); ConvertRaw8ToRGB(RGBbuffer, buffer, width, height); free(buffer); bitmap = (unsigned char *)malloc(3*IMAGESIZE+54); //filesize = ConvertRGBToWindowsBmp(width, height, tft_width, tft_height, RGBbuffer, bitmap); filesize = ConvertRGBToWindowsBmp(width, height, width, height, RGBbuffer, bitmap); free(RGBbuffer); } else if(RGB565) { bitmap = buffer; filesize = BYTES_PER_PIXEL*IMAGESIZE; } fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC, 0666); if (fd == -1) { (void)printf("%s: failed to open \"%s\"", argv[0], filename); free(bitmap); } else { int bytes_out = write(fd, bitmap, filesize); (void)close(fd); free(bitmap); printf ("*******************************************************************************\n"); printf("Saved: %s \nSize : %d\n", filename, bytes_out); printf ("*******************************************************************************\n"); } } else { if(detail) { for (i = 0; i < 500; i++) printf("0x%2x ", *(buffer+i)); printf("\n"); for (i = BYTES_PER_PIXEL*IMAGESIZE-500; i < BYTES_PER_PIXEL*IMAGESIZE+10; i++) printf("0x%2x ", *(buffer+i)); } free(buffer); } } // if mode == 0 exit(0);} // end of main()
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -