CQ出版 Interface記事用サンプル。 トラ技カメラ+FIFOからデータを得て、 エリア判定後、デバイスに保存

Dependencies:   SDFileSystem mbed

Committer:
TETSUYA
Date:
Fri Sep 27 03:19:01 2013 +0000
Revision:
1:c822ea77c7b2
Parent:
0:1648bb4e70e5
Child:
2:3aed552f3385
CQ publishing ver 1.00

Who changed what in which revision?

UserRevisionLine numberNew contents of line
TETSUYA 0:1648bb4e70e5 1 /*
TETSUYA 0:1648bb4e70e5 2 Toragi-CCD-Cam OV7670andFIFO sample use driver
TETSUYA 0:1648bb4e70e5 3
TETSUYA 0:1648bb4e70e5 4 Sadaei Osakabe ( http://mbed.org/users/diasea/ )
TETSUYA 0:1648bb4e70e5 5 http://mbed.org/users/diasea/code/OV7670_with_AL422B_Color_Size_test/
TETSUYA 0:1648bb4e70e5 6
TETSUYA 0:1648bb4e70e5 7 */
TETSUYA 1:c822ea77c7b2 8 #include <string.h>
TETSUYA 1:c822ea77c7b2 9 #include <math.h>
TETSUYA 0:1648bb4e70e5 10 #include "mbed.h"
TETSUYA 0:1648bb4e70e5 11 #include <algorithm>
TETSUYA 0:1648bb4e70e5 12 #include "ov7670.h"
TETSUYA 0:1648bb4e70e5 13
TETSUYA 0:1648bb4e70e5 14 #define QQVGA
TETSUYA 0:1648bb4e70e5 15 #ifdef QQVGA
TETSUYA 0:1648bb4e70e5 16 # define SIZEX (160)
TETSUYA 0:1648bb4e70e5 17 # define SIZEY (120)
TETSUYA 0:1648bb4e70e5 18 #else
TETSUYA 0:1648bb4e70e5 19 # define SIZEX (320)
TETSUYA 0:1648bb4e70e5 20 # define SIZEY (240)
TETSUYA 0:1648bb4e70e5 21 #endif
TETSUYA 0:1648bb4e70e5 22
TETSUYA 0:1648bb4e70e5 23 OV7670 camera(
TETSUYA 0:1648bb4e70e5 24 p28,p27, // SDA,SCL(I2C / SCCB)
TETSUYA 0:1648bb4e70e5 25 p25,p26,p29, // VSYNC,HREF,WEN(FIFO)
TETSUYA 0:1648bb4e70e5 26 p24,p23,p22,p21,p20,p19,p18,p17, // D7-D0
TETSUYA 0:1648bb4e70e5 27 p5,p6,p7) ; // RRST,OE,RCLK
TETSUYA 0:1648bb4e70e5 28
TETSUYA 0:1648bb4e70e5 29
TETSUYA 0:1648bb4e70e5 30
TETSUYA 0:1648bb4e70e5 31 LocalFileSystem local("local");
TETSUYA 0:1648bb4e70e5 32
TETSUYA 0:1648bb4e70e5 33 Serial pc(USBTX,USBRX) ;
TETSUYA 0:1648bb4e70e5 34
TETSUYA 0:1648bb4e70e5 35 int sizex = 0;
TETSUYA 0:1648bb4e70e5 36 int sizey = 0;
TETSUYA 0:1648bb4e70e5 37
TETSUYA 1:c822ea77c7b2 38 #define AREA_X 32
TETSUYA 1:c822ea77c7b2 39 #define AREA_Y 24
TETSUYA 1:c822ea77c7b2 40
TETSUYA 1:c822ea77c7b2 41 char canvas[160][120] ; //18.5KB
TETSUYA 1:c822ea77c7b2 42 signed int AreaDiff[2][5][5]; // 5x5 Area = 32x24dot Each Block
TETSUYA 1:c822ea77c7b2 43 int face_bank = 0;
TETSUYA 1:c822ea77c7b2 44
TETSUYA 1:c822ea77c7b2 45
TETSUYA 0:1648bb4e70e5 46
TETSUYA 0:1648bb4e70e5 47 int main() {
TETSUYA 0:1648bb4e70e5 48 char color_format = 0;
TETSUYA 0:1648bb4e70e5 49 char c;
TETSUYA 1:c822ea77c7b2 50 int d1,d2 ;
TETSUYA 0:1648bb4e70e5 51 int mx, pixel , i;
TETSUYA 1:c822ea77c7b2 52 int pixc, pixelg;
TETSUYA 1:c822ea77c7b2 53 int sort[3];
TETSUYA 1:c822ea77c7b2 54 int ay = 0;
TETSUYA 1:c822ea77c7b2 55
TETSUYA 1:c822ea77c7b2 56 memset( AreaDiff, '\0', sizeof(AreaDiff));
TETSUYA 1:c822ea77c7b2 57
TETSUYA 0:1648bb4e70e5 58 pc.baud(115200);
TETSUYA 0:1648bb4e70e5 59 RESJMP:
TETSUYA 0:1648bb4e70e5 60 //pc.printf("Camera resetting..\r\n");
TETSUYA 0:1648bb4e70e5 61 camera.Reset();
TETSUYA 0:1648bb4e70e5 62
TETSUYA 0:1648bb4e70e5 63 //pc.printf("Before Init...\r\n");
TETSUYA 0:1648bb4e70e5 64 //camera.PrintRegister();
TETSUYA 0:1648bb4e70e5 65 switch( color_format ){
TETSUYA 0:1648bb4e70e5 66 case '1':
TETSUYA 0:1648bb4e70e5 67 camera.InitRGB444();
TETSUYA 0:1648bb4e70e5 68 break;
TETSUYA 0:1648bb4e70e5 69 case '2':
TETSUYA 0:1648bb4e70e5 70 camera.InitRGB555();
TETSUYA 0:1648bb4e70e5 71 break;
TETSUYA 0:1648bb4e70e5 72 default:
TETSUYA 0:1648bb4e70e5 73 camera.InitRGB565();
TETSUYA 0:1648bb4e70e5 74 break;
TETSUYA 0:1648bb4e70e5 75 }
TETSUYA 0:1648bb4e70e5 76
TETSUYA 0:1648bb4e70e5 77 //sizex = 160;
TETSUYA 0:1648bb4e70e5 78 //sizey = 120;
TETSUYA 0:1648bb4e70e5 79 camera.InitQQVGA();
TETSUYA 0:1648bb4e70e5 80
TETSUYA 0:1648bb4e70e5 81 camera.InitForFIFOWriteReset();
TETSUYA 0:1648bb4e70e5 82 camera.InitDefaultReg(true, true); // flipv/flipH
TETSUYA 0:1648bb4e70e5 83
TETSUYA 0:1648bb4e70e5 84 //pc.printf("After Init...\r\n");
TETSUYA 0:1648bb4e70e5 85 //camera.PrintRegister();
TETSUYA 0:1648bb4e70e5 86
TETSUYA 0:1648bb4e70e5 87
TETSUYA 0:1648bb4e70e5 88 // CAPTURE and SEND LOOP
TETSUYA 0:1648bb4e70e5 89 while(1)
TETSUYA 0:1648bb4e70e5 90 {
TETSUYA 1:c822ea77c7b2 91 memset( &AreaDiff[face_bank], '\0', sizeof(AreaDiff[face_bank]));
TETSUYA 1:c822ea77c7b2 92
TETSUYA 0:1648bb4e70e5 93 pc.printf("Hit Any Key to send RGBx160x120 Capture Data.\r\n") ;
TETSUYA 0:1648bb4e70e5 94 while(!pc.readable()) ;
TETSUYA 0:1648bb4e70e5 95 c = pc.getc() ;
TETSUYA 0:1648bb4e70e5 96 if (( c == '1' )|| ( c == '2' )||( c == '3' )){
TETSUYA 0:1648bb4e70e5 97 color_format = c;
TETSUYA 0:1648bb4e70e5 98 goto RESJMP;
TETSUYA 0:1648bb4e70e5 99 }
TETSUYA 0:1648bb4e70e5 100 camera.CaptureNext(); // sample start!
TETSUYA 0:1648bb4e70e5 101 while(camera.CaptureDone() == false);
TETSUYA 0:1648bb4e70e5 102 camera.ReadStart();
TETSUYA 0:1648bb4e70e5 103 pixc = 0;
TETSUYA 1:c822ea77c7b2 104 ay = 0;
TETSUYA 0:1648bb4e70e5 105 for (int y = 0;y < SIZEY;y++) {
TETSUYA 1:c822ea77c7b2 106 ay = y / AREA_Y;
TETSUYA 0:1648bb4e70e5 107 for (int x = 0;x < SIZEX;x++) {
TETSUYA 0:1648bb4e70e5 108 d1 = camera.ReadOneByte() ; // upper nibble is XXX , lower nibble is B
TETSUYA 0:1648bb4e70e5 109 d2 = camera.ReadOneByte() ; // upper nibble is G , lower nibble is R
TETSUYA 0:1648bb4e70e5 110 pixel = ((unsigned int)d2 << 8) + ((unsigned int)d1 & 0xff);
TETSUYA 1:c822ea77c7b2 111
TETSUYA 1:c822ea77c7b2 112 // Make GrayScale
TETSUYA 1:c822ea77c7b2 113 // make 6bit Code on Each Color
TETSUYA 1:c822ea77c7b2 114 sort[0] = ((pixel >> 11) & 0x1f)<<1; // r
TETSUYA 1:c822ea77c7b2 115 sort[1] = ((pixel >> 5) & 0x3f); // g
TETSUYA 1:c822ea77c7b2 116 sort[2] = ((pixel ) & 0x1f)<<1; // b
TETSUYA 1:c822ea77c7b2 117
TETSUYA 1:c822ea77c7b2 118 int max = 0, min = 0xffff;
TETSUYA 1:c822ea77c7b2 119 for (int i=0;i<3;i++){
TETSUYA 1:c822ea77c7b2 120 if (sort[i] > max) max = sort[i];
TETSUYA 1:c822ea77c7b2 121 if (sort[i] < min) min = sort[i];
TETSUYA 1:c822ea77c7b2 122 }
TETSUYA 1:c822ea77c7b2 123 int gray = ((max + min) / 2) ;
TETSUYA 1:c822ea77c7b2 124
TETSUYA 1:c822ea77c7b2 125 pixelg = ((gray>>1)<<11) + (gray<<5) + (gray>>1);
TETSUYA 1:c822ea77c7b2 126 pixel = pixelg;
TETSUYA 1:c822ea77c7b2 127 canvas[x][y] = (char)( pixelg ) & 0x3f; // 6bit gray scale
TETSUYA 1:c822ea77c7b2 128
TETSUYA 1:c822ea77c7b2 129 // Make Difference AreaData
TETSUYA 1:c822ea77c7b2 130 AreaDiff[face_bank][x/AREA_X][ay] += ( gray << 2 ); // 8bit scaler!
TETSUYA 1:c822ea77c7b2 131
TETSUYA 0:1648bb4e70e5 132 // send <CRLF> and Count on each 16dot.
TETSUYA 0:1648bb4e70e5 133 if ( !(x%16) ){
TETSUYA 0:1648bb4e70e5 134 pc.printf("\r\n%04x: ",pixc ) ;
TETSUYA 0:1648bb4e70e5 135 pixc +=16;
TETSUYA 0:1648bb4e70e5 136 }
TETSUYA 0:1648bb4e70e5 137 pc.printf("%04x ",pixel) ;
TETSUYA 1:c822ea77c7b2 138
TETSUYA 0:1648bb4e70e5 139 }
TETSUYA 0:1648bb4e70e5 140
TETSUYA 0:1648bb4e70e5 141 }
TETSUYA 0:1648bb4e70e5 142 camera.ReadStop();
TETSUYA 1:c822ea77c7b2 143
TETSUYA 1:c822ea77c7b2 144 // Difference Check!!
TETSUYA 1:c822ea77c7b2 145 pc.printf("\r\n" ) ;
TETSUYA 1:c822ea77c7b2 146 int backArea = ( face_bank + 1 )&0x01;
TETSUYA 1:c822ea77c7b2 147 for (int y = 0; y < 5; y++) {
TETSUYA 1:c822ea77c7b2 148 pc.printf("Diff: " ) ;
TETSUYA 1:c822ea77c7b2 149 for (int x = 0; x < 5; x++) {
TETSUYA 1:c822ea77c7b2 150 int dif = abs( AreaDiff[backArea][x][y] - AreaDiff[face_bank][x][y] );
TETSUYA 1:c822ea77c7b2 151 if (dif >= 20000) {
TETSUYA 1:c822ea77c7b2 152 pc.printf("X%5d " , dif) ;
TETSUYA 1:c822ea77c7b2 153 }else{
TETSUYA 1:c822ea77c7b2 154 pc.printf("O%5d " , dif) ;
TETSUYA 1:c822ea77c7b2 155 }
TETSUYA 1:c822ea77c7b2 156 }
TETSUYA 1:c822ea77c7b2 157 pc.printf(" " ) ;
TETSUYA 1:c822ea77c7b2 158 pc.printf(" \r\n" ) ;
TETSUYA 1:c822ea77c7b2 159 }
TETSUYA 1:c822ea77c7b2 160
TETSUYA 1:c822ea77c7b2 161
TETSUYA 1:c822ea77c7b2 162
TETSUYA 1:c822ea77c7b2 163 /*
TETSUYA 1:c822ea77c7b2 164 // Median Filter
TETSUYA 1:c822ea77c7b2 165 for (int y = 1;y < SIZEY-1;y++) {
TETSUYA 1:c822ea77c7b2 166 for (int x = 1;x < SIZEX-1;x++) {
TETSUYA 1:c822ea77c7b2 167 int sortM[9] = { 0 };
TETSUYA 1:c822ea77c7b2 168 int p=0;
TETSUYA 1:c822ea77c7b2 169
TETSUYA 1:c822ea77c7b2 170 // Get Around Pixels
TETSUYA 1:c822ea77c7b2 171 for (int k = -1; k < 2; k++) {
TETSUYA 1:c822ea77c7b2 172 for (int j = -1; j < 2; j++) {
TETSUYA 1:c822ea77c7b2 173 sortM[p++] = canvas[x+j][y+k]; //grayscale data
TETSUYA 1:c822ea77c7b2 174 }
TETSUYA 1:c822ea77c7b2 175 }
TETSUYA 1:c822ea77c7b2 176 // sort now...
TETSUYA 1:c822ea77c7b2 177 for (int k = 0; k < 8; k++){
TETSUYA 1:c822ea77c7b2 178 for (int j = 8; j > k; j--) {
TETSUYA 1:c822ea77c7b2 179 if (sortM[j] < sortM[j - 1]) {
TETSUYA 1:c822ea77c7b2 180 int dmy = sortM[j];
TETSUYA 1:c822ea77c7b2 181 sortM[j] = sortM[j - 1];
TETSUYA 1:c822ea77c7b2 182 sortM[j - 1] = dmy;
TETSUYA 1:c822ea77c7b2 183 }
TETSUYA 1:c822ea77c7b2 184 }
TETSUYA 1:c822ea77c7b2 185 }
TETSUYA 1:c822ea77c7b2 186
TETSUYA 1:c822ea77c7b2 187 canvasM[x][y] = sortM[4]; // Center Data!
TETSUYA 1:c822ea77c7b2 188 }
TETSUYA 1:c822ea77c7b2 189 }
TETSUYA 1:c822ea77c7b2 190
TETSUYA 1:c822ea77c7b2 191 // Send Median Display
TETSUYA 1:c822ea77c7b2 192 pixc = 0;
TETSUYA 1:c822ea77c7b2 193 for (int y = 0;y < SIZEY;y++) {
TETSUYA 1:c822ea77c7b2 194 for (int x = 0;x < SIZEX;x++) {
TETSUYA 1:c822ea77c7b2 195 // send <CRLF> and Count on each 16dot.
TETSUYA 1:c822ea77c7b2 196 if ( !(x%16) ){
TETSUYA 1:c822ea77c7b2 197 pc.printf("\r\n%04x: ",pixc ) ;
TETSUYA 1:c822ea77c7b2 198 pixc +=16;
TETSUYA 1:c822ea77c7b2 199 }
TETSUYA 1:c822ea77c7b2 200 pc.printf("%04x ",canvasM[x][y]) ;
TETSUYA 1:c822ea77c7b2 201 }
TETSUYA 1:c822ea77c7b2 202 }
TETSUYA 1:c822ea77c7b2 203 */
TETSUYA 1:c822ea77c7b2 204 face_bank++;
TETSUYA 1:c822ea77c7b2 205 face_bank&=0x01;
TETSUYA 1:c822ea77c7b2 206
TETSUYA 1:c822ea77c7b2 207
TETSUYA 0:1648bb4e70e5 208 //pc.printf("\r\n") ;
TETSUYA 0:1648bb4e70e5 209 }
TETSUYA 0:1648bb4e70e5 210 }
TETSUYA 0:1648bb4e70e5 211
TETSUYA 0:1648bb4e70e5 212
TETSUYA 0:1648bb4e70e5 213
TETSUYA 0:1648bb4e70e5 214 /*
TETSUYA 1:c822ea77c7b2 215 int create_header(FILE *fp, int width, int height) ;
TETSUYA 0:1648bb4e70e5 216
TETSUYA 0:1648bb4e70e5 217 #if defined(BITMAPFILE) || defined(BAYERBITMAPFILE)
TETSUYA 0:1648bb4e70e5 218 #define BITMAPFILE
TETSUYA 0:1648bb4e70e5 219 #undef BAYERBITMAPFILE
TETSUYA 0:1648bb4e70e5 220 #undef HEXFILE
TETSUYA 0:1648bb4e70e5 221 #undef COLORBAR
TETSUYA 0:1648bb4e70e5 222
TETSUYA 0:1648bb4e70e5 223 #define FILEHEADERSIZE 14 //ファイルヘッダのサイズ
TETSUYA 0:1648bb4e70e5 224 #define INFOHEADERSIZE 40 //情報ヘッダのサイズ
TETSUYA 0:1648bb4e70e5 225 #define HEADERSIZE (FILEHEADERSIZE+INFOHEADERSIZE)
TETSUYA 0:1648bb4e70e5 226
TETSUYA 0:1648bb4e70e5 227 int create_header(FILE *fp, int width, int height) {
TETSUYA 0:1648bb4e70e5 228 int real_width;
TETSUYA 0:1648bb4e70e5 229 unsigned char header_buf[HEADERSIZE]; //ヘッダを格納する
TETSUYA 0:1648bb4e70e5 230 unsigned int file_size;
TETSUYA 0:1648bb4e70e5 231 unsigned int offset_to_data;
TETSUYA 0:1648bb4e70e5 232 unsigned long info_header_size;
TETSUYA 0:1648bb4e70e5 233 unsigned int planes;
TETSUYA 0:1648bb4e70e5 234 unsigned int color;
TETSUYA 0:1648bb4e70e5 235 unsigned long compress;
TETSUYA 0:1648bb4e70e5 236 unsigned long data_size;
TETSUYA 0:1648bb4e70e5 237 long xppm;
TETSUYA 0:1648bb4e70e5 238 long yppm;
TETSUYA 0:1648bb4e70e5 239
TETSUYA 0:1648bb4e70e5 240 real_width = width*3 + width%4;
TETSUYA 0:1648bb4e70e5 241
TETSUYA 0:1648bb4e70e5 242 //ここからヘッダ作成
TETSUYA 0:1648bb4e70e5 243 file_size = height * real_width + HEADERSIZE;
TETSUYA 0:1648bb4e70e5 244 offset_to_data = HEADERSIZE;
TETSUYA 0:1648bb4e70e5 245 info_header_size = INFOHEADERSIZE;
TETSUYA 0:1648bb4e70e5 246 planes = 1;
TETSUYA 0:1648bb4e70e5 247 color = 24;
TETSUYA 0:1648bb4e70e5 248 compress = 0;
TETSUYA 0:1648bb4e70e5 249 data_size = height * real_width;
TETSUYA 0:1648bb4e70e5 250 xppm = 1;
TETSUYA 0:1648bb4e70e5 251 yppm = 1;
TETSUYA 0:1648bb4e70e5 252
TETSUYA 0:1648bb4e70e5 253 header_buf[0] = 'B';
TETSUYA 0:1648bb4e70e5 254 header_buf[1] = 'M';
TETSUYA 0:1648bb4e70e5 255 memcpy(header_buf + 2, &file_size, sizeof(file_size));
TETSUYA 0:1648bb4e70e5 256 header_buf[6] = 0;
TETSUYA 0:1648bb4e70e5 257 header_buf[7] = 0;
TETSUYA 0:1648bb4e70e5 258 header_buf[8] = 0;
TETSUYA 0:1648bb4e70e5 259 header_buf[9] = 0;
TETSUYA 0:1648bb4e70e5 260 memcpy(header_buf + 10, &offset_to_data, sizeof(offset_to_data));
TETSUYA 0:1648bb4e70e5 261 memcpy(header_buf + 14, &info_header_size, sizeof(info_header_size));
TETSUYA 0:1648bb4e70e5 262 memcpy(header_buf + 18, &width, sizeof(width));
TETSUYA 0:1648bb4e70e5 263 height = height * -1; // データ格納順が逆なので、高さをマイナスとしている
TETSUYA 0:1648bb4e70e5 264 memcpy(header_buf + 22, &height, sizeof(height));
TETSUYA 0:1648bb4e70e5 265 memcpy(header_buf + 26, &planes, sizeof(planes));
TETSUYA 0:1648bb4e70e5 266 memcpy(header_buf + 28, &color, sizeof(color));
TETSUYA 0:1648bb4e70e5 267 memcpy(header_buf + 30, &compress, sizeof(compress));
TETSUYA 0:1648bb4e70e5 268 memcpy(header_buf + 34, &data_size, sizeof(data_size));
TETSUYA 0:1648bb4e70e5 269 memcpy(header_buf + 38, &xppm, sizeof(xppm));
TETSUYA 0:1648bb4e70e5 270 memcpy(header_buf + 42, &yppm, sizeof(yppm));
TETSUYA 0:1648bb4e70e5 271 header_buf[46] = 0;
TETSUYA 0:1648bb4e70e5 272 header_buf[47] = 0;
TETSUYA 0:1648bb4e70e5 273 header_buf[48] = 0;
TETSUYA 0:1648bb4e70e5 274 header_buf[49] = 0;
TETSUYA 0:1648bb4e70e5 275 header_buf[50] = 0;
TETSUYA 0:1648bb4e70e5 276 header_buf[51] = 0;
TETSUYA 0:1648bb4e70e5 277 header_buf[52] = 0;
TETSUYA 0:1648bb4e70e5 278 header_buf[53] = 0;
TETSUYA 0:1648bb4e70e5 279
TETSUYA 0:1648bb4e70e5 280 //ヘッダの書き込み
TETSUYA 0:1648bb4e70e5 281 fwrite(header_buf, sizeof(unsigned char), HEADERSIZE, fp);
TETSUYA 0:1648bb4e70e5 282
TETSUYA 0:1648bb4e70e5 283 return 0;
TETSUYA 0:1648bb4e70e5 284 }
TETSUYA 0:1648bb4e70e5 285 #endif
TETSUYA 0:1648bb4e70e5 286 */