image transformation and pattern matching (very basic)
Dependents: mycame Practica4_Camara
imagetr.cpp
- Committer:
- sylvainkritter
- Date:
- 2016-02-17
- Revision:
- 0:7e50b328a66f
File content as of revision 0:7e50b328a66f:
#pragma once
#include "mbed.h"
#include "global.h"
#include "imagetr.h"
#include "SDFileSystem.h"
#include "SPI_TFT_ILI9341.h"
//DigitalOut str(PB_3); // internal strobe for debug
//DigitalOut str1(PC_8); // internal strobe for debug
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, char name[])
{
int i,j,k, l, maxi, maxj, car, tt,n;
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) {
break;
}
}
}
if (tt<th) {
maxi=i;
maxj=j;
i=nl;
j=nc;
n=nv;
}
}
}
}
Time.stop();
if (tt<th) {
//pc.printf("line: %d, column: %d, n: %d max: %d time: %f \r\n",maxi,maxj,n0,tt, Time.read());
TFT.locate(160,20);
printf("Pat found %4.2f s",Time.read());
TFT.locate(160+maxj+(ncta/2),240-maxi-(nlta/2));
printf(name);
TFT.rect(160+maxj,240-maxi-nlta,160+maxj+ncta,240-maxi,Red);
} else {
TFT.locate(160,20);
printf("Not found %4.2f s",Time.read());
//pc.printf("not found time: %4f n:%d max: %d \r\n",Time.read(), n0,tt);
}
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);
}