/* 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;
}
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]