Tested on Nucleo F411RE Based on OV7670 without FIFO, SCCB protocol rewritten. View on TFT ILI9341, possible capture picture on sd Around 3 frames per second Basic image treatment: zoom, rotation, etc Very basic pattern recognition, pattern being stored on SD, after camera capture, or from .bmp file (rgb 565, 120x160 max)
Dependencies: FastPWM SDFileSystem SPI_TFT_ILI9341 TFT_fonts imagetrlib mbed ov7670s
Revision 0:39c9f3b49f5a, committed 2016-02-16
- Comitter:
- sylvainkritter
- Date:
- Tue Feb 16 14:28:55 2016 +0000
- Child:
- 1:7fbc24ad0958
- Commit message:
- Tested on Nucleo F411RE
; Based on OV7670 without FIFO, SCCB protocol rewritten.
; View on TFT ILI9341, possible capture picture on sd
; Around 3 frames per second
; Basic image treatment: zoom, rotation, etc
; Very basic pattern recognition, pattern bein...
Changed in this revision
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/FastPWM.lib Tue Feb 16 14:28:55 2016 +0000 @@ -0,0 +1,1 @@ +http://developer.mbed.org/users/Sissors/code/FastPWM/#8b1bf34c72aa
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/SDFileSystem.lib Tue Feb 16 14:28:55 2016 +0000 @@ -0,0 +1,1 @@ +http://mbed.org/users/neilt6/code/SDFileSystem/#d10a519c0910
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/SPI_TFT_ILI9341.lib Tue Feb 16 14:28:55 2016 +0000 @@ -0,0 +1,1 @@ +http://mbed.org/users/dreschpe/code/SPI_TFT_ILI9341/#b2b3e5430f81
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/TFT_fonts.lib Tue Feb 16 14:28:55 2016 +0000 @@ -0,0 +1,1 @@ +http://mbed.org/users/dreschpe/code/TFT_fonts/#76774250fcec
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/global.h Tue Feb 16 14:28:55 2016 +0000 @@ -0,0 +1,6 @@ +#define nl 120 +#define nc 160 +#define nlta 30 +#define ncta 40 +#define nv 5 +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/imagetr/imagetr.h Tue Feb 16 14:28:55 2016 +0000 @@ -0,0 +1,747 @@ +#pragma once +#include "mbed.h" +#include "global.h" +#include "SDFileSystem.h" +#include "SPI_TFT_ILI9341.h" +#include "Arial12x12.h" +#include "Arial24x23.h" +#include "Arial28x28.h" +#include "font_big.h" + +const int nc2=nc*2; +const int nc2ta=ncta*2; +const int tarray = nc*nl; +const int tarrayta = ncta*nlta; +const int tmarrayta = nc2ta*nlta; + +extern const int tmarray ; +extern char desfile[25]; +extern Serial pc; +extern unsigned char bank[]; +extern unsigned char bankf[]; +extern unsigned char bankt[nl][nc]; +extern unsigned char banktc[nl][nc]; +unsigned char bankta[nlta][ncta][nv]; +unsigned char banktatc[nlta][ncta]; + + + +extern Timer Time; +extern FILE *fp; +extern SPI_TFT_ILI9341 TFT; + +class imagetr +{ +public: + + void rgbtoy(void); + void rgbtoyta(void); + void rgbtoytaed(void); + void ytorgb(unsigned char b[nl][nc]); + void ytorgbta(unsigned char b[nlta][ncta][nv], int nu,const char des[]); + void ytorgbtas(unsigned char b[nlta][ncta][nv], int nu); + void extcont(int minc, int maxc); + void templatematch(unsigned char t); + void getimage(const char nf[]); + void extedge(int minc, int maxc, int th); + void extedgeta(int minc, int maxc, int th); + void affine (int x, int y, float a, float z); + void genta (float tx , float ty, float a, float z); + void lumi (float z); + void avera (void); + void extrta(void); + void searchpat(int th); + int ar(float a); + int BMP_tofile(unsigned int x, unsigned int y, const char *Name_BMP); + + +}; + +imagetr imagetr; + +//DigitalOut str(PB_3); // internal strobe for debug +//DigitalOut str1(PC_8); // internal strobe for debug +// int nl; +// int nc; + +//extern const int nlta; +//extern const int ncta; + + +/* +unsigned char bankt[nl][nc]; +unsigned char banktc[nl][nc]; +unsigned char bankta[nlta][ncta][nv]; +unsigned char banktatc[nlta][ncta]; +*/ +void imagetr::getimage( const char nf[]) +{ + fp = fopen(nf, "r"); + pc.printf("get %s\r\n", nf); + for (int i=0; i<tmarray; i++) { + + bank[i] =fgetc(fp); + } + fclose(fp); +} + +void imagetr::avera() +{ + int i,j,k,l, av; + for (i=1; i<nl-1; i=i+1) { + for (j=1; j<nc-1; j=j+1) { + av=0; + for (k=0; k<3; k++) { + for (l=0; l<3; l++) { + av=av+banktc[i-1+k][j-1+l]; + } + } + banktc[i][j]=av/9; + } + } +} + + +void imagetr::extrta() +{ + for (int i=120-nlta; i<120; i++) { + for (int j=0; j<ncta; j++) { + bankta[i-120+nlta][j][0]=banktc[i][j]; + } + } +} +int imagetr::ar(float a) +{ + int ai; + ai=a; + if (a-ai >=0.5f) { + return a+1; + } else { + return a; + } +} + +void imagetr::affine (int x, int y, float a, float z) +{ + float cosa, sina, tif, tjf, dx, dy ; + int ti,tj,i,j, tm1i, tm1j, til, tih, tjl, tjh; + cosa=cos(a); + sina=sin(a); + for (i=0; i<nl; i++) { + for (j=0; j<nc; j++) { + banktc[i][j]=25; + } + } + for (i=0; i<nl; i++) { + for (j=0; j<nc; j++) { + + dx=i-61; + dy=j-80; + tif=dx*cosa - dy*sina + 60; + tjf=dx*sina + dy*cosa + 80; + tif=tif-x; + tjf=tjf-y; + ti=ar((tif-60) * z + 60); + tj=ar((tjf-80) * z + 80 ); + tm1i =ti; + if (tm1i<0) { + tm1i=0; + } + if (tm1i>nl-1) { + tm1i=nl-1; + } + + dx=i-60; + dy=j-81; + tif=dx*cosa - dy*sina + 60; + tjf=dx*sina + dy*cosa + 80; + tif=tif-x; + tjf=tjf-y; + ti=ar((tif-60) * z + 60); + tj=ar((tjf-80) * z + 80 ); + tm1j =tj; + if (tm1j<0) { + tm1j=0; + } + if (tm1j>=nc) { + tm1j=nc-1; + } + + dx=i-60; + dy=j-80; + tif=dx*cosa - dy*sina + 60; + tjf=dx*sina + dy*cosa + 80; + tif=tif-x; + tjf=tjf-y; + ti=ar((tif-60) * z + 60); + tj=ar((tjf-80) * z + 80 ); + + if((ti>=0) && (tj >=0) && (ti <nl) && (tj < nc)) { + banktc[ti][tj]=bankt[i][j]; + if (ti> tm1i) { + til = tm1i; + tih = ti; + } else { + til =ti; + tih = tm1i; + } + + if (tj> tm1j) { + tjl = tm1j; + tjh = tj; + } else { + tjl =tj; + tjh = tm1j; + } + for (int k = til; k<tih+1; k++) { + for (int l = tjl; l<tjh+1; l++) { + banktc[k][l]=bankt[i][j]; + } + } + } + } + + } +} +void imagetr::genta (float tx, float ty, float a, float z) +{ + // generate multiple ta + float cosa, sina, tif, tjf, dx, dy ; + int ti,tj,i,j, tm1i, tm1j, til, tih, tjl, tjh; + cosa=cos(a); + sina=sin(a); + int nlta2=nlta/2; + int ncta2=ncta/2; + for (i=0; i<nlta; i++) { + for (j=0; j<ncta; j++) { + banktatc[i][j]=25; + } + } + for (i=0; i<nlta; i++) { + for (j=0; j<ncta; j++) { + + dx=(i-nlta2-1)*tx; + dy=(j-ncta2)*ty; + tif=dx*cosa - dy*sina + nlta2; + tjf=dx*sina + dy*cosa + ncta2; + ti=ar((tif-nlta2) * z + nlta2); + tj=ar((tjf-ncta2) * z + ncta2 ); + tm1i =ti; + if (tm1i<0) { + tm1i=0; + } + if (tm1i>nlta-1) { + tm1i=nlta-1; + } + dx=(i-nlta2)*tx; + dy=(j-ncta2-1)*ty; + tif=dx*cosa - dy*sina + nlta2; + tjf=dx*sina + dy*cosa + ncta2; + ti=ar((tif-nlta2) * z + nlta2); + tj=ar((tjf-ncta2) * z + ncta2 ); + tm1j =tj; + if (tm1j<0) { + tm1j=0; + } + if (tm1j>=ncta) { + tm1j=ncta-1; + } + + dx=(i-nlta2)*tx; + dy=(j-ncta2)*ty; + tif=dx*cosa - dy*sina + nlta2; + tjf=dx*sina + dy*cosa + ncta2; + ti=ar((tif-nlta2) * z + nlta2); + tj=ar((tjf-ncta2) * z + ncta2 ); + + if((ti>=0) && (tj >=0) && (ti <nlta) && (tj < ncta)) { + banktatc[ti][tj]=bankta[i][j][0]; + if (ti> tm1i) { + til = tm1i; + tih = ti; + } else { + til =ti; + tih = tm1i; + } + + if (tj> tm1j) { + tjl = tm1j; + tjh = tj; + } else { + tjl =tj; + tjh = tm1j; + } + for (int k = til; k<tih+1; k++) { + for (int l = tjl; l<tjh+1; l++) { + banktatc[k][l]=bankta[i][j][0]; + } + } + } + } + + } + +} +void imagetr::lumi (float z) +{ + int i,j; + for (i=0; i<nl; i++) { + for (j=0; j<nc; j++) { + banktc[i][j]=banktc[i][j]*z; + } + } +} + +void imagetr::rgbtoy(void) +{ + //transform bank in Y in table bankt + int R,G,G1,B,Y; + for (int i=0; i<tmarray; i=i+2) { + + R=(bank[i+1]>>3); + G=(bank[i+1]&0x07)<<3; + + G1=bank[i]>>5; + G= G|G1; + B=bank[i]&0x1f; + + Y=ar(0.299f*R+0.587f*G+0.114f*B); + //pc.printf("i:%d\r\n",i); + bankt[i/nc2][(i/2)%nc]=Y; + } +} +void imagetr::rgbtoyta(void) +{ + //transform bank in Y in table bankta, create muliple view + int R,G,G1,B,Y; + for (int i=0; i<tmarrayta; i=i+2) { + R=(bank[i+1]>>3); + G=(bank[i+1]&0x07)<<3; + + G1=bank[i]>>5; + G= G|G1; + B=bank[i]&0x1f; + + Y=ar(0.299f*R+0.587f*G+0.114f*B); + bankta[i/nc2ta][(i/2)%ncta][0]=Y; + } + + + genta (1, 1, 0.17, 1); // 10 deg + for (int i=0; i<nlta; i=i+1) { + for (int j=0; j<ncta; j=j+1) { + bankta[i][j][1]= banktatc[i][j]; + } + } + genta (1, 1, -0.17, 1); // -10 deg + for (int i=0; i<nlta; i=i+1) { + for (int j=0; j<ncta; j=j+1) { + bankta[i][j][2]= banktatc[i][j]; + } + } + genta (1, 1, 0, 0.8); // zoom 0.8 + for (int i=0; i<nlta; i++) { + for (int j=0; j<ncta; j=j+1) { + bankta[i][j][3]= banktatc[i][j]; + } + } + genta (1, 1, 0, 1.20); // zoom 1.2 + for (int i=0; i<nlta; i++) { + for (int j=0; j<ncta; j=j+1) { + bankta[i][j][4]= banktatc[i][j]; + } + }/* + genta (0.9, 1, 0, 1); + for (int i=0; i<nlta; i=i+1) { + for (int j=0; j<ncta; j=j+1) { + // pc.printf("i %d, j %d b %02x\r\n", i, j, bankta[i][j][0]); + bankta[i][j][5]= banktatc[i][j]; + } + } + //pc.printf("ty\r\n"); + genta (1, 0.9, 0, 1); + for (int i=0; i<nlta; i=i+1) { + for (int j=0; j<ncta; j=j+1) { + bankta[i][j][6]= banktatc[i][j]; + } + }*/ +} + + +void imagetr::rgbtoytaed(void) +{ + //transform bank in Y in table bankta, create muliple view + int R,G,G1,B,Y; + for (int i=0; i<tmarrayta; i=i+2) { + R=(bank[i+1]>>3); + G=(bank[i+1]&0x07)<<3; + + G1=bank[i]>>5; + G= G|G1; + B=bank[i]&0x1f; + + Y=ar(0.299f*R+0.587f*G+0.114f*B); + bankta[i/nc2ta][(i/2)%ncta][0]=Y; + } + + extedgeta(0,0,2); + + for (int i=0; i<nlta; i=i+1) { + for (int j=0; j<ncta; j=j+1) { + bankta[i][j][0]= banktatc[i][j]; + } + } + + genta (1, 1, 0.17, 1); // 10 deg + for (int i=0; i<nlta; i=i+1) { + for (int j=0; j<ncta; j=j+1) { + bankta[i][j][1]= banktatc[i][j]; + } + } + genta (1, 1, -0.17, 1); // -10 deg + for (int i=0; i<nlta; i=i+1) { + for (int j=0; j<ncta; j=j+1) { + bankta[i][j][2]= banktatc[i][j]; + } + } + genta (1, 1, 0, 0.8); // zoom 0.8 + for (int i=0; i<nlta; i++) { + for (int j=0; j<ncta; j=j+1) { + bankta[i][j][3]= banktatc[i][j]; + } + } + genta (1, 1, 0, 1.20); // zoom 1.2 + for (int i=0; i<nlta; i++) { + for (int j=0; j<ncta; j=j+1) { + bankta[i][j][4]= banktatc[i][j]; + } + }/* + genta (0.9, 1, 0, 1); + for (int i=0; i<nlta; i=i+1) { + for (int j=0; j<ncta; j=j+1) { + // pc.printf("i %d, j %d b %02x\r\n", i, j, bankta[i][j][0]); + bankta[i][j][5]= banktatc[i][j]; + } + } + //pc.printf("ty\r\n"); + genta (1, 0.9, 0, 1); + for (int i=0; i<nlta; i=i+1) { + for (int j=0; j<ncta; j=j+1) { + bankta[i][j][6]= banktatc[i][j]; + } + }*/ +} + + + + +void imagetr::ytorgb(unsigned char b[nl][nc]) +{ + //populate bank with table b + int R,G,G1,B,Y; + for (int i=0; i<tarray; i=i+1) { + + Y=b[i/nc][i%nc]; + // Y=Y*yco; + R=Y*0.71; + if (R>31) { + R=31; + } + G=Y*1.45; + if (G>63) { + G=63; + } + B=R; + G1=G>>3; + bank[2*i+1]=R<<3|G1; + bank[2*i]=G<<5|B; + } +} + +void imagetr::ytorgbta(unsigned char b[nlta][ncta][nv], int nu,const char des[]) +{ + //p0pulate bankf with table b special target, write targetf.txt + int R,G,G1,B,Y; + fp = fopen(des, "w"); + for (int j=0; j<tmarray; j++) { + bank[j]=25; + } + for (int i=0; i<tarrayta; i=i+1) { + + Y=b[i/ncta][i%ncta][nu]; + // Y=Y*yco; + R=Y*0.71; + if (R>31) { + R=31; + } + G=Y*1.45; + if (G>63) { + G=63; + } + B=R; + G1=G>>3; + bank[2*i+1]=R<<3|G1; + bank[2*i]=G<<5|B; + fputc(bank[2*i], fp); + fputc(bank[2*i+1], fp); + + } + fclose(fp); +} +void imagetr::ytorgbtas(unsigned char b[nlta][ncta][nv], int nu) +{ + //p0pulate bank with table b special target, without write targetfile + int R,G,G1,B,Y; + + for (int j=0; j<tmarray; j++) { + bank[j]=25; + } + for (int i=0; i<tarrayta; i=i+1) { + + Y=b[i/ncta][i%ncta][nu]; + // Y=Y*yco; + R=Y*0.71; + if (R>31) { + R=31; + } + G=Y*1.45; + if (G>63) { + G=63; + } + B=R; + G1=G>>3; + bank[2*i+1]=R<<3|G1; + bank[2*i]=G<<5|B; + } +} + +void imagetr::extcont(int minc, int maxc) +{ + // contrast expand + int Y; + for (int i=0; i<tarray; i=i+1) { + + Y=bankt[i/nc][i%nc]; + if (Y<=minc) { + Y=0; + } + if (Y>=maxc) { + Y=50; + } + banktc[i/nc][i%nc]=Y; + } +} +void imagetr::extedge(int minc, int maxc, int th) +{ + //edge extract + int Y,YG,YH,i,j; + int M=0; + for (i=0; i<nl; i++) { + for (j=0; j<nc; j++) { + M=M+bankt[i][j]; + + } + } + M=M/tarray; + // if (M>maxc ||M<minc) { + // th=1; + // } else { + // th=4; + // } + // th=6*M/minc; + // pc.printf( "M: %d th %d: minc: %d maxc; %d \r\n",M,th, minc, maxc); + for (i=1; i<nl; i++) { + for (j=1; j<nc; j++) { + Y=bankt[i][j]; + YG=bankt[i][j-1]; + YH=bankt[i-1][j]; + if (abs(Y-YG) >th||abs(Y-YH) >th) { + Y=50; + } else { + Y=0; + } + banktc[i][j]=Y; + } + } +} +void imagetr::extedgeta(int minc, int maxc, int th) +{ + //edge extract + int Y,YG,YH,i,j; + int M=0; + for (i=0; i<nlta; i++) { + for (j=0; j<ncta; j++) { + M=M+bankta[i][j][0]; + + } + } + M=M/tarray; + // if (M>maxc ||M<minc) { + // th=1; + // } else { + // th=4; + // } + // th=6*M/minc; + // pc.printf( "M: %d th %d: minc: %d maxc; %d \r\n",M,th, minc, maxc); + for (i=1; i<nlta; i++) { + for (j=1; j<ncta; j++) { + Y=bankta[i][j][0]; + YG=bankta[i][j-1][0]; + YH=bankta[i-1][j][0]; + if (abs(Y-YG) >th||abs(Y-YH) >th) { + Y=50; + } else { + Y=0; + } + banktatc[i][j]=Y; + } + } +} + + +void imagetr::searchpat(int th) +{ + int i,j,k, l, maxi, maxj; + int car, tt,n0,n; + int max ; + max =th; + n0=0; + Time.start(); + for (n=0; n<=nv; n++) { + for (i =0 ; i < nl-nlta; i++) { + for (j=0; j<nc-ncta; j++) { + tt=0; + for (k=0; k<nlta; k++) { + for (l=0; l<ncta; l++) { + car= bankta[k][l][n]-banktc[i+k][j+l]; + tt=tt+car*car; + if (tt>th) { + k =nlta; + l=ncta; + } + } + } + max=tt; + // pc.printf("1 n: %d max: %d time: %f \r\n",n0,max, Time.read()); + + if (max<th) { + maxi=i; + maxj=j; + n0=n; + i=nl; + j=nc; + n=nv; + // pc.printf("2 line: %d, column: %d, n: %d max: %d time: %f \r\n",maxi,maxj,n0,max, Time.read()); + } + } + } + } + Time.stop(); + TFT.Bitmap(160,120,160,120,bank); + if (tt<th) { + pc.printf("line: %d, column: %d, n: %d max: %d time: %f \r\n",maxi,maxj,n0,max, Time.read()); + TFT.locate(160,20); + printf("Pat found %3.2f s",Time.read()); + TFT.locate(160+maxj+(ncta/2),240-maxi-(nlta/2)); + printf("X"); + TFT.rect(160+maxj,240-maxi-nlta,160+maxj+ncta,240-maxi,Red); + } else { + TFT.locate(160,20); + printf("Not found %3.2f s",Time.read()); + pc.printf("not found time: %4f n:%d max: %d \r\n",Time.read(), n0,max); + } + Time.reset(); +} + +int imagetr::BMP_tofile(unsigned int x, unsigned int y, const char *Name_BMP) +{ + +#define OffsetPixelWidth 18 +#define OffsetPixelHeigh 22 +#define OffsetFileSize 34 +#define OffsetPixData 10 +#define OffsetBPP 28 + + char filename[50]; + unsigned char BMP_Header[54]; + unsigned short BPP_t; + unsigned int PixelWidth,PixelHeigh,start_data; + unsigned int i,off; + int padd,j; + unsigned short *line; + + // get the filename + i=0; + while (*Name_BMP!='\0') { + filename[i++]=*Name_BMP++; + } + filename[i] = 0; + + FILE *Image = fopen((const char *)&filename[0], "rb"); // open the bmp file + if (!Image) { + return(0); // error file not found ! + } + + fread(&BMP_Header[0],1,54,Image); // get the BMP Header + + if (BMP_Header[0] != 0x42 || BMP_Header[1] != 0x4D) { // check magic byte + fclose(Image); + return(-1); // error no BMP file + } + + BPP_t = BMP_Header[OffsetBPP] + (BMP_Header[OffsetBPP + 1] << 8); + if (BPP_t != 0x0010) { + fclose(Image); + return(-2); // error no 16 bit BMP + } + + PixelHeigh = BMP_Header[OffsetPixelHeigh] + (BMP_Header[OffsetPixelHeigh + 1] << 8) + (BMP_Header[OffsetPixelHeigh + 2] << 16) + (BMP_Header[OffsetPixelHeigh + 3] << 24); + PixelWidth = BMP_Header[OffsetPixelWidth] + (BMP_Header[OffsetPixelWidth + 1] << 8) + (BMP_Header[OffsetPixelWidth + 2] << 16) + (BMP_Header[OffsetPixelWidth + 3] << 24); + if (PixelHeigh > TFT.height() + y || PixelWidth > TFT.width() + x) { + fclose(Image); + return(-3); // to big + } + + start_data = BMP_Header[OffsetPixData] + (BMP_Header[OffsetPixData + 1] << 8) + (BMP_Header[OffsetPixData + 2] << 16) + (BMP_Header[OffsetPixData + 3] << 24); + + line = (unsigned short *) malloc (2 * PixelWidth); // we need a buffer for a line + if (line == NULL) { + return(-4); // error no memory + } + + // the bmp lines are padded to multiple of 4 bytes + padd = -1; + do { + padd ++; + } while ((PixelWidth * 2 + padd)%4 != 0); + + // GraphicsDisplay.window(x, y,PixelWidth ,PixelHeigh); + //GraphicsDisplay.wr_cmd(0x2C); // send pixel + //GraphicsDisplay.spi_16(1); + int compt=38400; + unsigned char c,c1; + for (j = PixelHeigh - 1; j >= 0; j--) { //Lines bottom up + off = j * (PixelWidth * 2 + padd) + start_data; // start of line + fseek(Image, off ,SEEK_SET); + fread(line,1,PixelWidth * 2,Image); // read a line - slow + // for (i = 0; i < PixelWidth; i++) { // copy pixel data to TFT + for (int i = PixelWidth-1; i >=0; i--) { // copy pixel data to TFT + compt = compt -1; + c=line[i]&0x00FF; + c1=line[i]>>8; + bank[compt] =c1 ; + compt = compt -1; + bank[compt] =c; // one 16 bit pixel + } + } + //spi_bsy(); + //_cs = 1; + //spi_16(0); + free (line); + fclose(Image); + //WindowMax(); + return(1); +} + + +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/main.cpp Tue Feb 16 14:28:55 2016 +0000 @@ -0,0 +1,756 @@ +#include "mbed.h" +#include "global.h" +#include "FastPWM.h" +#include "imagetr.h" +#include "ov7670s.h" +#include "ov7670sreg.h" +#include "SPI_TFT_ILI9341.h" +#include "SDFileSystem.h" + +#define SCTFT PA_5 // sclk TFT +#define MISOTFT PA_6 //miso TFT +#define MOSITFT PA_7 //Mosi tft +#define PA9 PA_9 // dc TFT +#define PB6 PB_6 // cs TFT +#define PA11 PA_11 // reset TFT pc7 + +#define PCLK PC_10 //camera Pixel clock PB13 +#define HREF PC_11 //camera Href +#define VSYNC PC_12 // camera Vsync +#define I2C_D PB_3 // Camera SCCB port data +#define I2C_CLK PB_10 // Camera SCCB port clock +#define RESET PB_12 // camera reset +#define XCLK PA_10 // camera system clock + + +#define mD0 PC_2//camera Data +#define mD1 PC_3//camera Data +#define mD2 PC_4//camera Data +#define mD3 PC_5//camera Data +#define mD4 PC_6//camera Data +#define mD5 PC_7//camera Data +#define mD6 PC_8 // camera Data +#define mD7 PC_9 //camera Data + + +#define SCSD PB_13 // sclk SD +#define MISD PB_14 // miso SD +#define MOSD PB_15 // mosi SD + +#define PD2 PD_2 /: CS SD + + +#define VGA 307200 //640*480 +#define QVGA 76800 //320*240 +#define QQVGA 19200 //160*120 + + +DigitalOut myled(LED1); +InterruptIn my_button(USER_BUTTON); +AnalogIn analog_value0(A0); +AnalogIn analog_value1(A1); +AnalogIn analog_value2(A2); +AnalogIn analog_value3(A3); + +Timer Time; + +int mask =0x1FFC; + + +Serial pc(USBTX,USBRX); +//camera +OV7670 OV7670(I2C_D,I2C_CLK,XCLK,PortC,mask,RESET); + +// the TFT is connected to SPI pin +SPI_TFT_ILI9341 TFT(MOSITFT, MISOTFT, SCTFT, PB6, PA11, PA9,"TFT"); // mosi, miso, sclk, cs, reset, dc +// LED on 3.3V with 1Kohm + +SDFileSystem sd(MOSD, MISD, SCSD, PD_2, "sd",NC,SDFileSystem::SWITCH_NONE,2500000); // mosi, miso, sclk, cs, cd unused, switchtype, speed spi +// image transformation +//imagetr imagetr; + +char desfile[25]; +char patfile[25]; +char filename[25]; +const int tmarray = nc*2*nl; +unsigned char bank[tmarray]; +unsigned char bankt[nl][nc]; +unsigned char bankf[tmarray]; +unsigned char banktc[nl][nc]; + + +float meas0,measold0,meas1,measold1,meas2,measold2, meas3, measold3; + +int volatile statc=0; +bool volatile captur =false; +FILE *fp; + +void pressed() +{ + wait (0.1); + if (my_button==0) { + if (statc==0) { + pc.printf("capture requested\r\n"); + captur=true; + TFT.foreground(Red); + TFT.locate(0,0); + } + if (statc==1) { + pc.printf("visu \r\n"); + fp = fopen(desfile, "r"); + for (int i=0; i<tmarray; i++) { + bankf[i] =fgetc(fp); + } + fclose(fp); + + } + if (statc==2) { + statc=0; + } else { + statc=statc+1; + } + } +} +void pressedtargnewca() +{ + //start from first image cat extract target in desfile + wait (0.1); + if (my_button==0) { + if (statc==0) { + pc.printf("capture target requested \r\n"); + //imagetr.rgbtoy(); + imagetr.ytorgb(banktc); + fp = fopen(desfile, "w"); + for (int i=0; i<tmarray; i++) { + fputc(bank[i], fp); + } + TFT.Bitmap(160,0,160,120,bank); + pc.printf("captured target done \r\n"); + TFT.foreground(Green); + TFT.locate(0,0); + printf(" capture done"); + fclose(fp); + pc.printf("open target file \r\n"); + fp = fopen(desfile, "r"); + for (int i=0; i<tmarray; i++) { + bank[i] =fgetc(fp); + } + fclose(fp); + TFT.Bitmap(0,120,160,120,bank); + imagetr.rgbtoy(); + imagetr.ytorgb(bankt); + + } + if (statc==1) { + printf(" target capture done"); + imagetr.extrta(); + imagetr.ytorgbta(bankta,0,patfile); + TFT.fillrect(160,0,160,240,Green); + TFT.Bitmap(160,10,ncta,nlta,bank); + pc.printf("clear bank \r\n"); + for (int i=0; i<tmarray; i++) { + bank[i]=78; + } + fp = fopen(patfile, "r"); + pc.printf("get targetf \r\n"); + for (int i=0; i<tmarrayta; i++) { + bank[i] =fgetc(fp); + } + fclose(fp); + imagetr.rgbtoyta(); + for (int i = 0; i<7; i++) { + imagetr.ytorgbtas(bankta,i); + TFT.Bitmap(40*(i/3),120+30* (i%3),ncta,nlta,bank); + } + } + if (statc==2) { + statc=0; + } else { + statc=statc+1; + + } + pc.printf("new s:%d \r\n", statc); + } +} + +void pressedtargca() +{ + //start from first image from camera extract + wait (0.1); + if (my_button==0) { + if (statc==0) { + + pc.printf("view \r\n"); + + } + if (statc==1) { + pc.printf("search \r\n"); + } + if (statc==2) { + statc=0; + } else { + statc=statc+1; + + } + } +} + + +void sdtofile(const char sou[],const char des[]) +{ + pc.printf("open .bmp \r\n"); + int err = imagetr.BMP_tofile(0, 0, sou); + if (err != 1) TFT.printf(" - Err: %d",err); + TFT.Bitmap(0,0,160,120,bank); + + pc.printf("open .txt in write \r\n"); + fp = fopen(des, "w"); + + for (int i=0; i<tmarray; i++) { + fputc(bank[i], fp); + } + fclose(fp); + pc.printf("open .txt in read \r\n"); + fp = fopen(des, "r"); + for (int i=0; i<tmarray; i++) { + bank[i] =fgetc(fp); + } + fclose(fp); + TFT.Bitmap(0,120,160,120,bank); +} +void pressedtargsd() +{ + //start from first image in bankt extract target in bankta generate different target + wait (0.1); + if (my_button==0) { + + imagetr.extrta(); + imagetr.ytorgbta(bankta,0,desfile); + TFT.Bitmap(160,10,ncta,nlta,bank); + TFT.fillrect(0,120,160,240,Green); + pc.printf("clear bank \r\n"); + for (int i=0; i<tmarray; i++) { + bank[i]=78; + } + fp = fopen(desfile, "r"); + pc.printf("get targetf \r\n"); + for (int i=0; i<tmarrayta; i++) { + bank[i] =fgetc(fp); + } + fclose(fp); + imagetr.rgbtoyta(); + TFT.Bitmap(0,120,ncta,nlta,bank); + for (int i = 0; i<7; i++) { + imagetr.ytorgbtas(bankta,i); + TFT.Bitmap(40*(i/3),120+30* (i%3),ncta,nlta,bank); + } + //sdtofile(des); + } +} + +void affinem(bool rec) +{ + bool c = false; + float ad; + meas0 = analog_value0.read(); // Converts and read the analog input value (value from 0.0 to 1.0) + meas0 = meas0 * 320-160 ; // x colonnes + if( fabs(meas0-measold0)>1 ) { + measold0=meas0; + c=true; + } + meas1 = analog_value1.read(); // Converts and read the analog input value (value from 0.0 to 1.0) + meas1 = meas1 * 240 -120; // y lines + if( fabs(meas1-measold1)>1 ) { + measold1=meas1; + c=true; + } + + meas2 = analog_value2.read(); // Converts and read the analog input value (value from 0.0 to 1.0) + meas2 = meas2 -0.5f; // angle -0.5 a +0.5 (radiant) + if( fabs(meas2-measold2)>0.1f ) { + measold2=meas2; + c=true; + } + meas3 = analog_value3.read(); // Converts and read the analog input value (value from 0.0 to 1.0) + meas3 = 0.5f + (meas3 * 1.5f); // zoom max1.5 + if( fabs(meas3-measold3)>0.5f ) { + measold3=meas3; + c=true; + } + if(c) { + + ad=180*meas2/3.14f; + TFT.foreground(White); + pc.printf("x: %d, y: %d, angle: %.2f zoom: %.2f \r\n", int(meas0),int(meas1), meas2, meas3); + TFT.locate(170,45); + printf("x %d",int(meas0)); + TFT.locate(170,65); + printf("y %d",int(meas1)); + TFT.locate(170,105); + printf("zoom %.2f",meas3); + TFT.locate(170,85); + printf("angle %.2f",ad); + // imagetr.affine(0,0,0, 1.2); + imagetr.affine(meas1,meas0,meas2, meas3); + if (rec) { + TFT.rect(160,120,160+ncta,120+nlta,Red); + } + } +} +void gentam(void) +{ + bool c = false; + float ad; + meas0 = analog_value0.read(); // Converts and read the analog input value (value from 0.0 to 1.0) + meas0 = meas0 * 0.2f + 0.8f; // tilt x 0-20% + if( fabs(meas0-measold0)>0.05f ) { + measold0=meas0; + c=true; + } + meas1 = analog_value1.read(); // Converts and read the analog input value (value from 0.0 to 1.0) + meas1 = meas1 * 0.2f+0.8f; // tilt y lines 0-20% + if( fabs(meas1-measold1)>0.05f ) { + measold1=meas1; + c=true; + } + + meas2 = analog_value2.read(); // Converts and read the analog input value (value from 0.0 to 1.0) + meas2 = meas2 -0.5f; // angle -0.5 a +0.5 (radiant) + if( fabs(meas2-measold2)>0.1f ) { + measold2=meas2; + c=true; + } + meas3 = analog_value3.read(); // Converts and read the analog input value (value from 0.0 to 1.0) + meas3 = 0.5f + (meas3 * 1.5f); // zoom max1.5 + if( fabs(meas3-measold3)>0.3f ) { + measold3=meas3; + c=true; + } + if(c) { + ad=180*meas2/3.14f; + TFT.foreground(White); + //pc.printf("x: %d, y: %d, angle: %.2f zoom: %.2f \r\n", int(meas0),int(meas1), meas2, meas3); + TFT.locate(170,45); + printf("tiltx %2f",meas0); + TFT.locate(170,65); + printf("tilty %2f",meas1); + TFT.locate(170,105); + printf("zoom %.2f",meas3); + TFT.locate(170,85); + printf("angle %.2f",ad); + // imagetr.affine(0,0,0, 1.2); + imagetr.genta(meas1,meas0,meas2, meas3); + } +} + + + +void luma(void) +{ + float meas,measold; + meas = analog_value3.read(); // Converts and read the analog input value (value from 0.0 to 1.0) + meas = meas * 3; // 0 a 10 + if( fabs(meas-measold)>0.1f ) { + pc.printf("lumi: %04f \r\n", meas); + TFT.locate(170,85); + TFT.foreground(White); + printf("lumi %f",meas); + imagetr.lumi(meas); + measold=meas; + } + +} + +void searchp(void) +{ + bool c = false; + float ad; + meas0 = analog_value0.read(); // Converts and read the analog input value (value from 0.0 to 1.0) + meas0 = meas0 * 320-160 ; // x colonnes + if( fabs(meas0-measold0)>1 ) { + measold0=meas0; + c=true; + + } + meas1 = analog_value1.read(); // Converts and read the analog input value (value from 0.0 to 1.0) + meas1 = meas1 * 1000000; // 0 a 4000 + if( fabs(meas1-measold1)>200 ) { + c=true; + } + + meas2 = analog_value2.read(); // Converts and read the analog input value (value from 0.0 to 1.0) + meas2 = meas2 -0.5f; // angle -0.5 a +0.5 (radiant) + if( fabs(meas2-measold2)>0.1f ) { + measold2=meas2; + c=true; + } + meas3 = analog_value3.read(); // Converts and read the analog input value (value from 0.0 to 1.0) + meas3 = 0.5f + (meas3 * 1.5f); // zoom max1.5 + if( fabs(meas3-measold3)>0.5f ) { + measold3=meas3; + c=true; + } + if(c) { + ad=180*meas2/3.14f; + TFT.foreground(White); + //pc.printf("x: %d, y: %d, angle: %.2f zoom: %.2f \r\n", int(meas0),int(meas1), meas2, meas3); + TFT.locate(170,45); + printf("x %3d",int(meas0)); + TFT.locate(170,65); + printf("threshold %6d",int(meas1)); + TFT.locate(170,105); + printf("zoom %.2f",meas3); + TFT.locate(170,85); + printf("angle %.2f",ad); + imagetr.affine(0,meas0,meas2, meas3); + imagetr.searchpat(meas1); + } +} +void viewf(void) +{ + imagetr.ytorgb(banktc); + TFT.Bitmap(160,120,160,120,bank); +} + +void extedgem(void) +{ + bool c = false; + meas0 = analog_value0.read(); // Converts and read the analog input value (value from 0.0 to 1.0) + meas0 = meas0 * 50; // 0 to 50 max threshod + if( fabs(meas0-measold0)>1) { + measold0=meas0; + c=true; + } + meas1 = analog_value1.read(); // Converts and read the analog input value (value from 0.0 to 1.0) + meas1 = meas1 * 50 ; // min threshold 0 50 + if( fabs(meas1-measold1)>1 ) { + measold1=meas1; + c=true; + } + meas2 = analog_value2.read(); // Converts and read the analog input value (value from 0.0 to 1.0) + meas2 = meas2 * 5 ; // thrshold + if( fabs(meas2-measold2)>1 ) { + measold2=meas2; + c=true; + } + + if (c) { + //pc.printf("x: %d, y: %d \r\n", int(meas0),int(meas1)); + imagetr.extedge(meas1,meas0, meas2); + } +} +void loadtargettxt(const char sou[]) +{ + imagetr.getimage(sou); + TFT.Bitmap(0,0,160,120,bank); + imagetr.rgbtoy(); + imagetr.ytorgb(bankt); + TFT.Bitmap(160,120,160,120,bank); +} + +void loadtarget(const char sou[]) +{ + int err = imagetr.BMP_tofile(0, 0, sou); + if (err != 1) TFT.printf(" - Err: %d",err); + TFT.Bitmap(0,0,160,120,bank); + imagetr.rgbtoy(); + //imagetr.ytorgb(bankt); + //TFT.Bitmap(160,120,160,120,bank); +} +void loadtargeted(const char sou[]) +{ + int err = imagetr.BMP_tofile(0, 0, sou); + if (err != 1) TFT.printf(" - Err: %d",err); + TFT.Bitmap(0,0,160,120,bank); + imagetr.rgbtoy(); + imagetr.extedge(0,0,2); + for (int i=0; i<nl; i=i+1) { + for (int j=0; j<nc; j=j+1) { + bankt[i][j]= banktc[i][j]; + } + } + imagetr.ytorgb(bankt); + TFT.Bitmap(160,120,160,120,bank); +} +void loadpat(const char pat[]) +{ + imagetr.getimage(pat); + TFT.Bitmap(160,0,ncta,nlta,bank); + imagetr.rgbtoyta(); + for (int i = 0; i<7; i++) { + imagetr.ytorgbtas(bankta,i); + TFT.Bitmap(40*(i/3),120+30* (i%3),ncta,nlta,bank); + } +} +void loadpated(const char pat[]) +{ + imagetr.getimage(pat); + TFT.Bitmap(160,0,ncta,nlta,bank); + imagetr.rgbtoytaed(); + for (int i = 0; i<7; i++) { + imagetr.ytorgbtas(bankta,i); + TFT.Bitmap(40*(i/3),120+30* (i%3),ncta,nlta,bank); + } +} +void readregister() +{ + int tempo ; + pc.printf("PID %02x \r\n", OV7670.ReadReg(REG_PID)); + pc.printf("VER %0.2x \r\n", OV7670.ReadReg(REG_VER)); + + pc.printf("Lecture Registres...\r\n") ; + pc.printf("AD : +0 +1 +2 +3 +4 +5 +6 +7 +8 +9 +A +B +C +D +E +F") ; + for (int i=0; i<OV7670_REGMAX; i++) { + + tempo = OV7670.ReadReg(i) ; // READ REG + if ((i & 0x0F) == 0) { + pc.printf("\r\n%02X : ",i) ; + } + pc.printf("%02X ",tempo) ; + } + pc.printf("\r\n") ; +} +void testsd(void) +{ + //Perform a write test to SD + // Set up the SD + sd.disk_initialize(); + pc.printf("\nWriting to SD card..."); + fp = fopen("/sd/sdtest.txt", "w"); + if (fp != NULL) { + fprintf(fp, "We're writing to an SD card!"); + fclose(fp); + pc.printf("success!\r\n"); + } else { + pc.printf("failed!\r\n"); + } + //Perform a read test + pc.printf("Reading from SD card..."); + fp = fopen("/sd/sdtest.txt", "r"); + if (fp != NULL) { + char c = fgetc(fp); + if (c == 'W') + pc.printf("success!\r\n"); + else + pc.printf("incorrect char (%c)!\r\n", c); + fclose(fp); + } else { + pc.printf("failed!\r\n"); + } +} + +void capturecycle(const char des[]) +{ + strcpy( desfile,des); + if (statc==0||statc==1) { + OV7670.CaptureNext() ; + OV7670.exrgbf(0); + TFT.Bitmap(0,120,160,120,bankf); + OV7670.exrgbf(1); + TFT.Bitmap(160,120,160,120,bankf); + OV7670.exrgbf(2); + TFT.Bitmap(0,0,160,120,bankf); + OV7670.exrgbf(3); + TFT.Bitmap(160,0,160,120,bankf); + } + if (statc==2) { + OV7670.CaptureNext() ; + TFT.fillrect(0,120,160,240,Green); + TFT.fillrect(160,0,320,120,Green); + TFT.foreground(Yellow); + TFT.locate(170,108); + printf("captured picture"); + TFT.Bitmap(0,0,160,120,bank); + TFT.Bitmap(160,120,160,120,bankf); + } +} + + +void epatternmatch(const char tar[],const char pat[]) +{ + int i=0; + loadtarget(tar); + loadpat(pat); + for (i=0; i<25; i++) { + filename[i]=pat[i+4]; + } + + pc . printf("f : %s\r\n", filename); + TFT.set_font((unsigned char*) Arial12x12); + TFT.foreground(Red); +} +void epatternmatched(const char tar[],const char pat[]) +{ + int i=0; + loadtargeted(tar); + loadpated(pat); + for (i=0; i<25; i++) { + filename[i]=pat[i+4]; + } + pc . printf("f : %s\r\n", filename); + TFT.set_font((unsigned char*) Arial12x12); + TFT.foreground(Red); +} +void epatca(const char tar[],const char pat[]) +{ + loadtargettxt(tar); + loadpat(pat); + TFT.set_font((unsigned char*) Arial12x12); + TFT.foreground(Red); +} +void patternmatch(const char pat[]) +{ + my_button.fall(&pressedtargca); + OV7670.CaptureNext() ; + TFT.Bitmap(0,0,160,120,bank); + loadpat(pat); + TFT.set_font((unsigned char*) Arial12x12); + TFT.foreground(Red); +} + +void targetfromca(const char des[],const char pat[]) +{ + OV7670.CaptureNext() ; + TFT.Bitmap(0,0,160,120,bank); + imagetr.rgbtoy(); + strcpy( desfile,des); + strcpy( patfile,pat); + my_button.fall(&pressedtargnewca); +} +void loadnewca() +{ + OV7670.CaptureNext() ; + TFT.Bitmap(0,0,160,120,bank); + imagetr.rgbtoy(); +} + +void targetfromsd(const char sou[],const char des[]) +{ + int err = imagetr.BMP_tofile(0, 0, sou); + if (err != 1) pc.printf(" - Err: %d",err); + TFT.Bitmap(0,0,160,120,bank); + imagetr.rgbtoy(); + strcpy( desfile,des); + TFT.rect(160,120,160+ncta,120+nlta,Red); + my_button.fall(&pressedtargsd); +} + + +int main() +{ + myled=0; + statc=0; + + + // Set up the TFT + TFT.claim(stdout); // Send stdout to the TFT display + TFT.background(Black); // Set background to black + TFT.foreground(White); // Set chars to white + TFT.cls(); // Clear the screen + TFT.set_font((unsigned char*) Arial12x12); // Select the font + TFT.set_orientation(3); // Select orientation + TFT.locate(0,0); + printf(" Hello Mbed "); + OV7670.Reset(); + OV7670.Init("RGB", QQVGA); + pc.printf("Hello World !\r\n"); +////////////////////////////////////////////////////////// +// to view camera + + my_button.fall(&pressed); + + while (1) { + capturecycle("/sd/picture.txt"); + } +} + +////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////// +// to create a target from a .bmp to sd +/* + targetfromsd("/sd/manchodou.bmp","/sd/manchodou.txt"); + while (1) { + viewf(); + __disable_irq(); // Disable Interrupts + affinem(true); + __enable_irq(); // Enable Interrupts + } +} +*/ +////////////////////////////////////////////////////////// +// to recognise a target from bmp and target on sd +/* + epatternmatch("/sd/manchodou.bmp","/sd/manchodou.txt"); + while (1) { + viewf(); + searchp(); + } + } + */ +////////////////////////////////////////////////////////// +////////////////////////////////////////////////////////// +// to recognise a target from bmp and target on sd, on edge +/* + epatternmatched("/sd/manchodou.bmp","/sd/manchodou.txt"); + while (1) { + + viewf(); + searchp(); + } +} +*/ +////////////////////////////////////////////////////////// +//to create a target from camera +/* + targetfromca("/sd/man.txt","/sd/man2.txt"); + while (1) { + + __disable_irq(); // Disable Interrupts + if (statc==0) { + loadnewca(); + } + + affinem(true); + __enable_irq(); // Enable Interrupts + +// if (statc==0) { searchp();} else {affinem(false);} + viewf(); + + } +} +*/ +//////////////////////////////////////////// +//to search pattern from .txt +/* + epatca("/sd/man.txt","/sd/man2.txt"); + while (1) { + viewf(); + searchp(); + } +} +*/ +//////////////////////////////////////////// +//to search pattern from camera +/* + patternmatch("/sd/man2.txt"); + while (1) { + loadnewca(); + viewf(); + if (statc==0) { + searchp(); + } else { + affinem(false); + } + } +} +*/ +//////////////////////////////////////////// +// to extract edge from image in bmp +/* + loadtarget("/sd/manchodou.bmp"); + while (1) { + viewf(); + extedgem(); + } +} +*/ \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed.bld Tue Feb 16 14:28:55 2016 +0000 @@ -0,0 +1,1 @@ +http://mbed.org/users/mbed_official/code/mbed/builds/6f327212ef96 \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ov7670s.lib Tue Feb 16 14:28:55 2016 +0000 @@ -0,0 +1,1 @@ +https://developer.mbed.org/users/sylvainkritter/code/ov7670s/#2530e24fafa1