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);
}