Plate recognition

Page 1

ECE 532 Project Report

rahulv@email.arizona.edu

ECE 532 DIGITAL IMAGE ANALYSIS PROJECT REPORT On

LICENSE PLATE RECOGNITION SYSTEM By RAHUL VERMA

1


ECE 532 Project Report

rahulv@email.arizona.edu

Index

1. Project Description………………………………………...………..3 2. Proposed Solution…………………………………………………...3 3. Source of Images………………………………………………….…4 4. About the Codes…………………………………………………..…4 5. Assumptions & Constraints………………………………………...4 6. Methods Used………………………………………………………..4 7. Performance…………………………………………………………9 8. Computational Efficiency…………………………………………20 9. Modifications………………………………………………………20 10.References………………………………………………………….21 11.Source Codes……..………………………………………………..22

2


ECE 532 Project Report

rahulv@email.arizona.edu

LICENSE PLATE RECOGNITION

1. Project Description: The project deals with matching a license plate image from a pool of available images. For this the image of the car with the plate is taken. Then the license plate is extracted. This is followed by searching for the license plate in the database of images. An example of the application of this project would be the toll gates, where the car needs to be registered to get inside. One way of checking for this is as follows. The image of the car is taken and the license plate (extracted from the car image) is matched with the database. If there is a match then car is allowed else it is stopped. The images stored in the database are images of the car with the plate at the time of registering. So any time the car comes to the toll gate, its picture is taken. That is used to get the license plate and this plate image is matched with the database. The example given above explains that the output of the project will not be an image as such but will only tell the user if the license plate is available in the database. The problem is then divided into three stages: 1. License plate location and extraction. 2. Matching license plate with images in the database. 2. Proposed Solution: The following was implemented to solve the problem. Description of all the steps used is explained later: Stage 1: License plate Location 1. 2. 3. 4. 5. 6.

Use Sobel Edge detection[2,5] technique to find vertical edges Use Erosion (Morphological Operation)[5] to reduce noisy edges Use Erosion again to reduce occurrence of adjacent edges Binarise the resulting image for successive steps Perform localized search for finding end points of the license plate Extraction of license plate.

Stage 2: Matching License Plate with Prototypes 1. Compute average gray levels of plate and images in database. 2. Compute Cross Correlation[1] values for license plates with database images [4] 3. Find the match.

3


ECE 532 Project Report

rahulv@email.arizona.edu

3. Source of Images (Database): The images were obtained from a website [4]. 4. About the codes: The project codes were written in C. All the codes were self developed except for FUNCS.C which has been authored by Prof. Rodriguez. 5. Assumptions & Constraints: 1. Images are in the PGM format. 2. The distance between the camera and the car is more or less assumed to be a constant. 3. The license plate is located mostly close to the centre of the image. 4. The license plate is assumed to have no tilt. 5. Illumination conditions are not taken into consideration.

6. Methods Used: Stage 1: The following was done to locate the license plate.

Fig.1. A typical image

4


ECE 532 Project Report

rahulv@email.arizona.edu

For stage one, the vertical edges were found using sobel [2,5]edge detector modified to find only the vertical edges. This was done based on the fact that in a license plate there are more horizontal edges than vertical ones. This leads to a very sparse edge map which is easy to deal with in terms of finding the license plate. Another advantage of finding the vertical edges is that of the variety of images of the car that one observes, the prominent vertical edges are that of the license plate. The result of the sobel edge detector is an image with vertical edges including noisy ones.

Fig.2 Vertical Edge Map

The noisy edges were removed using erosion[5]. The structuring element is a 15 by 15 square disk (centered at the origin) with 0 as the object pixel.

Fig.3 15 by 15 structuring element 5


ECE 532 Project Report

rahulv@email.arizona.edu

It eroded all the noisy edges which obviously are smaller than the main vertical edge which corresponds to the license plate. There were characters of the license plate that were present in the image even after erosion, but they are smaller than the main vertical edge that represents the side of the box containing the license plate. So they do not pose any problem for locating the box containing the plate.

Fig.4 Vertical Edge Map After Erosion once The search for co ordinates of the license plate could be done now. But in most images there are two edges side by side which made the process of finding the end points of the plate difficult. This was resolved by performing another erosion process. This time the structuring element used was a 3 by 3 square disk with the origin (at the centre of the disk) and the pixel next to it in the forward direction set to be the object pixel(in this case 0).

Fig. 5. 3 by 3 structuring element

6


ECE 532 Project Report

rahulv@email.arizona.edu

The result of this erosion was an edge map with very few vertical edges (no adjacent edges) with the prominent ones corresponding to the two sides of the license plate.

Fig.6 Vertical Edge Map after Erosion for the second time

The search for the co ordinates is the next step. A Localized Search was performed (in the forward direction) wherein the image was scanned from 10% to 20 % of the number of rows to 50 % of the number of rows. This gave the first end point. Followed by this, another Localized Search was performed from 75% to 85 % of the number of columns to about 50% of the number of columns (in the backward direction). This gave the Diagonally Opposite end point of the plate. The motivation behind Localized Search is the fact that most of the license plates are observed to be located in the centre of the image. Hence, the range is as mentioned. The variable ranges were used to account for the problem of not getting the co ordinates in the first search. After obtaining the end points, the image was read between these end points to extract the license plate.

Fig.7 A typical image of plate after extraction

7


ECE 532 Project Report

rahulv@email.arizona.edu

Stage 2: After stage two, the image is ready for matching with the images in the database. A hardcore matching doesn’t give appropriate results and it also doesn’t prove to be efficient. By hardcore we mean matching the actual pixels in the set of two images (plate and the database image). The method used made use of cross-correlation operator [1]. Cross Correlation: ° be its average gray level. Let f be the license Let gi be the image in the database and gi plate image (extracted as above) and ° f be its average gray level. The cross correlation

operator is then defined in the discrete case as follows:

C fgi =

°) ∑∑ ( f − °f )( gi − gi °) ∑∑ ( f − °f ) ( gi − gi 2

2

The summation signs in the above expression take into account the shifting of the image gi over the plate image f and hence results in normalized C fgi . But in the algorithm implemented the results were coming accurate even without shifting the image gi . Hence the values of C fgi were not normalized. That is the image gi was not shifted over f . A quick scan through the values with the intention of searching the maximum C fgi , leads to correct match with a high degree of accuracy. In the actual implementation, the license plate image is correlated with the car images in the database in the region defined by the end points of the plate (obtained in stage 1). Intuitively and also found after implementation, if the plate was correlated with the correct image, it gave the maximum value for C fgi among other values obtained by correlating the plate with the rest of the database. 7. Performance: The code was run for a total of 10 images. It gave a match for each one of them. The images obtained at each stage of the project are as follows: Ti.pgm: the image in the database 1.pgm: the vertical edge map 2.pgm: the map after erosion once 3.pgm: the map after erosion twice 4.pgm: the map after binarisation Li.pgm: the license plate Where i varies from 1 to 10.

8


ECE 532 Project Report

rahulv@email.arizona.edu

3.pgm

T1.pgm

4.pgm

1.pgm

L1.pgm

2.pgm

9


ECE 532 Project Report

rahulv@email.arizona.edu

3.pgm

T2.pgm

4.pgm

1.pgm

L2.pgm

2.pgm

10


ECE 532 Project Report

rahulv@email.arizona.edu

T3.pgm

3.pgm

1.pgm

4.pgm

L3.pgm

2.pgm

11


ECE 532 Project Report

rahulv@email.arizona.edu

T4.pgm

3.pgm

1.pgm

4.pgm

L4.pgm

2.pgm

12


ECE 532 Project Report

rahulv@email.arizona.edu

3.pgm

T5.pgm

1.pgm 4.pgm

L5.pgm

2.pgm

13


ECE 532 Project Report

rahulv@email.arizona.edu

T6.pgm

3.pgm

1.pgm

4.pgm

L6.pgm

2.pgm

14


ECE 532 Project Report

rahulv@email.arizona.edu

T7.pgm

3.pgm

1.pgm

4.pgm

L7.pgm

2.pgm

15


ECE 532 Project Report

rahulv@email.arizona.edu

3.pgm T8.pgm

4.pgm

1.pgm

L8.pgm

2.pgm

16


ECE 532 Project Report

rahulv@email.arizona.edu

T9.pgm

3.pgm

1.pgm

4.pgm

L9.pgm

2.pgm

17


ECE 532 Project Report

rahulv@email.arizona.edu

3.pgm

T10.pgm

1.pgm

4.pgm

L10.pgm

2.pgm

18


ECE 532 Project Report

rahulv@email.arizona.edu

The following table gives the values of the cross correlation operator for all the 10 images of plates matched with the database images. These were obtained after running the project code on the 10 images. For eg: if T1.pgm is the first image then it is the first image in the database and its license plate is the first one. So cfgv1 represents cross correlation with T1.pgm of the license plate. Let us consider license plate L1 which was obtained from T1. Now the images T1 to T10 are already present in the database ( gi with i=1 to 10). L1 is matched with all the images from T1 to T10. That is cross correlation value Cfgi is calculated for all the images with L1 where I varies from 1 to 10. As can be seen from the table below, the value of Cfgi is maximum for i=1. And it is taken as the match.

L1 L2 L3 L4 L5 L6 L7 L8 L9 L10

Cfgv 1 74.4 87.9 88.3 84.7 78.8 88.8 70.9 83.7 90.1 81.6

Cfgv 2 67.5 99.2 83.4 84.2 78.2 85.3 71.4 83.4 88.3 82.8

Cfgv 3 66.7 87.5 104.2 86.5 75.9 84.5 73.9 87.3 93.7 80.2

Cfgv 4 74.6 85.1 91.5 93.3 77.8 86.1 75.3 92.0 98.8 80.8

Cfgv 5 73.6 92.3 81.5 85.5 84.8 89.5 70.5 83.5 87.5 88.2

Cfgv 6 72.4 93.7 96.9 89.3 82.2 97.3 76.7 90.9 99.1 86.9

Cfgv 7 70.2 91.3 92.7 87.9 80.0 90.6 77.4 89.6 95 85.6

Cfgv 8 71.5 90.6 93.6 90.5 79.3 89.1 75.6 92.9 97 84.4

Cfgv 9 70 86.4 96.8 89.5 75.3 86.8 73.7 89.9 99.6 79.6

Cfgv 10 72.8 92.3 87.2 88.1 83.7 92.3 75.5 87.5 92.8 90.3

Table 1 As one can see the diagonal elements, that is, (Li,Cfgi) has the maximum value of Cfg in that particular row i. According to the algorithm this corresponds to the image with which the license plate matches.

19


ECE 532 Project Report

rahulv@email.arizona.edu

A graphical representation for L3 is as follows:

Fig.9 Graph of cross correlation values of license plate 3 8. Computational Efficiency: The computation time was not a major issue in this project. There is only one thing to note. Ideally, the correlation is calculated as a normalized one by shifting the image on the plate pixel by pixel. This might have resulted in a slow response had that been implemented. But results are accurate enough even without shifting the image. This might have increased the computation speed. 9. Modifications: a. b. c. d. e.

The database can surely be increased to include more and more images With say, a JPEG to PGM converter the project can be made to work on JPEG images. Similarly it can be extended for other format of images. The images can be preprocessed if the database size is large just to ensure correct location and hence correct correlation. For the given set of images need was not felt for Normalized cross correlation operator but it can be also computed. After getting the match data can be read regarding the car owner like name, address, date of registration etc.

20


ECE 532 Project Report

rahulv@email.arizona.edu

10. References: [1] P Cornelli, P Ferragina, M.N. Granieri, F Stabile, “Optical recognition of motor vehicle license plates”, IEEE Transaction on Vehicular Technology, Volume 44, Issue 4, pp. 790-799, Nov. 1995 [2] Rafael C. Gonzalez and Richard E. Woods, Digital Image Processing, Peasron Education Asia, Second Edition, 2002 [3] J. R. Parker, “Gray level thresholding in badly illuminated images,”

IEEE Transaction Pattern Analysis, Machine Intelligence, vol. 13, no. 8, pp. 813-819, 1991

[4] www.olavplates.com [5] M. Sonka, V. Hlvac, R. Boyle, Image Processing, Analysis and Machine Vision, PWS publishing, San Francisco, 1999 [6] http://www.ph.tn.tudelft.nl/Courses/FIP/noframes/fip.html

21


ECE 532 Project Report

rahulv@email.arizona.edu

11. Source Codes: Sobel_vertical.c /* This program detects the vertical edge in an image using Sobel Edge Detection technique. */ /* Input is a PGM image. */ /* Author: Rahul Verma December 2005 */ #include <stdio.h> #include <stdlib.h> #include <string.h> extern int read_pgm_hdr(FILE *, int *, int *); extern void **matrix(int, int, int, int, int); extern void reflect(unsigned char **, int, int, int); extern void error(const char *); int main(int argc, char **argv) { int sum,t,u,max=0; FILE *fpx, *fpy; int nrows, ncols, i, j; unsigned char **x, **a; /* PARSE THE COMMAND LINE */ while(--argc > 0 && **(argv+1) == '-') switch((*++argv)[1]) { default: error("Usage: sobel [infile]"); } /* OPEN FILES */ if((fpx = fopen("t19.pgm", "rb")) == NULL) error("can't open file"); fpy = fopen("1.pgm", "wb");

/* READ HEADER */ if(read_pgm_hdr(fpx, &nrows, &ncols) < 0) error("not a PGM image or bpp > 8");

22


ECE 532 Project Report

rahulv@email.arizona.edu

/* ALLOCATE ARRAYS */ x = (unsigned char **)matrix(nrows+2, ncols+2, -1, -1, sizeof(char)); a = (unsigned char **)matrix(nrows, ncols, 0, 0, sizeof(char)); if(x == NULL ) error("can't allocate memory"); /* READ THE IMAGE */ for(i = 0; i < nrows; i++) if(fread(&x[i][0], sizeof(char), ncols, fpx) != ncols) error("can't read the image"); /* REFLECT THE IMAGE ACROSS ITS BORDERS BY ONE PIXEL */ reflect(x, nrows, ncols, 1); /* COMPUTE THE SOBEL EDGE IMAGE */ /* No bounds checking needed because we extended the image. */ for(i = 0; i < nrows; i++) for(j = 0; j < ncols; j++) { u = x[i-1][j+1]+2*x[i][j+1]+x[i+1][j+1]-x[i-1][j-1]-2*x[i][j-1]-x[i+1][j-1]; sum = u*u; /*COMPUTE MAXIMUM VALUEOF MAGNITUDE SQUARED GRADIENT */ if (sum>max) max=sum; /* COMPARING WITH THE THRESHOLD VALUE OF 3000 */ if (sum>3000) a[i][j] = 0; else a[i][j] = 255; } /* WRITE THE IMAGE */ fprintf(fpy, "P5\n%d %d\n255\n", ncols, nrows); for(i = 0; i < nrows; i++) if(fwrite(&a[i][0], sizeof(char), ncols, fpy) != ncols) error("can't write the image"); /* CLOSE FILE & QUIT */ fclose(fpx); fclose(fpy); exit(0);

23


ECE 532 Project Report

rahulv@email.arizona.edu

} Erosion_1.c /* This Program performs binary erosion WITH A SQUARE DISK 15 BY 15 IN SIZE*/ /* Author: RAHUL VERMA DECEMBER 2005*/ /* Input is a PGM image*/ #include <stdio.h> #include <stdlib.h> #include <string.h> #include <math.h> extern int read_pgm_hdr(FILE *, int *, int *); extern void **matrix(int, int, int, int, int); extern void reflect(unsigned char **, int, int, int); extern void error(const char *); int main(int argc, char **argv) { FILE *fpx,*fpy; int nrows,ncols,s,rows,cols,k=0,m=0,i,j,flag=0,u,v; unsigned char **x,**y,**b;

/* PARSE THE COMMAND LINE */ while(--argc > 0 && **(argv+1) == '-') switch((*++argv)[1]) { default: error("Usage: 1 [infile]"); } rows = 15; /* ROWS OF STRUCTURING ELEMENT */ cols = 15; /* COLUMNS OF STRUCTURING ELEMENT */ s = 0; /* OBJECT PIXEL*/ u = (int)(rows/2); v = (int)(cols/2); /* OPEN FILES */ if((fpx = fopen("1.pgm", "rb")) == NULL) error("can't open file"); fpy = fopen("2.pgm","wb");

24


ECE 532 Project Report

rahulv@email.arizona.edu

/* READ HEADER */ if(read_pgm_hdr(fpx, &nrows, &ncols) < 0) error("not a PGM image or bpp > 8"); /* ALLOCATE ARRAYS */ x = (unsigned char **)matrix(nrows+(2*u), ncols+(2*v), -u, -v, sizeof(char)); y = (unsigned char **)matrix(nrows, ncols, 0, 0, sizeof(char)); /* b IS STRUCTURING ELEMENT */ b = (unsigned char **)matrix(rows, cols, -u, -v, sizeof(char)); /* READ THE IMAGE */ for(i = 0; i < nrows; i++) if(fread(&x[i][0], sizeof(char), ncols, fpx) != ncols) error("can't read the image"); /* REFLECT THE IMAGE BY HALF THE NUMBER OF ROWS=COLUMNS */ reflect(x, nrows, ncols, u); /* INITIALISE THE OUTPUT IMAGE */ for(i=0;i<nrows;i++) { for(j=0;j<ncols;j++) { y[i][j] = 255; } } /* INITIALISE THE STRUCTURING ELEMENT */ for (i=(-u);i<=u;i++) { for(j=(-v);j<=v;j++) { b[i][j] = 255-s; b[i][0] = s; } } /* PERFORM EROSION */ for(i=0;i<nrows;i++) { for(j=0;j<ncols;j++) { flag = 0; if (x[i][j] == s) {

25


ECE 532 Project Report

rahulv@email.arizona.edu

for(k=(-u);k<=u;k++) { for(m=(-v);m<=v;m++) { if (x[i+k][j+m]!=s && b[k][m]==s) { flag = 1; break; } } if (flag == 1) break; } if (flag == 1) { y[i][j] = 255-s; } else { if (flag == 0) { y[i][j] = s; } } } } } /* WRITE THE IMAGE */ fprintf(fpy, "P5\n%d %d\n255\n", ncols, nrows); for(i = 0; i < nrows; i++) if(fwrite(&y[i][0], sizeof(char), ncols, fpy) != ncols) error("can't write the image"); /* CLOSE FILE & QUIT */ fclose(fpx); fclose(fpy); exit(0); } Erosion_2.c /* This Program performs binary erosion WITH A SQUARE DISK 3 BY 3 IN SIZE*/ /* Author: RAHUL VERMA DECEMBER 2005*/

26


ECE 532 Project Report

rahulv@email.arizona.edu

/* Input is a PGM image*/ #include <stdio.h> #include <stdlib.h> #include <string.h> #include <math.h> extern int read_pgm_hdr(FILE *, int *, int *); extern void **matrix(int, int, int, int, int); extern void reflect(unsigned char **, int, int, int); extern void error(const char *); int main(int argc, char **argv) { FILE *fpx,*fpy; int nrows,ncols,s,rows,cols,k=0,m=0,i,j,flag=0,u,v; unsigned char **x,**y,**b; /* PARSE THE COMMAND LINE */ while(--argc > 0 && **(argv+1) == '-') switch((*++argv)[1]) { default: error("Usage: 2 [infile]"); } rows = 3; /*rows of structuring element*/ cols = 3; /*columns of structuring element*/ s = 0; /* Object pixel*/ u = (int)(rows/2); v = (int)(cols/2); /* OPEN FILES */ if((fpx = fopen("2.pgm", "rb")) == NULL) error("can't open file"); fpy = fopen("3.pgm","wb"); /* READ HEADER */ if(read_pgm_hdr(fpx, &nrows, &ncols) < 0) error("not a PGM image or bpp > 8"); /* ALLOCATE ARRAYS */ x = (unsigned char **)matrix(nrows+(2*u), ncols+(2*v), -u, -v, sizeof(char)); y = (unsigned char **)matrix(nrows, ncols, 0, 0, sizeof(char)); /* b IS STRUCTURING ELEMENT */

27


ECE 532 Project Report

rahulv@email.arizona.edu

b = (unsigned char **)matrix(rows, cols, -u, -v, sizeof(char)); /* READ THE IMAGE */ for(i = 0; i < nrows; i++) if(fread(&x[i][0], sizeof(char), ncols, fpx) != ncols) error("can't read the image"); /* REFLECT THE IMAGE BY HALF THE NUMBER OF ROWS=COLUMNS */ reflect(x, nrows, ncols, u); /* INITIALISE THE OUTPUT IMAGE */ for(i=0;i<nrows;i++) { for(j=0;j<ncols;j++) { y[i][j] = 255; } } /* INITIALISE THE STRUCTURING ELEMENT */ for (i=(-u);i<=u;i++) { for(j=(-v);j<=v;j++) { b[i][j] = 255-s; } } b[0][0] = s; b[0][1] = s;

/* PERFORM EROSION */ for(i=0;i<nrows;i++) { for(j=0;j<ncols;j++) { flag = 0; if (x[i][j] == s) { for(k=(-u);k<=u;k++) { for(m=(-v);m<=v;m++) { if (x[i+k][j+m]!=s && b[k][m]==s) { flag = 1;

28


ECE 532 Project Report

rahulv@email.arizona.edu

break; } } if (flag == 1) break; } if (flag == 1) { y[i][j] = 255-s; } else { if (flag == 0) { y[i][j] = s; } } } } } /* WRITE THE IMAGE */ fprintf(fpy, "P5\n%d %d\n255\n", ncols, nrows); for(i = 0; i < nrows; i++) if(fwrite(&y[i][0], sizeof(char), ncols, fpy) != ncols) error("can't write the image"); /* CLOSE FILE & QUIT */ fclose(fpx); fclose(fpy); exit(0); } Match.c

/* This program first performs binarisation using kittler's method on previous image */ /* It then performs localised search to get co ordinates of the license plate*/ /* Finally it goes for the computation of Cross correlation values*/ /* Author: RAHUL VERMA Decembner 2005*/ /* Input is a PGM image*/

29


ECE 532 Project Report

rahulv@email.arizona.edu

#include <stdio.h> #include <stdlib.h> #include <string.h> #include <math.h> #include <malloc.h> extern int read_pgm_hdr(FILE *, int *, int *); extern void **matrix(int, int, int, int, int); extern void error(const char *); int main(int argc, char **argv) { FILE *fpx,*fpy,*fpw,*fpz,*fpv; int nrows,ncols,b=0,first=0,last=0; int i,j,t; int tmin;/* required threshold (gray level) for segmenting the image*/

float p[256]; double mu1[256],mu2[256],var1[256],var2[256],q1[256],q2[256]; double mu=0.0,H[256],Hmin=4.0,temp; unsigned char **x,**y,**w,**z,**v; int *h; /* Declarations for the second part of the code(Co ordinates) */ int rows_initial,cols_initial,rows_final,cols_final,flag,rows,cols; double cfgv1,cfgv2,cfgv3,cfgv4,cfgv5,cfgv6,cfgv7,cfgv8,cfgv9; double cfgv10,avgv,avg1,num,den; long int sum,nrows1,ncols1; FILE *fpg1,*fpg2,*fpg3,*fpg4,*fpg5,*fpg6; FILE *fpg7,*fpg8,*fpg9,*fpg10,*fpg11; unsigned char **g1,**g2,**g3,**g4,**g5; unsigned char **g6,**g7,**g8,**g9,**g10; int nrows2,ncols2,nrows3,ncols3,nrows4,ncols4,nrows5; int ncols5,nrows6,ncols6,nrows7,ncols7,nrows8,ncols8; int nrows10,ncols10,nrows9,ncols9,d; double avg2,avg3,avg4,avg5,avg6,avg7,avg8,avg9,avg10; double max,cfg[11]; /* Allocate memory for the histogram */ h = (int*) malloc(256*sizeof(int)); if( h == NULL )

30


ECE 532 Project Report

rahulv@email.arizona.edu

printf( "Insufficient memory available\n" ); /* PARSE THE COMMAND LINE */ while(--argc > 0 && **(argv+1) == '-') switch((*++argv)[1]) { default: error("Usage: 3 [infile]"); } /* OPEN FILES */ if((fpx = fopen("3.pgm", "rb")) == NULL) error("can't open file"); /* the car image with the license plate you need to examine*/ if((fpw = fopen("t4.pgm", "rb")) == NULL) error("can't open file"); fpy = fopen("4.pgm","wb"); fpz = fopen("5.pgm","wb"); fpv = fopen("6.pgm","wb");

/* READ HEADER */ if(read_pgm_hdr(fpx, &nrows, &ncols) < 0) error("not a PGM image or bpp > 8"); if(read_pgm_hdr(fpw, &nrows, &ncols) < 0) error("not a PGM image or bpp > 8"); /* ALLOCATE ARRAYS */ x = (unsigned char **)matrix(nrows, ncols, 0, 0, sizeof(char)); w = (unsigned char **)matrix(nrows, ncols, 0, 0, sizeof(char)); y = (unsigned char **)matrix(nrows, ncols, 0, 0, sizeof(char)); if(x == NULL|| y == NULL || w == NULL) error("can't allocate memory"); /* READ THE IMAGES */ for(i = 0; i < nrows; i++) if(fread(&x[i][0], sizeof(char), ncols, fpx) != ncols) error("can't read the image"); for(i = 0; i < nrows; i++) if(fread(&w[i][0], sizeof(char), ncols, fpw) != ncols) error("can't read the image");

31


ECE 532 Project Report

rahulv@email.arizona.edu

/* Initialise all the matrices being used in the code */ for (t=0; t<256; t++) { h[t] = 0; /* Histogram */ p[t] = 0.0; /* Probability */ var2[t] = 0.0; /* Variance 1 */ var1[t] = 0.0; /* Variance 2 */ mu1[t] = 0.0; /* Mean 1 */ mu2[t] = 0.0; /* Mean 2 */ q1[t] = 0.0; /* Q1 */ q2[t] = 1.0; /* Q2 */ H[t] = 0.0; /* Function H */ }

/* Compute the Histogram */ for (i=0;i<nrows;i++) { for (j=0;j<ncols;j++) { b=x[i][j]; h[b]++; } } /* Compute the lower threshold value where h[t] is non zero */ for (t=0; t<256; t++) { if (h[t] != 0) { first = t; break; } }

/* Compute the higher threshold value where h[] is non zero */ for (t=255; t>=0; t--) { if (h[t] != 0) { last = t; break; } }

32


ECE 532 Project Report

rahulv@email.arizona.edu

/* Compute the probablities */ for (t=0; t<256; t++) { p[t] =(double) h[t]/(nrows*ncols); } /* Compute the mean of all pixels */ for (t=0;t<256;t++) { mu += t*p[t]; } /* Initialise the values of variuos parameters at FIRST */ q1[first] = p[first]; q2[first] = 1.0-q1[first]; mu2[first] = (mu - mu1[first-1]*q2[first-1])/q2[first]; for(t=0;t<256;t++) { var2[first] += (t - mu2[first])*(t - mu2[first])*p[t]/q2[first]; }

/* Use Recursion to compute Q1 and Q2 */ for(t=(first+1);t<=(last-2);t++) { q1[t] = q1[t-1] + p[t]; q2[t] = 1.0 - q1[t]; } /* Use Recursion to compute mean1 and Variance1 */ for(t=(first+1);t<=(last-2);t++) { mu1[t] = (q1[t-1]*mu1[t-1]+t*p[t])/q1[t]; var1[t] = (q1[t-1]*(var1[t-1]+(mu1[t-1]-mu1[t])*(mu1[t-1]-mu1[t])) + p[t]*(tmu1[t])*(t-mu1[t]))/q1[t]; } /* Use Recursion to compute mean2 and Variance2 */ for(t=(first+1);t<=(last-2);t++) { mu2[t] = (mu - q1[t] * mu1[t])/(q2[t]);

33


ECE 532 Project Report

rahulv@email.arizona.edu

var2[t] = (q2[t-1]*(var2[t-1]+(mu2[t-1]-mu2[t])*(mu2[t-1]-mu2[t]))-p[t]*(tmu2[t])*(t-mu2[t]))/q2[t]; }

/* Compute the value of H[t] which is to be minimised */ for(t=(first+1);t<=(last-2);t++) { H[t] = (q1[t]*log(var1[t])+q2[t]*log(var2[t]))/2 - q1[t]*log(q1[t])q2[t]*log(q2[t]); }

/* Compute the minimum value of H[t] */ for(t=(first+1);t<=(last-2);t++) { if (H[t] < Hmin) Hmin = H[t]; }

/* Compute the gray level value tmin where H[t] is minimum */ for(t=(first+1);t<=(last-2);t++) { if (H[t] == Hmin) tmin = t ; } printf("The threshold value found by Kittler's algorithm is %d\n",tmin);

/* Compute the segmented image */ for (i=0;i<nrows;i++) { for (j=0;j<ncols;j++) { if (x[i][j] >= tmin) y[i][j] = 255; else y[i][j] = 0; } } /*Compute the end points*/ rows_initial = 0; cols_initial = 0; rows_final = 0;

34


ECE 532 Project Report

rahulv@email.arizona.edu

cols_final = 0; rows = 0; cols = 0; flag = 0 ; for(i=(int)(0.4*nrows);i<(int)(0.5*nrows);i++) { for(j=(int)(0.2*ncols);j<(int)(0.5*ncols);j++) { if(y[i][j] == 0) { rows_initial = i; cols_initial = j; flag = 1; break; } } if (flag == 1) break; } rows_initial = rows_initial - 5;/* tolerance of 5 pixels */ printf("rows_initial = %d cols_initial = %d\n",rows_initial,cols_initial); flag = 0 ; for(i=(int)(0.6*nrows);i>=(int)(0.5*nrows);i--) { for(j=(int)(0.85*ncols);j>=(int)(0.5*ncols);j--) { if(y[i][j] == 0) { rows_final = i; cols_final = j; flag = 1; break; } } if (flag == 1) break; } rows_final = rows_final +10;/* tolerance of 10 pixels*/ printf("rows_final = %d

cols_final = %d\n",rows_final,cols_final);

35


ECE 532 Project Report

rahulv@email.arizona.edu

rows = rows_final - rows_initial; cols = cols_final - cols_initial; z = (unsigned char **)matrix(rows+1, cols+1, 0, 0, sizeof(char)); v = (unsigned char **)matrix(rows+6, cols+6, -3, -3, sizeof(char)); for(i=0;i<=rows;i++) { for(j=0;j<=cols;j++) { z[i][j] = w[i+rows_initial+1][j+cols_initial+1]; v[i][j] = z[i][j]; } } fclose(fpw); /* Match the plate with the database*/ if((fpg1 = fopen("t1.pgm", "rb")) == NULL) error("can't open file"); if((fpg2 = fopen("t12.pgm", "rb")) == NULL) error("can't open file"); if((fpg3 = fopen("t14.pgm", "rb")) == NULL) error("can't open file"); if((fpg4 = fopen("t15.pgm", "rb")) == NULL) error("can't open file"); if((fpg5 = fopen("t17new.pgm", "rb")) == NULL) error("can't open file"); if((fpg6 = fopen("t19.pgm", "rb")) == NULL) error("can't open file"); if((fpg7 = fopen("t23.pgm", "rb")) == NULL) error("can't open file"); if((fpg8 = fopen("t26new.pgm", "rb")) == NULL) error("can't open file"); if((fpg9 = fopen("t30.pgm", "rb")) == NULL) error("can't open file");

36


ECE 532 Project Report

rahulv@email.arizona.edu

if((fpg10 = fopen("t4.pgm", "rb")) == NULL) error("can't open file"); if(read_pgm_hdr(fpg1, &nrows1, &ncols1) < 0) error("not a PGM image or bpp > 8"); if(read_pgm_hdr(fpg2, &nrows2, &ncols2) < 0) error("not a PGM image or bpp > 8"); if(read_pgm_hdr(fpg3, &nrows3, &ncols3) < 0) error("not a PGM image or bpp > 8"); if(read_pgm_hdr(fpg4, &nrows4, &ncols4) < 0) error("not a PGM image or bpp > 8"); if(read_pgm_hdr(fpg5, &nrows5, &ncols5) < 0) error("not a PGM image or bpp > 8"); if(read_pgm_hdr(fpg6, &nrows6, &ncols6) < 0) error("not a PGM image or bpp > 8"); if(read_pgm_hdr(fpg7, &nrows7, &ncols7) < 0) error("not a PGM image or bpp > 8"); if(read_pgm_hdr(fpg8, &nrows8, &ncols8) < 0) error("not a PGM image or bpp > 8"); if(read_pgm_hdr(fpg9, &nrows9, &ncols9) < 0) error("not a PGM image or bpp > 8"); if(read_pgm_hdr(fpg10, &nrows10, &ncols10) < 0) error("not a PGM image or bpp > 8"); g1 = (unsigned char **)matrix(nrows1, ncols1, 0, 0, sizeof(char)); g2 = (unsigned char **)matrix(nrows2, ncols2, 0, 0, sizeof(char)); g3 = (unsigned char **)matrix(nrows3, ncols3, 0, 0, sizeof(char)); g4 = (unsigned char **)matrix(nrows4, ncols4, 0, 0, sizeof(char)); g5 = (unsigned char **)matrix(nrows5, ncols5, 0, 0, sizeof(char)); g6 = (unsigned char **)matrix(nrows6, ncols6, 0, 0, sizeof(char)); g7 = (unsigned char **)matrix(nrows7, ncols7, 0, 0, sizeof(char)); g8 = (unsigned char **)matrix(nrows8, ncols8, 0, 0, sizeof(char)); g9 = (unsigned char **)matrix(nrows9, ncols9, 0, 0, sizeof(char)); g10 = (unsigned char **)matrix(nrows10, ncols10, 0, 0, sizeof(char));

37


ECE 532 Project Report

rahulv@email.arizona.edu

for(i = 0; i < nrows1; i++) if(fread(&g1[i][0], sizeof(char), ncols1, fpg1) != ncols1) error("can't read the image"); for(i = 0; i < nrows2; i++) if(fread(&g2[i][0], sizeof(char), ncols2, fpg2) != ncols2) error("can't read the image"); for(i = 0; i < nrows3; i++) if(fread(&g3[i][0], sizeof(char), ncols3, fpg3) != ncols3) error("can't read the image"); for(i = 0; i < nrows4; i++) if(fread(&g4[i][0], sizeof(char), ncols4, fpg4) != ncols4) error("can't read the image"); for(i = 0; i < nrows5; i++) if(fread(&g5[i][0], sizeof(char), ncols5, fpg5) != ncols5) error("can't read the image"); for(i = 0; i < nrows6; i++) if(fread(&g6[i][0], sizeof(char), ncols6, fpg6) != ncols6) error("can't read the image"); for(i = 0; i < nrows7; i++) if(fread(&g7[i][0], sizeof(char), ncols7, fpg7) != ncols7) error("can't read the image"); for(i = 0; i < nrows8; i++) if(fread(&g8[i][0], sizeof(char), ncols8, fpg8) != ncols8) error("can't read the image"); for(i = 0; i < nrows9; i++) if(fread(&g9[i][0], sizeof(char), ncols9, fpg9) != ncols9) error("can't read the image"); for(i = 0; i < nrows10; i++) if(fread(&g10[i][0], sizeof(char), ncols10, fpg10) != ncols10) error("can't read the image"); /* Compute avearge gray levels */ sum=0; for (i=0;i<rows;i++) { for(j=0;j<cols;j++) {

38


ECE 532 Project Report

rahulv@email.arizona.edu

sum+=v[i][j]; } } avgv = sum/((float)(nrows*ncols)); sum=0; for (i=0;i<rows;i++) { for(j=0;j<cols;j++) { sum+=g1[i+rows_initial][j+cols_initial]; } } avg1 = sum/((float)(nrows1*ncols1)); sum=0; for (i=0;i<rows;i++) { for(j=0;j<cols;j++) { sum+=g2[i+rows_initial][j+cols_initial]; } } avg2 = sum/((float)(nrows2*ncols2)); sum=0; for (i=0;i<rows;i++) { for(j=0;j<cols;j++) { sum+=g3[i+rows_initial][j+cols_initial]; } } avg3 = sum/((float)(nrows3*ncols3)); sum=0; for (i=0;i<rows;i++) { for(j=0;j<cols;j++) { sum+=g4[i+rows_initial][j+cols_initial]; }

39


ECE 532 Project Report

rahulv@email.arizona.edu

} avg4 = sum/((float)(nrows4*ncols4)); sum=0; for (i=0;i<rows;i++) { for(j=0;j<cols;j++) { sum+=g5[i+rows_initial][j+cols_initial]; } } avg5 = sum/((float)(nrows5*ncols5)); sum=0; for (i=0;i<rows;i++) { for(j=0;j<cols;j++) { sum+=g6[i+rows_initial][j+cols_initial]; } } avg6 = sum/((float)(nrows6*ncols6)); sum=0; for (i=0;i<rows;i++) { for(j=0;j<cols;j++) { sum+=g7[i+rows_initial][j+cols_initial]; } } avg7 = sum/((float)(nrows7*ncols7)); sum=0; for (i=0;i<rows;i++) { for(j=0;j<cols;j++) { sum+=g8[i+rows_initial][j+cols_initial]; } } avg8 = sum/((float)(nrows8*ncols8));

40


ECE 532 Project Report

rahulv@email.arizona.edu

sum=0; for (i=0;i<rows;i++) { for(j=0;j<cols;j++) { sum+=g9[i+rows_initial][j+cols_initial]; } } avg9 = sum/((float)(nrows9*ncols9)); sum=0; for (i=0;i<rows;i++) { for(j=0;j<cols;j++) { sum+=g10[i+rows_initial][j+cols_initial]; } } avg10 = sum/((float)(nrows10*ncols10)); /* Compute Cross Co relation Values */ num=0; den=0;

for(i=(0);i<(rows);i++) { for(j=(0);j<(cols);j++) { num += (v[i][j] - avgv)*(g1[i+rows_initial][j+cols_initial] - avg1); den += (v[i][j] - avgv)*(v[i][j] - avgv)*(g1[i+rows_initial][j+cols_initial] avg1)*(g1[i+rows_initial][j+cols_initial] - avg1); } } cfgv1 = num/sqrt(den); num=0; den=0;

41


ECE 532 Project Report

rahulv@email.arizona.edu

for(i=(0);i<(rows);i++) { for(j=(0);j<(cols);j++) { num += (v[i][j] - avgv)*(g2[i+rows_initial][j+cols_initial] - avg2); den += (v[i][j] - avgv)*(v[i][j] - avgv)*(g2[i+rows_initial][j+cols_initial] avg2)*(g2[i+rows_initial][j+cols_initial] - avg2); } } cfgv2 = num/sqrt(den); num=0; den=0; for(i=(0);i<(rows);i++) { for(j=(0);j<(cols);j++) { num += (v[i][j] - avgv)*(g3[i+rows_initial][j+cols_initial] - avg3); den += (v[i][j] - avgv)*(v[i][j] - avgv)*(g3[i+rows_initial][j+cols_initial] avg3)*(g3[i+rows_initial][j+cols_initial] - avg3); } } cfgv3 = num/sqrt(den); num=0; den=0; for(i=(0);i<(rows);i++) { for(j=(0);j<(cols);j++) { num += (v[i][j] - avgv)*(g4[i+rows_initial][j+cols_initial] - avg4); den += (v[i][j] - avgv)*(v[i][j] - avgv)*(g4[i+rows_initial][j+cols_initial] avg4)*(g4[i+rows_initial][j+cols_initial] - avg4); }

42


ECE 532 Project Report

rahulv@email.arizona.edu

} cfgv4 = num/sqrt(den); num=0; den=0; for(i=(0);i<(rows);i++) { for(j=(0);j<(cols);j++) { num += (v[i][j] - avgv)*(g5[i+rows_initial][j+cols_initial] - avg5); den += (v[i][j] - avgv)*(v[i][j] - avgv)*(g5[i+rows_initial][j+cols_initial] avg5)*(g5[i+rows_initial][j+cols_initial] - avg5); } } cfgv5 = num/sqrt(den); num=0; den=0;

for(i=(0);i<(rows);i++) { for(j=(0);j<(cols);j++) { num += (v[i][j] - avgv)*(g6[i+rows_initial][j+cols_initial] - avg6); den += (v[i][j] - avgv)*(v[i][j] - avgv)*(g6[i+rows_initial][j+cols_initial] avg6)*(g6[i+rows_initial][j+cols_initial] - avg6); } } cfgv6 = num/sqrt(den); num=0; den=0; for(i=(0);i<(rows);i++) { for(j=(0);j<(cols);j++) {

43


ECE 532 Project Report

rahulv@email.arizona.edu

num += (v[i][j] - avgv)*(g7[i+rows_initial][j+cols_initial] - avg7); den += (v[i][j] - avgv)*(v[i][j] - avgv)*(g7[i+rows_initial][j+cols_initial] avg7)*(g7[i+rows_initial][j+cols_initial] - avg7); } } cfgv7 = num/sqrt(den); num=0; den=0;

for(i=(0);i<(rows);i++) { for(j=(0);j<(cols);j++) { num += (v[i][j] - avgv)*(g8[i+rows_initial][j+cols_initial] - avg8); den += (v[i][j] - avgv)*(v[i][j] - avgv)*(g8[i+rows_initial][j+cols_initial] avg8)*(g8[i+rows_initial][j+cols_initial] - avg8);

} } cfgv8 = num/sqrt(den); num=0; den=0; for(i=(0);i<(rows);i++) { for(j=(0);j<(cols);j++) { num += (v[i][j] - avgv)*(g9[i+rows_initial][j+cols_initial] - avg9); den += (v[i][j] - avgv)*(v[i][j] - avgv)*(g9[i+rows_initial][j+cols_initial] avg9)*(g9[i+rows_initial][j+cols_initial] - avg9); } } cfgv9 = num/sqrt(den);

44


ECE 532 Project Report

rahulv@email.arizona.edu

num=0; den=0; for(i=(0);i<(rows);i++) { for(j=(0);j<(cols);j++) { num += (v[i][j] - avgv)*(g10[i+rows_initial][j+cols_initial] - avg10); den += (v[i][j] - avgv)*(v[i][j] - avgv)*(g10[i+rows_initial][j+cols_initial] avg10)*(g10[i+rows_initial][j+cols_initial] - avg10); } } cfgv10 = num/sqrt(den); printf("cfgv1 = %f\n",cfgv1); printf("cfgv2 = %f\n",cfgv2); printf("cfgv3 = %f\n",cfgv3); printf("cfgv4 = %f\n",cfgv4); printf("cfgv5 = %f\n",cfgv5); printf("cfgv6 = %f\n",cfgv6); printf("cfgv7 = %f\n",cfgv7); printf("cfgv8 = %f\n",cfgv8); printf("cfgv9 = %f\n",cfgv9); printf("cfgv10 = %f\n",cfgv10); cfg[1] = cfgv1; cfg[2] = cfgv2; cfg[3] = cfgv3; cfg[4] = cfgv4; cfg[5] = cfgv5; cfg[6] = cfgv6; cfg[7] = cfgv7; cfg[8] = cfgv8; cfg[9] = cfgv9; cfg[10] = cfgv10;

45


ECE 532 Project Report

rahulv@email.arizona.edu

max = 0; for (i=1;i<=10;i++) { if(max < cfg[i]) { max = cfg[i]; d = i; } } printf("the plate matches with cfg%d and has a cross corelation value of %f ",d,max);

/* WRITE THE IMAGE */ fprintf(fpy, "P5\n%d %d\n255\n", ncols, nrows);

for(i = 0; i < nrows; i++) if(fwrite(&y[i][0], sizeof(char), ncols, fpy) != ncols) error("can't write the image"); fprintf(fpz, "P5\n%d %d\n255\n", cols, rows);

for(i = 0; i < rows; i++) if(fwrite(&z[i][0], sizeof(char), cols, fpz) != cols) error("can't write the image"); fprintf(fpv, "P5\n%d %d\n255\n", cols, rows); for(i = 0; i < rows; i++) if(fwrite(&v[i][0], sizeof(char), cols, fpv) != cols) error("can't write the image"); /* CLOSE FILE & QUIT */ fclose(fpx); fclose(fpy); fclose(fpz); fclose(fpv); fclose(fpg1); fclose(fpg2); fclose(fpg3); fclose(fpg4);

46


ECE 532 Project Report

rahulv@email.arizona.edu

fclose(fpg5); fclose(fpg6); fclose(fpg7); fclose(fpg8); fclose(fpg9); fclose(fpg10); exit(0); }

47


Turn static files into dynamic content formats.

Create a flipbook
Issuu converts static files into: digital portfolios, online yearbooks, online catalogs, digital photo albums and more. Sign up and create your flipbook.