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
*/