CQ出版 Interface記事用サンプル。 トラ技カメラ+FIFOからデータを得て、 エリア判定後、デバイスに保存
Dependencies: SDFileSystem mbed
main.cpp
- Committer:
- TETSUYA
- Date:
- 2013-09-27
- Revision:
- 2:3aed552f3385
- Parent:
- 1:c822ea77c7b2
- Child:
- 3:8d5594ce5b00
File content as of revision 2:3aed552f3385:
/* Toragi-CCD-Cam OV7670andFIFO sample use driver Sadaei Osakabe ( http://mbed.org/users/diasea/ ) http://mbed.org/users/diasea/code/OV7670_with_AL422B_Color_Size_test/ */ #include <string.h> #include <math.h> #include "mbed.h" #include <algorithm> #include "ov7670.h" #define QQVGA #ifdef QQVGA # define SIZEX (160) # define SIZEY (120) #else # define SIZEX (320) # define SIZEY (240) #endif OV7670 camera( p28,p27, // SDA,SCL(I2C / SCCB) p25,p26,p29, // VSYNC,HREF,WEN(FIFO) p24,p23,p22,p21,p20,p19,p18,p17, // D7-D0 p5,p6,p7) ; // RRST,OE,RCLK LocalFileSystem local("local"); BusOut myleds(LED1, LED2, LED3, LED4); Serial pc(USBTX,USBRX) ; int sizex = 0; int sizey = 0; #define AREA_X 32 #define AREA_Y 24 #define AREA_DIV_X 5 #define AREA_DIV_Y 5 //#define AREA_THRESH 12000 #define AREA_THRESH 8000 char canvas[160][120] ; //18.5KB signed int AreaDiff[2][AREA_DIV_X][AREA_DIV_Y]; // 5x5 Area = 32x24dot Each Block int face_bank = 0; int Dbmode = 0; int main() { char color_format = 0; char c; int d1,d2 ; int mx, pixel , i; int pixc, pixelg; int sort[3]; int ay = 0; memset( AreaDiff, '\0', sizeof(AreaDiff)); pc.baud(115200); RESJMP: //pc.printf("Camera resetting..\r\n"); camera.Reset(); //pc.printf("Before Init...\r\n"); //camera.PrintRegister(); switch( color_format ){ case '1': camera.InitRGB444(); break; case '2': camera.InitRGB555(); break; default: camera.InitRGB565(); break; } //sizex = 160; //sizey = 120; camera.InitQQVGA(); camera.InitForFIFOWriteReset(); camera.InitDefaultReg(true, true); // flipv/flipH //pc.printf("After Init...\r\n"); //camera.PrintRegister(); // CAPTURE and SEND LOOP while(1) { memset( &AreaDiff[face_bank], '\0', sizeof(AreaDiff[face_bank])); if ( Dbmode ){ pc.printf("Hit Any Key to send RGBx160x120 Capture Data.\r\n") ; while(!pc.readable()) ; c = pc.getc() ; if (( c == '1' )|| ( c == '2' )||( c == '3' )){ color_format = c; goto RESJMP; }else if (( c == 'd' )|| ( c == 'D' )){ Dbmode = 0; // GO FreeRun continue; } }else{ if ( pc.readable()) { c = pc.getc() ; if (( c == 'd' )|| ( c == 'D' )){ Dbmode = 1; // GO DEBUGmode continue; } } pc.printf(" \r\n") ; } camera.CaptureNext(); // sample start! while(camera.CaptureDone() == false); camera.ReadStart(); pixc = 0; ay = 0; for (int y = 0;y < SIZEY;y++) { ay = y / AREA_Y; for (int x = 0;x < SIZEX;x++) { d1 = camera.ReadOneByte() ; // upper nibble is XXX , lower nibble is B d2 = camera.ReadOneByte() ; // upper nibble is G , lower nibble is R pixel = ((unsigned int)d2 << 8) + ((unsigned int)d1 & 0xff); // Make GrayScale // make 6bit Code on Each Color sort[0] = ((pixel >> 11) & 0x1f)<<1; // r sort[1] = ((pixel >> 5) & 0x3f); // g sort[2] = ((pixel ) & 0x1f)<<1; // b int max = 0, min = 0xffff; for (int i=0;i<3;i++){ if (sort[i] > max) max = sort[i]; if (sort[i] < min) min = sort[i]; } int gray = ((max + min) / 2) ; pixelg = ((gray>>1)<<11) + (gray<<5) + (gray>>1); pixel = pixelg; canvas[x][y] = (char)( gray ) & 0x3f; // 6bit gray scale // Make Difference AreaData //AreaDiff[face_bank][x/AREA_X][ay] += ( gray << 2 ); // 8bit scaler! AreaDiff[face_bank][x/AREA_X][ay] += ( gray ); // 6bit scaler! if ( Dbmode ){ // send <CRLF> and Count on each 16dot. if ( !(x%16) ){ pc.printf("\r\n%04x: ",pixc ) ; pixc +=16; } pc.printf("%04x ",pixel) ; } } } camera.ReadStop(); // Difference Check!! pc.printf("\r\n" ) ; int err_c=0; int backArea = ( face_bank + 1 )&0x01; for (int y = 0; y < AREA_DIV_Y; y++) { if ( Dbmode ) pc.printf("Diff: " ) ; for (int x = 0; x < AREA_DIV_X; x++) { int dif = abs( AreaDiff[backArea][x][y] - AreaDiff[face_bank][x][y] ); if (dif >= AREA_THRESH) { err_c++; // Error Count if ( Dbmode ) pc.printf("X%5d " , dif) ; }else{ if ( Dbmode ) pc.printf("O%5d " , dif) ; } } if ( Dbmode ) { pc.printf(" " ) ; pc.printf(" \r\n" ) ; } } int led_s =0; switch ( err_c ){ case 1: led_s =1; break; case 2: led_s =3; break; case 3: led_s =7; break; default: if ( err_c >= 3) { led_s =7; }else{ led_s =0; } break; } led_s |= ( face_bank )? 0x08 : 0x00 ; myleds = led_s ; if ( err_c >= 3 ){ //pc.printf("\r\n") ; pixc = 0; for (int y = 0;y < SIZEY;y++) { for (int x = 0;x < SIZEX;x++) { char gray = 0; gray = canvas[x][y]; pixel = ((gray>>1)<<11) + (gray<<5) + (gray>>1); // send <CRLF> and Count on each 16dot. if ( !(x%16) ){ pc.printf("\r\n%04x: ",pixc ) ; pixc +=16; } pc.printf("%04x ",pixel) ; } } } face_bank++; face_bank&=0x01; //pc.printf("\r\n") ; } } /* // Median Filter for (int y = 1;y < SIZEY-1;y++) { for (int x = 1;x < SIZEX-1;x++) { int sortM[9] = { 0 }; int p=0; // Get Around Pixels for (int k = -1; k < 2; k++) { for (int j = -1; j < 2; j++) { sortM[p++] = canvas[x+j][y+k]; //grayscale data } } // sort now... for (int k = 0; k < 8; k++){ for (int j = 8; j > k; j--) { if (sortM[j] < sortM[j - 1]) { int dmy = sortM[j]; sortM[j] = sortM[j - 1]; sortM[j - 1] = dmy; } } } canvasM[x][y] = sortM[4]; // Center Data! } } // Send Median Display pixc = 0; for (int y = 0;y < SIZEY;y++) { for (int x = 0;x < SIZEX;x++) { // send <CRLF> and Count on each 16dot. if ( !(x%16) ){ pc.printf("\r\n%04x: ",pixc ) ; pixc +=16; } pc.printf("%04x ",canvasM[x][y]) ; } } */ /* int create_header(FILE *fp, int width, int height) ; #if defined(BITMAPFILE) || defined(BAYERBITMAPFILE) #define BITMAPFILE #undef BAYERBITMAPFILE #undef HEXFILE #undef COLORBAR #define FILEHEADERSIZE 14 //ファイルヘッダのサイズ #define INFOHEADERSIZE 40 //情報ヘッダのサイズ #define HEADERSIZE (FILEHEADERSIZE+INFOHEADERSIZE) int create_header(FILE *fp, int width, int height) { int real_width; unsigned char header_buf[HEADERSIZE]; //ヘッダを格納する unsigned int file_size; unsigned int offset_to_data; unsigned long info_header_size; unsigned int planes; unsigned int color; unsigned long compress; unsigned long data_size; long xppm; long yppm; real_width = width*3 + width%4; //ここからヘッダ作成 file_size = height * real_width + HEADERSIZE; offset_to_data = HEADERSIZE; info_header_size = INFOHEADERSIZE; planes = 1; color = 24; compress = 0; data_size = height * real_width; xppm = 1; yppm = 1; header_buf[0] = 'B'; header_buf[1] = 'M'; memcpy(header_buf + 2, &file_size, sizeof(file_size)); header_buf[6] = 0; header_buf[7] = 0; header_buf[8] = 0; header_buf[9] = 0; memcpy(header_buf + 10, &offset_to_data, sizeof(offset_to_data)); memcpy(header_buf + 14, &info_header_size, sizeof(info_header_size)); memcpy(header_buf + 18, &width, sizeof(width)); height = height * -1; // データ格納順が逆なので、高さをマイナスとしている memcpy(header_buf + 22, &height, sizeof(height)); memcpy(header_buf + 26, &planes, sizeof(planes)); memcpy(header_buf + 28, &color, sizeof(color)); memcpy(header_buf + 30, &compress, sizeof(compress)); memcpy(header_buf + 34, &data_size, sizeof(data_size)); memcpy(header_buf + 38, &xppm, sizeof(xppm)); memcpy(header_buf + 42, &yppm, sizeof(yppm)); header_buf[46] = 0; header_buf[47] = 0; header_buf[48] = 0; header_buf[49] = 0; header_buf[50] = 0; header_buf[51] = 0; header_buf[52] = 0; header_buf[53] = 0; //ヘッダの書き込み fwrite(header_buf, sizeof(unsigned char), HEADERSIZE, fp); return 0; } #endif */