[Back]
     /*  Code  */
/*This File contain the all of the code the we had used in this
project,Here we had written sufficient ammount of comments that will help
you in understanding the code. or you can download the tar file of the code from here.*/

/* This part contain the whole includes files */

#include<stdio.h>
#include<math.h>
#include<pgm.h>
#include<string.h>

/*This contain all the defines that will be used in the programme*/

#define PI 3.1415927
#define INCREASE 1
#define CONSTANT 0
#define DECREASE -1
#define FALSE 0
#define MAX_THETA 15                 //Max value -15 to +15
#define WHITE 255                         //have to be defined later
#define BLACK 0                             //have to defined later
#define LINE_INCREASE 100      //percentage increment of the width
#define TOP_MARGIN 10
#define RIGHT_MARGIN 10
#define LEFT_MARGIN 10
#define BOTTOM_MARGIN 10
#define LINE_SPACE 5
#define MAX_SPACING 5             //white spacing
#define MEDIAN_WINDOW 19      //this will depend upon the size of the
#define He 0
#define Ho 1
#define PI 3.1415927
#define SIGMA 4
#define BLOCK_SIZE 256
#define BLOCK_DECREMENT 20
#define NO_BLOCKS 2
#define PERC 30
#define PERC_LINES 70
#define LB_WINDOW 9
#define LB_WIN_LINE 5
#define UB_WINDOW 15
#define UB_WIN_LINE 25

/*Structure that is defined for the line */

typedef struct linestruct{
                int top;              //contain the pixel number of the top of the line
                int middle;       //middle of the line
                int bottom;      //bottom of the line
}line;

/*Function decleration that will be defined later on*/

void change(gray **image,int h_image,int w_image,gray maxval);
int *sift_peaks(int *hist,int *peaks);
void work(int roll,char *filename);
float find_mean(int *arr,int size);
int *get_width(line *l);
float find_std_deviation(int *arr,int size,int mean);
float find_radius(int,int,int,int,int,int);
void preprocess(gray **,int ,int ,int);
int *histogram(gray **,int ,int );
float cal_max(int theta,gray **image,int h_image,int w_image);
int  skew_angle_detection(gray **image,int h_image, int w_image);
int *median_filtering(int *,int,int );
int median(int [],int);
int *find_peaks(int *,int );
line *get_lines(int *,int *);
int get_end(int *,int ,int );
void write_newimage(gray **,line *,int ,int ,int );
gray **rotate_image(int theta, gray **image,int h_image,int w_image);
int min_of_2(int,int,int);
int find_max(float *array,int size);
gray **noise_filter(gray **image,int h_image,int w_image);
void process_gabor(int writer, gray **image,int h_image,int w_image);
void find_feature(float **ce,float **co,int h_image,int w_iamge,float *mea,float *std_dev);
float **H(int f,int theta,int sigma,int f_size,int flag);
float Gaborhe(int x,int y,int f,int theta,int sigma,int f_size);
float Gaborho(int x,int y,int f,int theta,int sigma,int f_size);
float Gauss2D(int x,int y,int sigma,int f_size);
float **convolve(float **image,int rows,int cols,float **filter,int f_size);
float **get_block(float **image,int h_image,int w_image,int,int,int);

/*Main function */

int main(){
        int opt;
        char file[50];

        printf("GIVE OPTIONS\n");
        printf("1 For Find Writer\n");
        printf("2 For Enter Some pages for the writer\n");
        printf("3 Exit\n");

        scanf("%d",&opt);
        switch(opt){
                case 1:                 //case when we want to find the writer name
                        printf("Give the Input File Name\n");
                        scanf("%s",&file);
                        printf("Case 1 Processing.....\n");
                        work(-1,file);
                        break;
                case 2:                //case when we want to train the system
                        printf("Case 2 Processing.....\n");
                        create_database();
                        break;
                case 3:                //case when we want to exit
                        exit(1);
                        break;
        }
}

//Function that change the initial input image change pixels values only to 0 and 255
// image=input image,h_image=height of image,w_image=width of image, //maxval=maximum intensity

void change(gray **image,int h_image,int w_image,gray maxval){
    int i,j;
    FILE *fpout;
    fpout=fopen("out.pgm","w");

    for(i=0;i<h_image;i++)
        for(j=0;j<w_image;j++)
            if(image[i][j]>200)image[i][j]=255;
            else image[i][j]=0;

    pgm_writepgm(fpout,image,w_image,h_image,maxval,0);
    fclose(fpout);
    return;
}

//fun to remove noise from the input Image
// image=input image,h_image=height of image,w_image=width of image

gray **noise_filter(gray **image,int h_image,int w_image){
    int i,j,m,n,count=0;
    gray **new_image;
    new_image =pgm_allocarray(w_image,h_image);
    for(i=1;i<h_image-1;i++){
        for(count=0,j=1;j<w_image-1;j++){
            new_image[i][0]=255;
                        new_image[i][w_image-1]=255;
                        if(image[i][j+1]==BLACK)count++;
            if(image[i-1][j]==BLACK)count++;
            if(image[i][j-1]==BLACK)count++;
            if(image[i+1][j]==BLACK)count++;

            if(count<1)new_image[i][j]=WHITE;
            else if(count>1)new_image[i][j]=BLACK;
            else new_image[i][j]=image[i][j];
            count=0;
        }
    }
        for(i=0;i<w_image;i++){
                new_image[0][i]=255;
                new_image[h_image-1][i]=255;
        }
    return new_image;
}

//will rotate the image by the angle theta
// theta=skew angle computed for the  document

gray **rotate_image(int theta, gray **image,int h_image,int w_image){
    gray **new_image;
    int x,y,r,i,j,t;
    double m=tan((double)(PI*theta/180)); //check for negative value of m
    int new_w_image = (int)((double)w_image/cos((double)(PI*theta/180)));

    new_image =pgm_allocarray(new_w_image,h_image);

    //code to have a white background
    for(i=0;i<h_image;i++)
        for(j=0;j<new_w_image;j++)
            new_image[i][j]=255;

    if(theta<0){
        t= -(int)(w_image*m);
        for(r=0;r<h_image+t;r++){
            for(x=0,j=0;x<w_image;x++){
                y =((int)(m*x))+r;
                if((y<0)||(y>=h_image)) break;
                new_image[r][j++]=image[y][x];
            }
        }
    }
    else{
        t= (int)(w_image*m);
        for(r=-t;r<h_image;r++){
            for(x=0,j=0;x<w_image;x++){
                y =((int)(m*x))+r;
                if((y<0)||(y>=h_image)) break;
                new_image[r][j++]=image[y][x];
            }
        }
    }
    return new_image;
}

//function to calculate the skew angle
// image=input image,h_image=height of image,w_image=width of image,

int  skew_angle_detection(gray **image,int h_image, int w_image){
    int i,row,coloum,theta;
    double tan;
    float maxHist[(2*MAX_THETA)+1];

    for(i=0,theta=-MAX_THETA;i<(2*MAX_THETA)+1;i++,theta++){
        maxHist[i] = cal_max(theta, image, h_image, w_image);

    }
    return find_max(maxHist,(2*MAX_THETA)+1);
}

//function to calculate the Maximum of the array passed
// array=input array of float values, size=size of array

int find_max(float *array,int size){
    int i,j,k;
    float max;

    for(i=0,k=j=-MAX_THETA,max=array[0];i<size;i++,j++){
        if(array[i]>max){
            max =array[i];
            k=j;
        }
    }
    return k;
}
 

//Function that Max Peak of a line
// image=input image,h_image=height of image,w_image=width of image,

float cal_max(int theta,gray **image,int h_image,int w_image){
    int r,x,y,t,max;
    int *hist,*thist,*peaks,*troughs;
    line *lines;
        int *avg;
        float std,min_std,mean;
        line *min;
    int w,size,w_size,min_size;
    double m=tan((double)(PI*theta/180)); //check for negative value of m

    thist=(int *)malloc(sizeof(int)*h_image);

        for(y=0;y<h_image;y++)
        thist[y]=0;

        for(r=0;r<h_image;r++){
            for(y=r,x=0;x<w_image;x++){
                y=(int)(m*x+r);
                if(y>=h_image || y<0) continue;
                if(image[y][x]==BLACK)
                ++thist[r];
            }
        }
        for(w=LB_WINDOW,w_size=w;w<UB_WINDOW;w+=2){
                hist=median_filtering(thist,w,h_image);
                peaks=find_peaks(hist,h_image);
                lines=get_lines(hist,peaks);
                if(w==LB_WINDOW){
                        min=lines;
                        min_size=get_size(min);
                }
                else{
                        size=get_size(lines);
                        if(size<min_size){
                                min=lines;
                                min_size=size;
                                w_size=w;
                        }
                }
        }
        for(max=0,y=0;min[y].middle!=-1;y++){
            if(max<(t=min_of_2(hist[min[y].top],hist[min[y].middle],hist[min[y].bottom])))
                max=t;
        }
        return max;
}

//Function that calculate the minimum of the two

int min_of_2(int t,int m,int b){
    if(abs(m-t)>abs(b-m))
        return abs(b-m);
    return abs(m-t);
}

//find the radius of the circle passing through given three points

float find_radius(int x1,int y1,int x2,int y2,int x3,int y3){
        float x,y,r,x12,y12,x23,y23,c12,c23,m12,m23;

         x12=(x1+x2)/2;
         x23=(x2+x3)/2;
         y12=(y1+y2)/2;
         y23=(y2+y3)/2;
         if(y2!=y1){
        m12=((float)(x1-x2))/((float)(y2-y1));
                c12=y12*m12-x12;
         }
         if(y3!=y2){
        m23=((float)(x2-x3))/((float)(y3-y2));
                c23=y23*m23-x23;
         }
        if((y3-y2)/(x3-x2)==(y2-y1)/(x2-x1))
                return -1;//case when the three points are collinear
        if(y1==y2){
                x=(x1+x2)/2;
                y=m23*x+c23;
        }
        else if(y2==y3){
                x=(x2+x3)/2;
                y=m12*x+c12;
        }
        else{
                x= (c23-c12)/(m12-m23);
                y=m12*x+c12;
        }
        return (float)sqrt((double)((x-x1)*(x-x1)+(y-y1)*(y-y1)));
}

//function that basically do all the work
// roll=rollnumber, filename=input image

void work(int roll,char *filename){
    FILE *fp;
    FILE *fpout;
    gray **input, **rotated_input,maxval;
    int h_image,w_image,theta;

    fp=fopen(filename,"r");
    input=pgm_readpgm(fp,&w_image,&h_image,&maxval);
    fclose(fp);
    change(input,h_image,w_image,maxval);

        input=noise_filter(input, h_image,w_image);
        fpout=fopen("noise.pgm","w");
    pgm_writepgm(fpout,input,w_image,h_image,maxval,0);
    fclose(fpout);

        theta =skew_angle_detection(input,h_image,w_image);
    printf("Skew Angle= %d\n",theta);

        rotated_input =rotate_image(theta,input,h_image,w_image);
    fpout=fopen("rotated.pgm","w");
    pgm_writepgm(fpout,rotated_input,w_image,h_image,maxval,0);
    fclose(fpout);

        //to do preprocessing
    fp=fopen("rotated.pgm","r");
    input=pgm_readpgm(fp,&w_image,&h_image,&maxval);
    fclose(fp);

    preprocess(input,h_image,w_image,maxval);

        fp=fopen("out.pgm","r");
        input=pgm_readpgm(fp,&w_image,&h_image,&maxval);
        fclose(fp);

    process_gabor(roll,input,h_image,w_image);

        return ;
}

// Main preprocessing function-the output after this stage is the rotated image
// image=input image,h_image=height of image,w_image=width of image

void preprocess(gray **image,int h_image,int w_image,int maxval){
        int *thist;
        int *hist;
        int *peaks;
        int *p;
        int *avg;
        float std,min_std,mean;
        line *lines,*min;
        int w,size,w_size,min_mean,min_size;

        thist=histogram(image,h_image,w_image);
        for(w=LB_WINDOW,w_size=w;w<UB_WINDOW;w+=2){
                hist=median_filtering(thist,w,h_image);
                p=find_peaks(hist,h_image);
                peaks=sift_peaks(hist,p);
                lines=get_lines(hist,peaks);
                if(w==LB_WINDOW){
                        min=lines;
                        avg=get_width(min);
                        size=get_size(min);
                        mean=find_mean(avg,size);
                        min_std=find_std_deviation(avg,size,mean);
                }
                else
                {
                        avg=get_width(lines);
                        size=get_size(lines);
                        mean=find_mean(avg,size);
                        std=find_std_deviation(avg,size,mean);
                        if(std<min_std){
                                min=lines;
                                min_mean=mean;
                                min_std=std;
                                w_size=w;
                        }
                }
        }
        //lines=sift_lines(min,min_mean);
        write_newimage(image,min,h_image,w_image,maxval);
}

// Removes very small peaks-this implies removal of very short lines eg. containing just 1
// or 2 words
// hist=histogram(set of int vals)

int *sift_peaks(int *hist,int *peaks){
        int i,icount,count,sum;
        float w,mean;
        int *p;

     for(sum=0,i=0;peaks[i]!=-1;i++)
             sum+=hist[peaks[i]];
     mean=sum/i;
    for(count=0,i=0;peaks[i]!=-1;i++){
                w=(float)hist[peaks[i]];
                if(w> ((1-(float)PERC/100)*mean))
                        count++;
        }
        p=(int *)malloc(sizeof(int)*(count+1));
    for(count=0,i=0;peaks[i]!=-1;i++){
                w=hist[peaks[i]];
                if(w> ((1-(float)PERC/100)*mean))
                        p[count++]=peaks[i];
        }
        p[count]=-1;
        return p;
}

// Returns the width of the line

int *get_width(line *l){
        int i;
        int *r;

     r=(int *)malloc(sizeof(int)*get_size(l));
        for(i=0;l[i].middle!=-1;i++)
                r[i]=abs(l[i].bottom-l[i].top);
        return r;
}

// Returns the number of lines in a page

int get_size(line *l){
        int i;

        for(i=0;l[i].middle!=-1;i++);
        return i;
}

// Computes mean of an int array

float find_mean(int *arr,int size){
        int i,sum=0;

        for(i=0;i<size;i++)
                sum+=arr[i];
        return sum/size;
}

// Computes standard deviation of an int array of mean values

float find_std_deviation(int *arr,int size,int mean){
        int i;
        float dev=0;
        for(i=0;i<size;i++)
                dev+=(arr[i]-mean)*(arr[i]-mean);
        return (float)sqrt((double)dev/size);

}

// compute histogram for given image. BLACK pixels counted per row

int *histogram(gray **image, int h_image,int w_image){
        int i,j;
        int *hist;

        hist=(int *)malloc(h_image*sizeof(int));
        for(i=0;i<h_image;i++)
                hist[i]=0;
        for(i=0;i<h_image;i++)
                for(j=0;j<w_image;j++)
                        if(image[i][j]==BLACK)  ++hist[i];
        return hist;
}

// apply median filter on histogram

int *median_filtering(int *hist,int window,int h_image){
        int i,j,k;
        int sort_array[window];
        int *pro_hist=(int *)malloc(h_image*sizeof(int));

        for(i=0;i<h_image;i++)
                pro_hist[i]=hist[i];
        for(i=(window/2);i<(h_image-(window/2));i++){
                        for(k=0,j=(i-(window/2));j<=(i+(window/2));k++,j++)
                                sort_array[k]=hist[j];
                        pro_hist[i]=median(sort_array,window);
        }
        return pro_hist;
}

// return median for an array of integer elements

int median(int sort[],int window){
        int i,j,t;

        for(i=0;i<window-1;i++)
                for(j=i+1;j<window;j++)
                        if(sort[i]>sort[j]){
                                t=sort[i];
                                sort[i]=sort[j];
                                sort[j]=t;
                        }
        return sort[window/2];
}

// array of peaks from the hist. -1 represents end of array

int *find_peaks(int *hist,int h_image)
{
        int i,flag,k=0,p;
        int *peaks;

        peaks = (int *)malloc(sizeof(int)*h_image);

        if(hist[1]>hist[0])
                flag=INCREASE;
        else if(hist[1]<hist[0])
                flag=DECREASE;
        else flag=CONSTANT;

        for(i=2;i<h_image;i++){
                if((flag==INCREASE)&&(hist[i]==hist[i-1])){
                        p=i-1;
                        flag=CONSTANT;
                }
                else if((flag==INCREASE)&&(hist[i]<hist[i-1]))
                        peaks[k++]=i-1;
                else if((flag==CONSTANT)&&(hist[i]<hist[i-1])){
                        peaks[k++]=((i-1)+p)/2;
                        flag=DECREASE;
                }
                else if((flag!=INCREASE)&&(hist[i]>hist[i-1]))
                        flag=INCREASE;
        }
        peaks[k]=-1;
        return peaks;
}
 

// get array of line structures representing the end points from peak-line width

line *get_lines(int *hist,int *peaks){
        int t,count;
        line *l;

        for(count=0,t=0;peaks[t]!=-1;count++,t++);
        l=(line *)malloc((count+1)*sizeof(line));
        for(t=0;peaks[t]!=-1;t++){
                l[t].top=get_end(hist,peaks[t],-1);
                l[t].bottom=get_end(hist,peaks[t],1);
                l[t].middle=peaks[t];
        }
        l[t].middle=-1;
        return l;
}
 

// find the x-coordinate where curvature is max

int get_end(int *hist,int peak,int dir)
{
        int t;
        float min,j;

        for(t=peak+dir;hist[t]==hist[peak];t+=dir);

        min=find_radius(t-1,hist[t-1],t,hist[t],t+1,hist[t+1]);
        t+=dir;

        while(min>(j=find_radius(t-1,hist[t-1],t,hist[t],t+1,hist[t+1]))){
                min=j;
                t+=dir;
        }
        return t;
}

//this fun will do the word spacing and also write the image into
//a new one and will maintain the distance between two lines and
//allign the document to the left

void write_newimage(gray **image,line *lines,int h_image,int w_image,int maxIntensity){
        gray **new_image;
        FILE *fpout;
        int i,j,w,inc,prev,l,counter,flag,k,add,lastw,sum_lines;
        int new_h_image,new_w_image,start,m,j1,w_flag;
        int opt;

        prev=TOP_MARGIN;
        fpout=fopen("out.pgm","w");

        for(sum_lines=0,add=0,i=0;lines[i].middle!=-1;i++){
                w=abs(lines[i].bottom-lines[i].top);
                inc=(int)(((float)LINE_INCREASE/100)*w);
                add +=inc;
                lines[i].top-=inc/2;
                if(lines[i].top<0)
                        lines[i].top=0;
                lines[i].bottom+=inc/2;
                if(lines[i].bottom>=h_image)
                        lines[i].bottom=h_image-1;
                sum_lines+=abs(lines[i].bottom-lines[i].top);
        }

        new_h_image =sum_lines+((i+1)*LINE_SPACE)+TOP_MARGIN+BOTTOM_MARGIN;
        new_w_image =w_image+LEFT_MARGIN+RIGHT_MARGIN;
        new_image=(gray **)malloc(sizeof(gray *)*new_h_image);
        for(i=0;i<new_h_image;i++)
                new_image[i]=(gray *)malloc(sizeof(gray)*new_w_image);

        for(i=0;i<new_h_image;i++)
                for(j=0;j<new_w_image;j++)
                        new_image[i][j]=WHITE;

        for(i=0;lines[i].middle!=-1;i++){
                lastw=0;
                for(w_flag=0,m=0,start=0,counter=0,j=0;j<w_image;j++){
                        for(flag=1,k=lines[i].top;k<=lines[i].bottom;k++){
                                if(image[k][j]==BLACK){
                                        w_flag=1;
                                        flag=0;
                                        start=1;
                                        counter=0;
                                        break;
                                }
                        }
                        if(flag==1){
                                ++counter;
                                if(w_flag==1){
                                        lastw=m;
                                        w_flag=0;
                                }
                        }
                        if(counter<MAX_SPACING)
                                if(start!=0){
                                        for(l=prev,k=lines[i].top;k<=lines[i].bottom;k++)
                                                new_image[l++][m+LEFT_MARGIN]=image[k][j];
                                        m++;
                                }
                }
                for(j1=0;j1<(w_image-RIGHT_MARGIN-lastw);j1++)
                        for(l=prev,k=lines[i].top;k<=lines[i].bottom;l++,k++)
                                new_image[l][j1+lastw+MAX_SPACING]=new_image[l][j1+LEFT_MARGIN];
                prev +=(lines[i].bottom-lines[i].top+LINE_SPACE);
        }
        pgm_writepgm(fpout,new_image,new_w_image,new_h_image,maxIntensity,0);
        fclose(fpout);
        //printf("View Output File(Yes=0,No=1):");
        //scanf("%d",&opt);
        opt=1;
        if(opt==0){
                system("xv out.pgm&");
                printf("Number of Text Lines=%d\n",get_size(lines));
        }
        return;
}

//function that process the gabor over the image

void process_gabor(int writer, gray **image,int h_image,int w_image){
        int i,j,f,theta,count,i1,j1,k,r,c,n_blocks;
        float **he,**ce;
        float **ho,**co;
        float **original;
        float **block;
        float feature[32];
        int sigma; //have to be defined later assigned some value
        int f_size,b_size; //this is filter size

        sigma=SIGMA;
        f_size=(2*sigma)+1; //this we can change

        original=(float **)malloc(sizeof(float *)*h_image);
        for(i=0;i<h_image;i++)
                original[i]=(float *)malloc(sizeof(float)*w_image);

        for(i=0;i<h_image;i++)
                for(j=0;j<w_image;j++)
                        original[i][j]=(float)image[i][j];

        n_blocks=NO_BLOCKS;
        if(writer==-1)
                n_blocks=1;

        for(k=0;k<n_blocks;k++){

                printf("\nGABOR FILTER OUTPUT\n");
                b_size=BLOCK_SIZE;

                do{
                        r=(int) ((h_image-b_size-1)*(float)rand()/(RAND_MAX+1.0));
                        c=(int) ((w_image-b_size-1)*(float)rand()/(RAND_MAX+1.0));
                        if(r<0 || c<0)
                                b_size-=BLOCK_DECREMENT;
                }while(r<0 || c<0);

                block=get_block(original,h_image,w_image,r,c,b_size);

                for(count=0,f=4,i=0;i<4;i++,f*=2){
                        for(theta=0;theta<=135;theta +=45,count+=2){
                                he=H(f,theta,sigma,f_size,He);
                                ho=H(f,theta,sigma,f_size,Ho);

                                ce=convolve(block, b_size,b_size, he, f_size);
                                co=convolve(block, b_size, b_size,ho, f_size);

                                find_feature(ce,co,b_size-2*(f_size/2),b_size-2*(f_size/2), &feature[count], &feature[count+1]);
                        }
                }
                if(writer!=-1){
                        write_database(writer,feature);   //writer is the writer number
                                                                                       //have to taken from the user
                }
                else{
                      //to find the writer case when we want to find the writer
                        printf("Searching for the writer\n");
                        find_writer(feature);
                }
        }
        return;
}

// Function returns a random block from the processed image

float **get_block(float **image,int h_image,int w_image,int r,int c,int b_size)
{
        int i,j;
        float **f;
        f=(float **)malloc(sizeof(float *)*b_size);
        for(i=0;i<b_size;i++)
                f[i]=(float *)malloc(sizeof(float)*b_size);
        for(i=0;i<b_size;i++)
                for(j=0;j<b_size;j++)
                        f[i][j]=image[i+r][j+c];

        return f;
}

//function that find the 2 features mean and std deviation

void find_feature(float **ce,float **co,int new_h_image,int new_w_image,float *mea,float *std_dev){
        int i,j;
        float **final;

        final=(float **)malloc(sizeof(float *)*new_h_image);
        for(i=0;i<new_h_image;i++)
                final[i]=(float *)malloc(sizeof(float)*new_w_image);

        for(i=0;i<new_h_image;i++){
                for(j=0;j<new_w_image;j++){
                        final[i][j]=sqrt((double)((ce[i][j])*(ce[i][j])+(co[i][j])*(co[i][j])));
                }
        }
        *mea=mean(final,new_h_image,new_w_image);//check the pointer thing
        *std_dev=std_deviation(final,new_h_image,new_w_image,*mea);//check the pointer thing
printf("mean =%f std=%f\n",*mea,*std_dev);
        return;
}

// function that calculate the he and ho even and odd H's

float **H(int f,int theta,int sigma,int f_size,int flag){
        int i,j;
        int center;

        float **h=(float **)malloc(sizeof(float *)*f_size);
        for(i=0;i<2*sigma+1;i++)
                h[i]=(float *)malloc(sizeof(float)*f_size);

        center=(f_size-1)/2;

        for(i=-center;i<=center;i++)
                for(j=-center;j<=center;j++)
                        if(flag==He)
                                h[i+center][j+center]=Gaborhe(i,j,f,theta,sigma,f_size);
                        else
                                h[i+center][j+center]=Gaborho(i,j,f,theta,sigma,f_size);
        return h;
}

// Returns even component of Gabor

float Gaborhe(int x,int y,int f,int theta,int sigma,int f_size){
        float he,g;
        float the =(PI*theta)/180; //convert theta into radians
        g=Gauss2D(x,y,sigma,f_size);
        he=g*((float)cos((double)(PI*2*PI*f*((x*cos((double)the))+(y*sin((double)the))/180))));
        return he;
}

// Returns odd component of Gabor

float Gaborho(int x,int y,int f,int theta,int sigma,int f_size){
        float ho,g;
        float the =(PI*theta)/180; //convert theta into radians
        g=Gauss2D(x,y,sigma,f_size);
        ho=g*((float)(sin((double)(PI*2*PI*f*(x*cos((double)the)+y*sin((double)the))/180))));
        return ho;
}

// Computes 2D Gaussian Filter

float Gauss2D(int x,int y,int sigma,int f_size){
        float f;

        f=(1/(sqrt(2*PI)*sigma))*exp(-1.0*(x*x+y*y)/(2*sigma*sigma));
        return f;
}

//function to convolve the image with the gabor He's and Ho's function
//basically it's a matrix multioplication

float **convolve(float **image,int rows,int cols,float **filter,int f_size){
        int i,j,i1,j1,count,p,q;
        float t;
        float **c;

        c=(float **)malloc(sizeof(float *)*(rows-2*(f_size/2)));
        for(i=0;i<rows-2*(f_size/2);i++)
                c[i]=(float *)malloc(sizeof(float)*(cols-2*(f_size/2)));

        for(i=f_size/2;i<rows-(f_size/2);i++){
                    for(j=f_size/2;j<cols-(f_size/2);j++){
                                t=0.0;
                        for(p=0,i1=i-(f_size/2);p<f_size;p++,i1++)
                                for(q=0,j1=j-(f_size/2);q<f_size;q++,j1++)
                                        t+=(image[i1][j1]*filter[p][q]);
                                c[i-(f_size/2)][j-(f_size/2)]=t;
                        }
    }
        return c;
}

/*                              DATA BASE FORMAT
 *                              database file
writer  feature1.....   ....    feature16....           .....feature32
number
                mean1 dev1 mean2 dev2 mean3 dev3 ..........     mean16 dev16.
*/

/* finaldata file
 *
 * writer  mean1 dev1 mean2 dev2 mean3 dev3...............mean32                                dev32.
 * number                                                                        (mean of 32th feature) (std dev of 32th fea)
 *
 */

int  MAX_PAGE_PER_USER=10;

int create_database();
void write_database(int writer,float *mean_dev);
void write_final_data(int roll);
void find_writer(float *curr_feature);
float mean(float **image,int h_image,int w_image);
float std_deviation(float **image,int h_image, int w_image,float mea);
 

// Creates the database from the training set (input documents)
//return -1 on failing 1 on success

int create_database(){
        int count,start,roll,i,temp;
        FILE *fp,*fp1;
        char *name,con[50];
        float *feature,m;
        int flag=0,opt,user;
        name= (char *)malloc(sizeof(char)*100);

    printf("Enter the Roll No for this User\n");
    scanf("%d",&roll);
    printf("Enter the Count of Pages for this User\n");
    scanf("%d",&count);
    printf("Enter the starting number of the page for this User\n");
    scanf("%d",&start);

        fp=fopen("rollno","r");
        if(fp!=NULL){
                while(fscanf(fp,"%d",&temp)!=EOF){
                        if(temp==roll){
                                printf("This user exits in database \n");
                                printf("Do you want to add more papers then Press 1 ");
                                printf("Else press 2\n");
                                scanf("%d",&opt);
                                if(opt!=1)return -1; //return when don't want to add more paper of this user
                                flag=1;
                        }
                }
                fclose(fp);
        }
        if(flag!=1){ //add this roll no to data base in file name "rollno"
                fp=fopen("rollno","a");
                fprintf(fp,"%d\n",roll);
                fclose(fp);
        }
        if(flag==1){
                printf("This user already exits. Adding more pages...\n");
                fp=fopen("finaldata","r");
                fp1=fopen("temp","w");

                fscanf(fp,"%d",&user);
                while(!feof(fp)){
                        if(user==roll){
                                for(i=0;i<64;i++){
                                        fscanf(fp,"%f",&m);
                                }
                        }
                        else{
                                fprintf(fp1,"%d",user);
                                for(i=0;i<64;i++){
                                        fscanf(fp,"%f",&m);
                                        fprintf(fp1," %f",m);
                                }
                                fprintf(fp1,"\n");
                        }
                        fscanf(fp,"%d",&user);
                }
                fclose(fp);
                fclose(fp1);
                system("cp temp finaldata");
                system("rm temp");
        }
        printf("%d roll no\n",roll);

    sprintf(name,"%d",roll);
    for(i=1;i<=count; i++,start++){
       sprintf(con,"_%d.pgm",start);
       name=strcat(name,con);
           printf("name=%s\n",name);
           work(roll,name);
       sprintf(name,"%d",roll);
    }

       write_final_data(roll);// have to modify the final database
       return 1;
}

//function that write into the database

void write_database(int writer,float *mean_dev){
        FILE *fp;
        int i;
        fp=fopen("database","a");
        fprintf(fp,"%d",writer);
        for(i=0;i<32;i++)
                fprintf(fp," %f",mean_dev[i]);
        fprintf(fp,"\n");
        fclose(fp);
        return;
}

// Computes mean and standard deviation of the feature set and writes into database

void write_final_data(int roll){
        FILE *fp;
        int i,j,k,writer,pages;
        float mean_dev[64],**feature;
        char *proc;
        char temp[200];
        int flag=0;
        float mea=0,std=0,arbit;

        feature =(float **)malloc(sizeof(float *)*MAX_PAGE_PER_USER);
        for(i=0;i<MAX_PAGE_PER_USER;i++){
                feature[i]=(float *)malloc(sizeof(float)*32);
        }

        fp=fopen("database","r");
        pages=0;
                fscanf(fp,"%d",&writer);
        while(!feof(fp)){
                if(writer==roll){
                        if(!(pages<MAX_PAGE_PER_USER)){
                                //reallocation of the array
                                printf("Rellocation of Memory\n");
                                MAX_PAGE_PER_USER +=4;
                                feature = (float **)realloc(feature,(sizeof(float *)*MAX_PAGE_PER_USER));
                                for(i=0;i<MAX_PAGE_PER_USER;i++){
                                        feature[i]=(float *)realloc(feature[i],(sizeof(float)*32));
                                }
                        }
                        flag=1;
                        for(i=0;i<32;i++){
                                fscanf(fp,"%f",&feature[pages][i]);
                        }
                        pages++;
                }
                else{
                        for(i=0;i<32;i++){
                                fscanf(fp,"%f",&arbit);
                        }
                }
                fscanf(fp,"%d",&writer);
        }
        fclose(fp);

        if(pages==0) printf("Roll No %d Not Found \n",roll);
        else{
                printf("Number of Rows For this user =%d\n",pages);
                for(i=0,k=0;i<32,k<64;i+=1,k+=2){
                        for(mea=0,j=0;j<pages;j++){
                                mea +=feature[j][i];
                        }
                        mea= mea/pages;
                        for(std=0,j=0;j<pages;j++){
                                std +=((feature[j][i]-mea)*(feature[j][i]-mea));
                        }
                        std =(float)sqrt((double)std/pages);
                        mean_dev[k]=mea;
                        mean_dev[k+1]=std;
                        printf("FINAL mean=%f std=%f\n",mea,std);
                }
        }

        fp=fopen("finaldata","a");
        fprintf(fp,"%d",roll);
        for(i=0;i<64;i++)
                fprintf(fp," %f",mean_dev[i]);
        fprintf(fp,"\n");
        fclose(fp);
        return;
}
 

//function to find the writer

void find_writer(float *curr_feature){
        int writer,i,min,m=1;
        float d,min_d,feature[64];
        char *proc,temp[200];
        FILE *fp;
        int flag=0;

        fp=fopen("finaldata","r");

        fscanf(fp,"%d",&writer);
        printf("writer= %d  \n",writer);
        while(!feof(fp)){
                for(i=0;i<64;i++){
                        fscanf(fp,"%f",&feature[i]);
                }
                for(d=0,i=0;i<32;i++){
                        d +=((curr_feature[i]-feature[2*i])*(curr_feature[i]-feature[2*i]))/(feature[2*i+1]*feature[2*i+1]);
                }
                if(flag==0){
                        flag=1;
                        min_d=d;
                        min=writer;
                }
                if(d<min_d){
                        min=writer;
                        min_d=d;
                }
                fscanf(fp,"%d",&writer);
         }
        printf("THE WRITER NUMBER IS %d\n",min);
        fclose(fp);
        return;
}

[ Main Page] [ Course page ] [ Course Projects]
[Amit] [Kamat]