Car license plate recognition using template matching algorithm

advertisement
CAR LICENSE PLATE RECOGNITION USING TEMPLATE MATCHING
ALGORITHM
Pramod S. Kapadia
B.E., Pune University, India, 2006
PROJECT
Submitted in partial satisfaction of
the requirements for the degree of
MASTER OF SCIENCE
in
ELECTRICAL AND ELECTRONIC ENGINEERING
at
CALIFORNIA STATE UNIVERSITY, SACRAMENTO
FALL
2010
CAR LICENSE PLATE RECOGNITION USING TEMPLATE MATCHING
ALGORITHM
A Project
by
Pramod S. Kapadia
Approved by:
__________________________________, Committee Chair
Jing Pang, Ph.D.
__________________________________, Second Reader
Preetham B. Kumar, Ph.D.
____________________________
Date
ii
Student: Pramod S. Kapadia
I certify that this student has met the requirements for format contained in the University
format manual, and that this project is suitable for shelving in the Library and credit is to
be awarded for the Project.
__________________________, Graduate Coordinator
Preetham B. Kumar, Ph.D.
Department of Electrical and Electronic Engineering
iii
___________________
Date
Abstract
of
CAR LICENSE PLATE RECOGNITION USING TEMPLATE MATCHING
ALGORITHM
by
Pramod S. Kapadia
License Plate Recognition or LPR is an image-processing technology used to
identify vehicles by their license plates. This technology is used in various applications
involving security, traffic, law enforcement, public safety and transportation sectors. It
mainly uses software code that enables computer systems to read automatically the
registration number (license number) of vehicles from digital pictures.
The project explains various algorithms that are exercised to recognize the
characters present on the California Car License Plate. One of them is Template
Matching algorithm that has an ability to store the information of a particular size
template in the form of four 16-bit vectors and apply it for recognizing the characters.
This feature of the algorithm mentioned above helped in achieving faster character
recognition of the license plate. This process of character recognition consists of steps
like Image processing, Defragmentation, Resizing and Character localization that are
required to be performed on the image in order for Template Matching to be done.
iv
The final goal of the project was to simulate these algorithms initially on
Microsoft Visual Studio using Open CV libraries. Once this was established, the design
was transferred on the TI’s video development platform DM6437 DVDP for testing and
performance analysis. The earlier mentioned algorithmic steps were written in C
programming language and demonstration of the project was successfully presented on
the TI’s DSP board EVM320DM6437.
_______________________, Committee Chair
Jing Pang, Ph.D.
_______________________
Date
v
ACKNOWLEDGMENTS
I would sincerely like to thank Dr. Jing Pang for providing me a wonderful
opportunity to work on this project, which provided a great exposure to the field of image
and video processing. I am grateful that she provided all the necessary resources, help
and guidance needed to complete the project successfully. Her knowledge and expertise
in the DSP field was very beneficial to me in order to understand the project and finish it
successfully. Without her key practical inputs, this project would not have completed
successfully on the Texas Instrument DAVINCI EVM320DM6437 board, which is
currently an industry-recognized platform.
I would like to express my brief appreciation towards the engineering community
at Texas Instruments for providing vital information about video processing steps and
methodologies on the above-mentioned board.
I would also like to thank Dr. Preetham B. Kumar for reviewing my report and
providing valuable suggestions that helped me to improve my project report. I would like
to show my gratitude towards all the faculty member of Department of Electrical and
Electronics Engineering at California State University, Sacramento for the help and
support to complete my graduation successfully. Last but not the least; I would like to
heartily thank my family members and all my friends for providing me strength and
inspiration during difficult times in the past 1 year.
vi
TABLE OF CONTENTS
Page
Acknowledgments....................................................................................................... vi
List of Tables .............................................................................................................. ix
List of Figures ............................................................................................................... x
Chapter
1. INTRODUCTION ................................................................................................. 1
1.1 Introduction to License Plate Recognition System .................................... 1
1.2 Purpose of the Project ................................................................................ 1
1.3 Significance of the Project .......................................................................... 2
1.4 Organization of Report ............................................................................... 2
2. BASIC INTRODUCTION TO DIGITAL IMAGING ........................................... 4
2.1 Digital Imaging ........................................................................................... 4
2.2 The RGB Color Space ................................................................................ 4
2.3 YUV Color Space ....................................................................................... 5
2.4 YCrCb (or YCbCr) Color Space ................................................................. 5
3. LICENSE PLATE CHARACTER RECOGNITION ALGORITHMS…………...6
3.1 Design Approach ........................................................................................ 6
3.2 Design Overview ........................................................................................ 6
3.3 Algorithm Description ................................................................................ 8
3.3.1 Image Processing ............................................................................ 8
3.3.2 Defragmentation ............................................................................. 9
3.3.3 Resizing .......................................................................................... 9
3.3.4 Four Quadrant Algorithm ............................................................. 12
3.3.5 Template Matching ....................................................................... 14
4. TMS320DM6437 DVDP PLATFORM OVERVIEW ......................................... 18
4.1 Introduction ............................................................................................... 18
4.2 Video Interfaces on TMS320DM6437 DVDP ......................................... 19
vii
4.3 DM6437 Functional Overview ................................................................. 19
4.4 TMS 320C64X+ DSP Cache .................................................................... 22
4.5 Design Implementation ............................................................................. 22
5. SIMULATION AND IMPLEMENTATION RESULTS ..................................... 25
5.1 Results and Performance Analysis............................................................ 25
5.2 Simulation Results .................................................................................... 26
5.2.1 Case 1: Clear Image and High Resolution .................................... 26
5.2.2 Case 2: Low Quality Image and Poor Lighting Condition ........... 28
5.2.3 Case 3: Blurry Image .................................................................... 29
5.2.4 Case Analysis................................................................................ 30
5.3 Implementation Results ............................................................................ 31
5.3.1 Case 1: High Quality Image .......................................................... 31
5.3.2 Case 2: Low Quality Image (Plate Detection + Recognition) ...... 32
5.3.3 Case 3: Bright Image (Plate Detection + Recognition) ................ 33
5.3.4 Case Analysis................................................................................ 34
5.4 Performance Analysis ............................................................................... 35
5.5 Optimization Techniques .......................................................................... 37
5.5.1 Code Optimization ........................................................................ 37
5.5.2 Cache Optimization ...................................................................... 39
5.5.3 Compiler Optimization ................................................................. 40
5.5.4 Optimization Results and Summary ............................................. 41
6.
CONCLUSION.....................................................................................................43
Appendix Simulation and Implementation Code ........................................................ 44
References ................................................................................................................... 72
viii
LIST OF TABLES
Page
1.
Table 3.1 Vectors for 36 Templates (Characters + Numbers)………………...…17
2.
Table 5.1 Simulation and Implementation Results…..……………….……...…..25
3.
Table 5.2 Case 1 Simulation Results for Character Recognition……….………..27
4.
Table 5.3 Case 2 Simulation Results for Character Recognition………………...29
5.
Table 5.4 Case 3 Simulation Results for Character Recognition………………...30
6.
Table 5.5 Performance Profile Summary…………….…………………...……...36
7.
Table 5.6 Performance Profile Summary After Cache Optimization…..………..40
8.
Table 5.7 Performance Profile Summary Before and After Optimization
with CPU of 600 Mhz…………………………………………………………....42
ix
LIST OF FIGURES
Page
1.
Figure 3.1 California License Plate ...…..………….……………….…..………...7
2.
Figure 3.2 Template for Database……….….…………..……….....…………...…8
3.
Figure 3.3 Resizing Algorithm Basic Concept..…….……..……..…………...…10
4.
Figure 3.4 Resizing Algorithm Requirement….………..……..……………..…..11
5.
Figure 3.5 Resizing Algorithm Graphical Representation……..….….……….....12
6.
Figure 3.6 Four Quadrant Generation Basic Flow……………..………...…........13
7.
Figure 3.7 16 Bit Vector Generation using Four Quadrant Algorithm….....…….13
8.
Figure 3.8 Template Matching Vector Comparison……….….……………..…..15
9.
Figure 4.1 Block Diagram of EVM DM6437...……………….……………...….18
10.
Figure 4.2 Functional Block Diagram of DM6437....…….……….………….....20
11.
Figure 5.1 Simulation Results for Case 1……………………………..…....…....27
12.
Figure 5.2 Simulation Results for Case 2…….………..…………………...........28
13.
Figure 5.3 Simulation Results for Case 3….………….….…………………...…30
14.
Figure 5.4 Implementation Results for Case 1…………….…………………......32
15.
Figure 5.5 Implementation Results for Case 2…………………..…………..…...33
16.
Figure 5.6 Implementation Results for Case 3….…………………………..........34
x
1
Chapter 1
INTRODUCTION
1.1. Introduction to License Plate Recognition System
The License Plate Recognition (LPR) system is an integrated hardware and software
device, which has the ability to detect and read the characters from the license plate and
convert it into electronic text like ASCII characters. Research has shown that majority of
crimes in United States are related to vehicles. Thus, the ability of LPR system to
automate the process of identifying vehicles of interest has revolutionized law
enforcement and has improved public security [1]. The input to the LPR system is a
digital image of the front or the rear end of the vehicle's license plate, taken by the
sophisticated cameras. Further processing on this image is carried out for the purpose of
license plate detection. After the plate information is extracted from the image, it is
further segmented to locate individual characters. There are several methods available in
the market used for recognizing the characters on the plate i.e., Character recognition
using Feed Forward Neural Network, Template Matching, etc. Each segmented
characters are identified using one of these algorithms and converted into electronic data.
This data can be used in various safety and traffic applications like tolling, law
enforcement, and thus useful in fighting crime and fraud thereby improving public safety.
1.2. Purpose of the Project
Automatic License Plate recognition is one of the techniques used for vehicle
identification purposes. The sole intention of this project is to find the most efficient way
to recognize the registration information from the digital image (obtained from the
2
camera). This process usually comprises of three steps. First step is the license plate
localization, regardless of the license-plate size and orientation. The second step is the
segmentation of the characters and last step is the recognition of the characters from the
license plate. Thus, this project uncovers the fundamental idea of various algorithms
required to accomplish character recognition from the license plate during Template
Matching.
1.3. Significance of the Project
The main importance of the project lies in the way the various algorithms are
implemented to create an automated system for License Plate Recognition. This project
focuses on the new way of storing the fixed size template in the database using four 16bit vectors that help in reducing the computation time required to find the characters on
the plate during template matching. On the hardware side, it helps understanding TI’s
DAVINCI EVM320DM6437 platform used for developing a complete model for LPR
system. Algorithms like Defragmentation, Resizing, Character Localization and Template
matching were tested both in Visual studio and on TI’s DAVINCI EVM320DM6437
platform and are written in the advance C and C++ programming language.
1.4. Organization of Report
Chapter 2 contains basic concepts of the smallest image (Pixel) elements and
color space that are important in understanding the whole field of image and video
processing.
Chapter 3 gives information about various algorithms used in the design and are
described briefly in this chapter.
3
Chapter 4 contains information about the Texas instruments image and video
development platform TMS320DM6437. It discusses various capabilities and features of
the board. Moreover, this chapter also discusses about various functions that are required
for the implementation of license plate recognition
Chapter 5 presents the design results including simulation and DM6437 hardware
implementation. It also discusses about various optimization techniques that are taken to
improve the performance of the design.
Chapter 6 presents the challenges, limitations and conclusions derived from this
project along with the future work perspective. References are provided in Reference
section. The program code for simulation and hardware implementation are given in
Appendix section.
4
Chapter 2
BASIC INTRODUCTION TO DIGITAL IMAGING
2.1 Digital Imaging
In digital imaging, pixel is a smallest addressable screen element that is normally
arranged in a two-dimensional grid, and is often represented using dot or a square. The
intensity of each pixel varies to represent a particular type of color shade. In color image
systems, either three-component intensities such as red, green, and blue or four
component intensities such as cyan, magenta, yellow, and black typically represent a
color. The number of distinct colors that represents a pixel depends on the number of bits
per pixel (bpp). A 1 bpp image uses 1-bit for each pixel, so each pixel can be either on or
off. Each additional bit doubles the number of colors available, for example, a 2 bpp
image can have 4 colors, and a 3 bpp image can have 8 colors.
The color depth is normally the sum of the bits allocated to each of the red, green,
and blue components. High color usually consists of 16 bpp and normally has five bits for
red and blue, and six bits for green, as human eye is more sensitive to errors in green than
in the other two primary colors. A 24-bit depth allows 8 bits per component. A color
space is a mathematical representation of a set of colors. The three most popular color
models are RGB used in computer graphics, YUV and YCrCb used in video systems,
CMYK used in color printing [2].
2.2 The RGB Color Space
The red, green and blue (RGB) color space is widely used throughout computer
graphics. These are three primary additive colors and each individual components are
5
added together to form a desired color. All three components need equal bandwidth to
generate arbitrary colors within the RGB color cube.
2.3 YUV Color Space
The YUV color space is use by the analog PAL, NTSC and SECAM color
video/TV standards. The Y component determines the brightness of the color while U
and V component determines the color itself. As human eye is more responsive to
brightness than color of the image, its encoding provides low bandwidth to the
chrominance component.
2.4 YCrCb (or YCbCr) Color Space
The YCrCb or YCbCr color space was develop as part of the ITU-R BT.601
[11] during the development of a worldwide digital component video standard. YCbCr is
an encoded nonlinear RGB signal that is widely used in MPEG and JPEG compression
standard. Y has a nominal range of 16–235; Cb and Cr have a nominal range of 16–240.
To accommodate storage and bandwidth limitation, the two color components (Cb and
Cr) are compressed by sampling them at lower rate than the brightness component. This
is known as Chroma sub sampling.
The TI Board uses YCrCb format in the interleaved fashion called 4:2:2 YCrCb
sub sampled format. It is also known as packed YCrCb format. In this format Cb and Cr
are sampled at half the sample rate of Y. Thus the horizontal chroma resolution is halved
while the full resolution is retained in the vertical direction with respect to luminance.
6
Chapter 3
LICENSE PLATE CHARACTER RECOGNITION ALGORITHMS
3.1 Design Approach
There are a number of techniques used to recognize the characters on the license
plate. After skimming through several IEEE papers, the most common technique brought
to light for character recognition is the use of Template Matching algorithm. Based on
several concepts available for implementing this algorithm that are currently available in
the market, the most common drawback is its execution time and memory usage for
storing the template. Hence, in order to overcome this drawback a complete new
methodology is used which not only makes this matching algorithm work faster but also
requires less memory space to store all 36 templates into the database. This method is
termed as “Four Quadrant Algorithm”. The basic concept behind this optimization
technique is to convert 64 × 128 pixel image data (which consumes 8 kB of memory
storage) into four 16-bit vectors and uses these vector values during character
Recognition. However, to implement this algorithm successfully, each character on the
plate should be of 64 × 128 pixel. Thus to make each character of 64 × 128 pixel there is
a need of a resizing algorithm which is also designed and tested successfully.
3.2 Design Overview
Based on various standards used in different countries, the vehicle license plates
are usually different in form, shape and material. Therefore, the LPR systems designed
are country specific and are adapted to the country specification. In US, every state has
7
its own laws and rules governing the license plates. Hence, the first step in implementing
the LPR System is to decide in which state the design has to be implemented. In this
project, California License plate is selected for designing the License Plate recognition
model and hence all the specifications of the design are based on the standard set by the
state of California. The basic diagram of a California License plate is as shown in Figure
3.1 below. Thus each license plate has following details on it viz., Registration Number,
Registration Valid Info and State Information.
Figure 3.1 California License Plate
This design includes five primary algorithms used for identifying the license plate
characters:
1. Image Processing – Simple Algorithm, which converts the pixel value to either 0
or 255, based on the set threshold. Basically, this step extracts the intensity
information from the image and converts it to either black (0) or white (255)
similar to the intensity defined by a 1-bit per pixel where 0 represents black and 1
represents white. This technique is most commonly known as Image Binarization.
2. Defragmentation – This algorithm finds the registration number from the
California license plate, segments the registration number and stores coordinate of
each character from the plate.
8
3. Resizing – Converts each individual character to a fixed size template. In this
project, the plate registration characters/numbers are converted to fixed size
templates of 64 × 128 pixels. This makes the system completely independent of
the detected plate size.
4. Four Quadrant Method – Each of these templates are divided into four quadrants
and used for generating four 16-bit vectors. In short, this technique is used to store
a huge chunk of data from a template into four 16-bit vectors.
5. Template Matching – The four 16-bit vectors generated from the detected
characters are compared in a bitwise order with the vectors that are stored in the
database. The image used to generate these database vectors is as shown in Figure
3.2 below and they are generated by using the above listed steps (1 to 4). Based
on the comparison, the best match character from the database is displayed.
Figure 3.2 Template for Database
3.3 Algorithm Description
3.3.1 Image Processing
This Algorithm copies the pixel values in a two Dimensional Array obtained from the
Frame Buffer (DSP Kit) or from the stored image (Simulator). Based on the set threshold
and pixel values obtained from the frame it converts the pixel value to either 0 or 255.
9
Here ‘0’ stands for complete black pixel and ‘255’ stands for complete white pixel. In
short, the whole image is converted to binary image of 0’s and 1’s. This step is very
important as both defragmentation algorithm and resizing algorithm performance
depends on the said digital conversion.
3.3.2 Defragmentation
Once the pixel values are converted into a digital format (0 or 255), the next step is to
look for the characters present in the plate. The “California License Plate” has details
such as Registration No., Registration Valid Info and State Information mentioned on it.
Therefore, to defragment each individual character this algorithm is divided into two
parts namely Horizontal Defragmentation and Vertical Defragmentation. Horizontal
defragmentation separates registration number and state information from the plate. To
perform this operation, a logic based on aspect ratio is used. Once the registration number
information is obtained, vertical defragmentation separates individual characters and
stores each character’s coordinate information.
3.3.3 Resizing
Now to make this design completely independent of size of the license plate and to
match each character with the fixed size template (64 × 128 pixel) present in the
database, Resizing algorithm is used. The basic function of this algorithm is to grab the
coordinate information provided by the Defragmentation Algorithm and resize it to a
fixed size template. The major problem with the resizing algorithm is the loss of data
during its resizing process. Hence, in order to make sure that only good information
related to a character is replicated, this algorithm is applied to the binary image. This
10
action was done during the Image processing step where it converts a gray scale image to
a digital format of 1’s and 0’s using a fixed threshold. Thus, this step helps in replicating
useful data during resizing and is very efficient for this particular application. It works on
a simple concept of adding or removing white and black pixels uniformly from the image
based on whether the image needs to get bigger or vice - versa. Basic graphical view for
the resizing algorithm is as shown in the Figure 3.3.
Figure 3.3 Resizing Algorithm Basic Concept
Now
to
implement
this
algorithm,
two
1-Dimensional
Arrays
(template_y_coordinate and template_x_coordinate) each of size 128 and other of size 64
are required. The size of this array depends on the size of the template used for matching.
For this project, in order to generate four 16-bit vectors, the whole template needs to be
divided into blocks of 8 × 16 pixels, which is the next step after resizing. Based on this
block size and length of the vector (16 bit), the size of the template was decided. Now
11
assume that the template shown in the Figure 3.4 is the size of the character, defined by
width X and height Y. In order to resize this character to a known size of 64 × 128 pixel,
divisional ratio should be such that divisor_x = X/X′ and divisor_y = Y/Y′.
Figure 3.4 Resizing Algorithm Requirement
The divisor value helps to maintain the uniformity while adding or removing the
pixel values during the image resizing. The pictorial representation of this algorithm is as
shown in Figure 3.4. This divisional value is multiplied with each address value of the
respective 1-dimensional array and the values obtained are stored at the same address
location of the array. The complete sequence of this flow is as shown in Figure 3.5.
12
Figure 3.5 Resizing Algorithm Graphical Representation
3.3.4 Four Quadrant Algorithm
Once the image is resized, the next step is to generate four 16-bit vectors. To do so,
the obtained resized image is divided into tiny blocks of 8 × 16 pixel. Each of this block
was scanned for its pixel values and based on majority color pixel’s (either black or
white) this whole block was transformed into 1’s or 0’s format. For example, out of 128
pixel values, if a block consists of 85 black pixels and 43 white pixels, then all pixels in
the block are converted to black pixels with the binary value of 0’s. Once each block is
transformed to 1’s or 0’s, this digitized format is further used for the vector generation.
The complete sequence of this flow is as shown in Figure 3.6. The Figure 3.7 shows a
13
way in which the template is divided into four quadrants and how these four 16-bit
vectors were generated from the whole template.
Figure 3.6 Four Quadrant Generation Basic Flow
Figure 3.7 16-bit Vector Generation using Four Quadrant Algorithm
14
3.3.5 Template Matching
This algorithm is used to match two generated vectors in a bitwise order obtained
from different templates. Now, the first requirement for template matching is to create a
database. To enforce this, the only thing required is an image with 36 characters in a
particular font format. In California, the type of font found on license plate is
“Penitentiary Gothic” [3]. Based on this specification, the image is selected and is as
shown in Figure 3.2. A database of four 16-bit vectors is created for each individual
character present in the image. These generated vectors are stored in a text file. This text
file is as shown in Table 3.1 with additional details included for reader’s convenience. All
these vectors for the database are created using the same steps that were mentioned
above. Using file I/O operation, this text file is copied in a 2-dimensional array and each
of these vectors are compared in their respective quadrant during template matching. The
complete sequence of this flow is as shown in the Figure 3.8. There are two parts to the
Template Matching Algorithm. In the first part, it calculates the matching percentile for
the whole image i.e., each template consists of 8192 pixels. Based on the number of
matched pixels between two templates, it calculates the overall matched percentile. In the
second part, it calculates the region wise percentile if, the value obtained in part one is
less than 85% i.e., it calculates the percentile of matched pixels, quadrant - wise and
averages out the final value. Depending on the best match obtained from all the 36
templates, the output is displayed in the form of electronic data and can be used further
by the developer for implementing various applications.
15
Figure 3.8 Template Matching Vector Comparison
The following Table 3.1 displays four information viz. characters, quadrant,
vector and a reference number. Every character has its own unique reference number,
which is used as identification during template matching. It also displays the value of 16bit vector in a decimal format for each respective quadrant. These vectors were saved
separately in a text file and were called and stored in the 2-dimensional array named
“Quadrant” using file I/O operation during Template Matching.
Character Quadrant
I
II
A
III
IV
I
II
B
III
IV
Vector
59367
50131
39297
48444
445
48569
32956
48128
Ref. No
0
1
Character Quadrant
I
II
S
III
IV
I
II
T
III
IV
Vector
33599
40935
62460
31745
231
59367
59367
59367
Ref. No.
18
19
16
Character Quadrant
I
II
C
III
IV
I
II
D
III
IV
I
II
E
III
IV
I
II
F
III
IV
I
II
G
III
IV
I
II
H
III
IV
I
II
I
III
IV
I
II
J
III
IV
I
II
K
III
IV
I
II
L
III
IV
Vector
33084
16191
16191
15488
316
15420
15420
15361
63
16191
1855
16128
63
16191
3903
16191
33084
16191
14396
15489
15932
15420
60
15420
231
59367
59367
59136
64764
64764
64764
15489
14371
3871
1827
14652
16191
16191
16191
16128
Ref. No
2
3
4
5
6
7
8
9
10
11
Character Quadrant
I
II
U
III
IV
I
II
V
III
IV
I
II
W
III
IV
I
II
X
III
IV
I
II
Y
III
IV
I
II
Z
III
IV
I
II
0
III
IV
I
II
1
III
IV
I
II
2
III
IV
I
II
3
III
IV
Vector
15420
15420
15420
15488
15420
39321
51651
50151
15420
15492
33153
33177
15513
50147
50113
39228
15513
39875
59367
59367
252
63987
59343
40704
33084
15420
15420
15488
49404
63987
59295
16128
50051
58339
58339
58112
380
64752
57596
64513
Ref. No.
20
21
22
23
24
25
26
27
28
29
17
Character Quadrant
I
II
M
III
IV
I
II
N
III
IV
I
II
O
III
IV
I
II
P
III
IV
I
II
Q
III
IV
I
II
R
III
IV
Vector
15384
2
9782
15420
15388
3084
9264
14392
60
15420
15420
15360
316
15360
1855
16191
33084
15420
15412
227
316
15360
825
14652
Ref. No
12
13
14
15
16
17
Character Quadrant
I
II
4
III
IV
I
II
5
III
IV
I
II
6
III
IV
I
II
7
III
IV
I
II
8
III
IV
I
II
9
III
IV
Vector
59343
53151
40761
249
63
792
64764
31745
63715
53123
6204
15489
248
63987
62435
59367
33084
15360
60
15489
33084
15420
33267
51103
Table 3.1 Vectors for 36 Templates (Characters + Numbers)
Ref. No.
30
31
32
33
34
35
18
Chapter 4
TMS320DM6437 DVDP PLATFORM OVERVIEW
4.1 Introduction
To evaluate and develop various video applications, EVM DM6437 provides a
good platform with several onboard devices. Key features include DM6437 processor
operating up to 600 Mhz, TVP5146M2 video decoder, ports for composite or S video,
four video DAC outputs, 128 Mbytes of DDR2 DRAM, 16 Mbytes of non-volatile Flash
memory, 64 Mbytes NAND Flash, 2 Mbytes SRAM, configurable boot load options and
Embedded JTAG emulation interface. The EVM is designed to work with TI’s Code
Composer Studio Development. Code Composer communicates with the board through
the embedded emulator. Block diagram of this platform is shown in Figure 4.1.
Figure 4.1 Block Diagram of EVM DM6437 [6]
19
4.2 Video Interfaces on TMS320DM6437 DVDP
Texas Instruments DM6437 processor is interfaced to various on-board
peripherals through integrated device interfaces and 8-bit wide EMIF bus. The DM6437
EVM comprises of input and output video ports that can support a variety of user
application. These interfaces are discussed in the following two sections below [7].
1) Input Video Port Interfaces:
The DM6437 EVM supports video capture through S video or composite video
input port that is decoded by TVP5146M2 decoder. Texas Instrument’s
TVP5146M2 is a high quality video digital decoder that digitizes and decodes all
popular analog video formats into digital component.
2) On Chip Video Output DAC:
The DM6437 incorporates four output DACs interfacing to various output
standards. The outputs of the DACs are programmable to support composite
video, component video or RGB color format. The DACs can operate at either 27
Mhz or 54 Mhz sampling rate to support either SDTV (interlaced) or EDTV
(progressive) signals.
4.3 DM6437 Functional Overview
Functional block diagram of DM6437 is shown in Figure 4.2. Only Video
Processing Subsystem is explained briefly in this project.
20
Figure 4.2 Functional Block Diagram of DM6437 [6]
The DM6437 device includes a Video Processing Subsystem (VPSS) with two
configurable video/imaging peripherals [6].
1) Video Processing Front-End (VPFE)
2) Video Processing Back-End (VPBE)
The Video Processing Front-End (VPFE) is used to capture input video. It comprises of
following modules:
a) CCD Controller (CCDC) – The CCDC is responsible for accepting raw
image/video data from a CMOS or CCD sensor. It can also accept YUV video
data from video decoder devices. The raw data obtained can be used to compute
various statistic to eventually control the image/video tuning parameters.
b) Preview Engine (Previewer) - It is a real-time image-processing engine that
21
takes raw image data from a CMOS sensor or CCD and converts it into YCrCb
422 format that is amenable for compression or display.
c) Hardware 3A (H3A) - It provides statistical information on the raw color data,
which can be further used to adjust various parameters for video or image
processing.
d) Resizer - It provides a mean to size the input image data to the desired display
or video encoding resolution. It accepts image data for separate horizontal and
vertical resizing from 1/4× to 4× in increments of 256/N, where N is between 64
and 1024.
The Video Processing Back-End (VPBE) provides an output interface for display
devices. It comprises of following sub modules:
a) On-Screen Display Engine (OSD) - The primary function of this module is to
gather and blend display windows with video data and pass it to the video
encoder in YCrCb format. It is capable of handling 2 separate video windows
and 2 separate OSD windows.
b) Video Encoder (VENC) - It takes the display frame from the OSD and formats
it to the desired output signal that are required to interface to the display
devices. It provides four analog DACs providing means for composite video, SVideo, and/or Component video output. The VENC also provides up to 24 bits
of digital output to interface to RGB888 devices.
22
4.4 TMS 320C64X+ DSP Cache
The TMS 320C64X+ utilizes a highly efficient two-level real-time cache for
internal program and data storage. The cache provides code and data to the CPU at the
speed of the processor, thus reducing the CPU to memory processing bottleneck. On the
first level, it consist of dedicated program and data memory which can be configured into
SRAM and cache. The size of cache is user configurable and can be set to 4K, 8K, 16K
or 32K bytes. The L1 memory is connected to a second-level memory of on-chip memory
called L2. The L2 memory acts as a bridge between the L1 memory and memory located
off-chip. Level 2 memory is also configurable and can be split into L2 SRAM and cache
with up to 256 Kbytes of cache. Thus, the L2 memory can function as mapped SRAM, as
a cache, or as a combination of both. The L2MODE field in the cache configuration
register (CCFG) determines what portion of L2 is mapped as SRAM and what portion
acts as cache. The mode with no L2 cache is referred to as ‘ALL SRAM’ mode [10].
4.5 Design Implementation
The main objective of this project was to create a complete model for the LPR system
and EVM-DM6437 kit provided the required base needed for its implementation. This kit
provides different board support libraries and pre – built software packages that can be
used based on specific application required. “Video Preview” code example from Texas
Instrument was used as a reference and seven functions needed for character recognition
were embedded in this code to achieve the required functionality. The board provided an
interface where camera was connected at the video input port through which front or rear
end car images were captured. The stored car images were used for license plate
23
detection [9]. The goal of this project was to test template-matching algorithm for
character recognition from the detected license plate. All algorithms, previously
mentioned in chapter 3 were divided into seven functions and are discussed very briefly
below. For testing and debugging purposes, two functions namely Reprocess Image and
Process Image were created that can be completely ignored during performance analysis.
1) Image_copy - This function simply copies the pixel values from the image
after processing it to either 0 or 255 based on the comparison made on the set
threshold.
2) Defragmentation - This function divides the whole license plate and localizes its
characters coordinates.
3) Resizing_quad_gen - Once the coordinate of each characters are known, the next
step is to resize it to a fixed size template and then divide this template into four
16 - bit vectors. This function is used to achieve the two tasks as described.
Firstly, it resizes to a fixed size template i.e. 64 x 128 pixel. Secondly, it converts
this resize image into a block of 8 x 16 pixel and generates four 16 bit vectors. In
chapter 3 above this was explained in detail.
4) File_mapping - This function grabs the data from the text file, stores it in an array
and uses it for template matching. For template matching, all the data for 36
templates (26 characters + 10 numbers) are stored in a text file in the form of four
16 - bit vectors. This data is then used for matching the contents from the plate.
5) Reprocess_image - This function is use to create the visibility of results on the
TV screen. It clears all the image data from the screen like a blank white Board.
24
This is an extra function and can be ignore during performance analysis.
6) Template_matching – It is used for matching two templates one from the
database and one from the License plate.
7) Process_image – Process_image is a function used to display all the matched
characters on the TV screen. It is created not only to test the results but also to
provide a high level of convenience to the designer during debugging. Like
Reprocess_image, this function is ignored during performance analysis.
25
Chapter 5
SIMULATION AND IMPLEMENTATION RESULTS
5.1 Results and Performance Analysis
In order to expect best results from the plate recognition algorithm, an image
acquisition system must provide a stable, balanced and good quality image under all
working conditions. However, due to several technical shortcomings of the image
acquisition system, the captured image may have some noise, blurriness etc., associated
with it that may affect the recognition results. The table 5.1 summarizes the simulation
and implementation results acquired from random 20 plates. Based on different test
criteria, functionality and integrity of the algorithm for the recognized characters are
tested. Forty percent of the plates used during testing are images with good high contrast,
good sharpness and good lighting conditions. Another forty percent of the test cases are
done on low quality images captured under poor lighting conditions and the remaining 20
percent of them are blurry images.
Criteria
Input
Images
Results based on
simulation
Matching (%)
Results based on
Hardware
Implementation
Matching (%)
High resolution
Image
Low resolution
image
8
100
94
8
100
89
4
100
80
Blurry Images
Table 5.1 Simulation and Implementation Results
26
From the above table, it can be concluded that conditions such as poor lighting,
noise, blurriness etc., that causes the characters to change are likely to return false
recognition results. Image Results for the above-mentioned criteria are as shown in
various test cases below.
5.2 Simulation Results
In order to test design algorithms during the initial phase of the implementation, a visual
environment is created in Microsoft Visual Studio using OpenCV libraries. Using several
built in features of this library, Three display windows were created that provided image
results at several stages during simulation [4][5]. Open CV library functions are the most
powerful tool that allows computers to see and make decision based on the data. The
library functions available are highly optimized that can run code in real time and helps
user to develop sophisticated vision application quickly.
5.2.1 Case 1: Clear Image and High Resolution
This type of image provides the best results and serves as an ideal case for
character recognition. Image clarity and resolution of the picture, both are highly
dependent on the type of the camera used for capturing the image. As shown in figure 5.1
below, along with an original plate used as an input image during simulation, it also
consists of a Processed Plate Results that is the binary image and the result of the resizing
algorithm. The results of character recognition stored in a file are as shown in the Table
5.2.
27
Figure 5.1 Simulation Results for Case 1
Number
0
1
2
3
4
5
6
Referenced Number
30
15
10
2
31
35
28
Matching Ratio %
95
98
90
90
85
85
87
Table 5.2 Case 1 Simulation Results for Character Recognition
The above results provide us with the following information. Column 1 is the
number field that indicates the location of numbers on the plate starting from LHS. Thus,
number zero indicates the first number/character while number 6 indicates the last
number/character. The maximum number of characters found in a plate are usually the
highest number i.e., six in this case plus one that gives seven numbers. The reference
number field in column2 indicates that the numbers/characters on the plate have been
matched with the nth location of the template stored in the database. Finally, the matching
28
ratio field in the last column shows the matching percentile between the two templates
i.e., the number of vector bits matched. Hence, the characters recognized are 4PKC592.
5.2.2 Case 2: Low Quality Image and Poor Lighting Condition
In this test case, images are captured from the camera under dark lighting and
cloudy conditions. These images captured under poor visibility conditions have low
contrast and brightness elements that generate a low quality image. It is very important to
feed these types of images as an input to the recognition algorithm in order to check the
integrity of the characters being identified. The figure 5.2 consists of an original plate
used as an input image during simulation, processed plate results that is the binary image
and the third image is the result of the resizing algorithm. The results of character
recognition are stored in the file which are as shown in Table 5.3.
Figure 5.2 Simulation Results for Case 2
29
Number
0
1
2
3
4
5
6
Reference Number
31
4
10
17
33
35
26
Matching Ratio %
85
92
89
100
96
84
92
Table 5.3 Case 2 Simulation Results for Character Recognition
The tabulated results above provide us with the following three fields. The
number field indicates the location of numbers/characters on the plate starting from LHS
i.e., number 0 indicates the first number/character while number 6 indicates the last
number/character. The reference number indicates whether the number/character on the
plate has matched with the nth location of the template stored in database. The matching
ratio field in the last column shows the matching percentile between the two templates
i.e., the number of vector bits matched during template matching. Hence, the characters
are 5EKR790.
5.2.3 Case 3: Blurry Image
This is another test case in which due to low shutter speed of the image acquisition
system, the image gets blurred. This type of image results in a loss of fine details
associated with the characters that may affect the recognition results. Figure 5.3 consists
of similar 3 things mentioned in the above two simulation results comprising of original
plate, a binary image and the results of a resizing algorithm. The results of character
recognition were stored in the file, which are as shown after Figure 5.3.
30
Figure 5.3 Simulation Results for Case 3
Number
0
1
2
3
4
5
6
Reference Number
30
13
16
4
33
31
26
Matching Ratio %
92
93
87
92
93
85
95
Table 5.4 Case 3 Simulation Results for Character Recognition
The extent to which the algorithm accurately detects and recognizes the characters is
possible by inclusion of these types of images. In this test case, the characters recognized
are 4NQE750.
5.2.4 Case Analysis
Three cases are analyzed in order to make sure that all the algorithms work
properly and required functionality is achieved. This project concentrates mainly on the
31
recognition part and plate detection is not included in the above simulation. Each of the
above cases discussed, consists of three images and log file results created and saved in a
file during simulation. The first image is an original image; second image is the
processed image while the third image is the result of the resizing algorithm. The
simulation results obtained provide us with the following information. The first member
of the column in the simulation results table i.e., Number gives the matched results for
the corresponding character present in the plate. The Reference part is a look up table
with values for each character of the template (26 characters and 10 numbers) as
mentioned in Table 3.2. This reference field is the confidence factor that tells the user
that, this is the best match achieved from all the 36 characters and matching ratio gives
the match between the two (plate characters and template characters) in terms of
percentage. From the above results it is brought to light that as long as the characters in
the test image are not affected by the environmental conditions, all the characters are
perfectly recognized.
5.3 Implementation Results
5.3.1 Case 1: High Quality Image
Test cases used above for simulation are reconsidered for testing at the hardware
level. Figure 5.4 consists of the following four images displayed on the TV screen. An
original plate that is an input image captured from the camera, processed plate binary
image results, result of the resizing algorithm and last is result of the character
recognition algorithm.
32
Figure 5.4 Implementation Results for Case 1
5.3.2 Case 2: Low Quality Image (Plate Detection + Recognition)
This test case performed on low quality image involves two parts as illustrated
in Figure 5.5. Firstly, it involves the detection of a license plate from the rear end picture
of a car and its display on the TV screen. Secondly, using the recognition algorithm, all
the characters are identified from the detected plate [9] and the matched results are
outputted on the TV screen.
33
Figure 5.5 Implementation Results for Case 2
5.3.3 Case 3: Bright Image (Plate Detection + Recognition)
This test case performed on a bright image also involves two parts as
illustrated in Figure 5.6. Firstly, it involves the detection of a license plate from the rear
end picture of a car and its display on the TV screen. Secondly, using the recognition
algorithm, all the characters are distinguished from the detected plate [9] and the matched
results are outputted on the TV screen.
34
Figure 5.6 Implementation Results for Case 3
5.3.4 Case Analysis
Three cases considered for testing all the algorithms on the DSP kit ensures the
required functionality achieved.
In all the three cases listed above, the first case
illustrates the recognition algorithm results based on a detected license plate. The
remaining two cases depict both license plate detection [9] and character recognition. In
Case 1, the first image is an original image, while the second image is the processed
image, third image is the result of the resizing algorithm and the fourth image is the
obtained result after Template Matching. The last image generated from the template
vector is created for verification purposes only. This feature is not realized when
Performance Analysis is carried out. While for case 2 and 3, the first image is an original
35
image, second image is the detected image [9] while the third image is the result obtained
after Template Matching. All the characters in the third image are perfectly recognized.
However, in one particular scenario of Case 2, the character B revealed as number eight
on the TV screen. Both, character B and number 8 are identical in their shape and a slight
variation on these characters result in the false recognition. Further analysis carried out
on the test picture, confirms that along with low brightness and contrast the plate also
included grain, noise and dust. Hence, during plate detection, processing steps such as
dilation and noise removal [9] affected the character orientation and resulted into false
recognition results.
5.4 Performance Analysis
Based on CCS (Code Compose Studio) profiling tool we see that after the
plate is detected from an image size of 720 × 480 pixels with a processor speed of 600
MHz, it requires approximately 90 ms for recognizing all the characters on the plate. The
overall system performance that includes both plate detection [9] and recognition requires
approximately 300 ms execution time. The table 5.2 summarizes the average
performance profile of various algorithms used for character recognition purposes for 20
input images, considered during test cases. Out of the seven functions used in the
recognition algorithm, functions like Image copy, Defragmentation, Process Image and
Reprocess Image are dependent on the size of the plate. Hence, the size of a plate is an
important factor and must be considered during performance analysis.
36
Function
Image Copy
Defragmentation
Resizing Quad Gen
File Mapping
Reprocess Image
Template Matching
Process Image
Total
Number of
clock cycles
(× 106)
1.8
4.7
10.8
0.3
12.5
4.4
21.6
56.1
Computation time with
a CPU of 600 MHz
( ms)
2.8
7.5
17.28
0.48
20
7
34.4
89.46
Table 5.5 Performance Profile Summary
From the table 5.2, it is evident that Template Matching algorithm takes only 7 ms
to recognize all the seven characters on the plate. This is said to be rationally fast as it
takes only 1 ms to identify each character on the plate. The Process Image and Reprocess
Image functions of an algorithm require maximum computational time. These functions
are optional features used to create the visibility of results on the TV screen and may be
ignored during Performance Analysis. Hence, the overall performance estimated for
image recognition part for the remaining five functions is 40 ms approximately. The
performance data mentioned by Clemens Arth from Graz University of Technology in an
IEEE paper entitled, “Real-Time License Plate Recognition on an Embedded DSPPlatform” - shows that it takes 52.11 ms for both plate detection and recognition from an
image with a frame resolution of 355 × 288 [12]. Based on performance analysis
measurements chart and summing up Image Acquisition, Segmentation and Classification
functions yields execution time of 11 ms approximately to recognize all the characters
once the plate has been detected [12]. However, Clemens, Florian and Horst made their
analysis for a fixed plate size of 90 × 30 and no resizing was taken into consideration.
37
However, the frame resolution in this project is twice the size of the frame mentioned in
their paper and as the size of the detected plate varies from 150 × 50 to 275 × 100, a
rough estimation of 20 ms is set as an achievable target. The following functions namely,
Image_copy, Defragmentation, Resizing_quad_gen, File mapping and Template
Matching are the governing factors that decide the above estimation.
5.5 Optimization Techniques
In order to optimize the above design, it is necessary to analyze the part of the
code that is consuming the maximum amount of time. From Table 5.2, it is obvious that
the best way to optimize the above code is by working on the Resizing_quad_gen
algorithm. There are several steps taken into consideration during our design
implementation in order to have better performance. Some of the design optimization
steps that are taken into account during the design as well as the one that will be used
further are described briefly in the given sections.
5.5.1 Code Optimization
The most common method used for code optimization is to use library routines
wherever possible instead of redesigning the code for the same functionality. To a large
extent, library routines are highly optimized and can improve the performance of the code
drastically. Through profiling, it is observed that the area of code that needs maximum
optimization is Resizing_Quad_gen function. By careful analysis, it is found that a
certain piece of code can be replaced by the power function to generate four 16-bit
vectors. Hence, the power function from the math library routine was used to optimize
the resizing_quad_gen function. Similarly, another technique was used to optimize the
38
‘for’ loop in Template_matching function. Let us see the basic requirement to perform
Template Matching before diving into the optimization technique. In order to do
Template Matching, four 16-bit vectors are created from the detected numbers and these
vectors are compared bitwise with other template vectors in their respective quadrant.
The degree of mismatch is found by the number of 1's present in the result. This can be
achieved in the following ways as shown below.
for (j = 0; j < 4; j ++) // J defines the quadrant
{
a = ((quadrant1[tt][j])) ^ ((quadrant[x][j])); // Two 16-bit vectors comparision
for (k = 0; k < 16; k ++) // tt defines 36 templates, x defines detected Numbers
{a >> k;
if ((a & 0x0001) == 1) {cnt = cnt + 1;} else {cnt = cnt;}
}
The above code takes approximately 2300 iterations (16 × 4 × 36 template) to
find out the number of mismatches in four 16-bit vectors for 36 templates (26 characters
and 10 numbers). This will be multiplied with 7 characters on the plate that will result
into 16,000 iterations. The above code was optimized in the following manner.
for (j = 0; j < 4; j ++)
{
a = ((quadrant1[tt][j])) ^ ((quadrant[x][j]));
result_match = ((a & 0x0008) == 8 ) + ((a & 0x0004) == 4) + ((a & 0x0002) == 2
) + ((a & 0x0001)== 1)+ result_match ;
39
a = a>>4;
result_match = ((a & 0x0008) == 8 ) + ((a & 0x0004) == 4) + ((a & 0x0002) ==
2) + ((a & 0x0001)== 1)+ result_match;
a = a>>4;
result_match = ((a & 0x0008) == 8 ) + ((a & 0x0004) == 4) + ((a & 0x0002) == 2
) + ((a & 0x0001) == 1)+ result_match;
a = a>>4 ;
result_match = ((a & 0x0008) == 8 ) + ((a & 0x0004) == 4) + ((a & 0x0002) == 2
) + ((a & 0x0001) == 1)+ result_match; }
To get the same functionality as with initial 16000 iterations the above code
now requires only 1000 iterations i.e., 16 times faster. Another technique which was used
for code optimization was loop combining. In this technique, when the two loops iterate
for the same amount of time, their bodies can be combined with a condition that variables
in both the loops are not dependent on each other. This technique is utilized in the
Defragmentation Algorithm and it drastically improved the performance by 50%.
5.5.2 Cache Optimization
In order to speed up the execution speed of the CPU, cache plays a very important
role provided it is configured correctly. As mentioned in Chapter 4 above, that there are
two types of caches available on the DSP board namely, L1 cache and L2 cache. In L1
cache, both program and data can be configured separately. Similarly, L2 may be
configured as a mapped SRAM, a cache, or a combination of both. For the previous
performance profiling shown in Table 5.2, L1 is configured with a space of 32 KB for
40
both program and data cache. Since this project is related to the real time applications,
configuring them to the maximum allocation helps in the faster execution. L2 cache is
configured in an “ALL SRAM” mode means a part of it was not configured as cache.
Thus in order to configure L2 partly as cache and partly as RAM, one needs to configure
the Gel file that is available with the video preview code provided by Texas Instrument.
By changing the configuration bits, L2 was configured as 768 KB RAM and 256 KB
cache. This is the maximum size that SRAM can be configured as a cache. The following
table shows the performance profile of the recognition system with and without L2 cache.
Function
Image Copy
Defragmentation
Resizing Quad Gen
File Mapping
Reprocess Image
Template Matching
Process Image
Number of clock
cycles (×106)
without L2 cache
1.132
2.924
10.751
0.307
12.522
4.512
21.687
Number of clock
cycles (×106) with L2
cache
1.118
2.914
10.769
0.303
12.524
4.513
21.678
Table 5.6 Performance Profile Summary After Cache Optimization
From the above Table 5.3, it can be seen clearly that there is hardly any difference
in the performance improvement. This is obvious as L2 cache is more effective when an
external memory is used as an interface for storage and data transfer.
5.5.3 Compiler Optimization
In this step, the output of the compiler is tuned by minimizing or maximizing the
particular attribute of the program viz. code size vs. speed to achieve the required
performance. Code composer studio provides user with several optimizing option that the
41
user can use and tune them according to their requirement. These options are available in
the build option of the project tab menu. There are two optimization option which can be
used to improve the performance viz., opt speed vs. size and opt level. Opt Speed vs Size
option is used to let the compiler know whether the user is more interested in optimizing
the speed or in reducing the code area. As improving the performance was primary goal,
this option was set to −ms0 that favors maximum performance against code size. Opt
Level option sets the level of optimization that needs to be performed on the program
code [8]. There are four Opt level available in code composer studio:
1) O0 – Provides register level optimization.
2) O1 – Addition to register optimization, compiler performs local optimization.
3) O2 – Additional to above optimization, global optimization is performed.
4) O3 – Additional to all above optimization, file level optimization is performed.
From all the above four level of optimization and considering the tradeoff
between memory usage and speed, O1 level was used as compiler optimization for this
project.
5.5.4 Optimization Results and Summary
After applying all these optimization techniques that were explained above, the
Table 5.4 summarizes the performance improvement achieved. After comparing both the
results, it is prominent that there is 50% improvement in the performance.
42
Function
Image Copy
Defragmentation
Resizing Quad
Gen
File Mapping
Reprocess Image
Template
Matching
Process Image
Total
Number of
clock cycles
(× 106)
Number of
clock cycles
(×106)
1.132
2.924
10.751
Computation
time (Before
optimization)
Ms
1.81
4.678
17.20
0.6
1.935
6.114
Computation
time (After
optimization)
ms
0.96
3.096
9.782
0.307
12.522
4.512
0.4912
20.03
7.2
0.308
5.61
1.972
0.492
8.97
3.155
21.687
34.699
86.10
10.51
16.816
43.271
Table 5.7 Performance Profile Summary Before and After Optimization with CPU of
600Mhz
Based on the approximations made in Performance Analysis section 5.4 before,
the achievable target was around 20 ms in which Process Image function and Reprocess
function were ignored. Hence, after ignoring these function’s execution times, the
performance is brought to 15 ms. Finally, it can be concluded that the performance goal
of the declared assumption was successfully achieved.
43
Chapter 6
CONCLUSION
License Plate Character Recognition system was designed, tested and
implemented successfully on Texas EVM DM6437 DSP platform. The new approach of
dividing the template into four 16-bit vectors and use it during Template Matching
proved to be very beneficial as it only requires 3.5 ms approximately for recognizing the
seven characters on the plate (after optimization). Moreover the amount of memory
required to store 36 templates into the database was negligible and thus improving the
performance to maximum extent. The design was verified for several test cases and as far
as Template Matching algorithm works on a predefined standard, the results obtained are
highly reliable. Conditions like poor lighting, noise, blurriness that can cause a character
to vary may result into uncertain results. Recognition of each and every character on the
plate also depends highly on successful defragmentation of every character. Any
variation or false segmentation will amplify the error during the resizing algorithm and
hence will result in false recognition.
The EVM DM6437 DSP platform also provides wireless feature, which can be
used with this application to send the data through internet. This can be used further to
create various law enforcement applications to fight crime and thus to improve public
safety. Several enhancements can be made in this project by using several other features
of the kit.
44
APPENDIX
Simulation and Implementation Code
1. SIMULATION CODE USING OPEN CV LIBRARIES
#include "stdafx.h"
#include <iostream>
#include <cstdlib>
#include <math.h>
#include <stdio.h>
#include <vector>
#include <fstream>
#include "cv.h"
#include "highgui.h"
#define image_row 302
#define image_column 85
#define template_size_x 64
#define template_size_y 128
using namespace std;
using namespace cv;
int main() {
int value;
int black;
int value1 [40];
int value2 [40];
int raw_count=0;
int total_nos = 0;
int width = 0;
int height = 0;
int row_no1 [5];
int row_no2 [5];
int total_row = 0;
int new_row_no1 [5];
int new_row_no2 [5];
int new_total_row = 0;
int max_difference = 0;
45
int row_difference[5];
double pixelvalue;
double pixel_sum;
double pixel_average;
//[image_column];
int template_x_coordinate[template_size_x];
int template_y_coordinate[template_size_y];
float temp_size_x = template_size_x;
float temp_size_y = template_size_y;
int temporary_str;
cout << "************************************************************\n";
cout << " WELCOME TO THE WORLD OF IMAGE PROCESSING FOR CAR
PLATE RECOGNITION \n";
cout << "*************************************************************\n";
// declare a new IplImage pointer
IplImage* myimage;
IplImage* mysample;
CvScalar p ;
p.val[0] = 0;
p.val[1] = 0;
p.val[2] = 0;
p.val[3] = 0;
// load an image
myimage = cvLoadImage("car4_plate2.jpg",0);//change the file name with your own
image
mysample = cvLoadImage ("template.jpg",0);
if(!myimage)
cout << "Could not load image file \n";
else cout << "Sample image successfully loaded\n";
if(!mysample)
cout << "Could not load plain image file \n";
else cout << "Plain image successfully loaded\n";
for (int y=0; y < image_column; y++) // image_column
{
for (int x = 0; x < image_row; x++) // image_row
{
46
pixelvalue =(double)cvGet2D (myimage,y,x).val[0]; // any value above 50
convert it into 255(white) and below it convert it to 0 (black)
//cout << "value of pixel" << y << "\t" << x << "\t" << pixelvalue << endl
;
if (pixelvalue < 150) //50
{
p.val[0] = 0;
p.val[1] = 0;
p.val[2] = 0;
p.val[3] = 0;
cvSet2D (myimage,y,x,p);
}
else
{
p.val[0] = 255;
cvSet2D (myimage,y,x,p);
}
}
}
//----------------------------------------------------------------------------------------------cout << "DEFRAGMENTING THE PLATE HORIZONTALLY" << endl;
for (int y = 0; y <image_column ; y++)
{
pixel_sum = 0;
for (int x=0; x < image_row; x++)
{
pixel_sum = pixel_sum + (double)cvGet2D (myimage,y,x).val[0];
}
pixel_average = image_row - (pixel_sum/255);
if (pixel_average < 4)
{
if ((raw_count > 5)|| (y == image_column)) // false checkin made
{
row_no1[total_row] = y - raw_count;
row_no2[total_row] = y;
//cout << "pixel_value" << pixel_average_horizontal[y] << endl;
raw_count = 0;
total_row = total_row + 1;
}
else
47
{
raw_count = 0 ;
}
}
else
{
raw_count = raw_count + 1;
}
}
for (int x = 0; x < total_row ; x++)
{
cout <<"Number_sequence" << "\t" << x << "\t" << "value1" << "\t" << row_no1
[x]<<"\t" << "value2" << "\t" << row_no2[x] << endl;
row_difference[x] = row_no2[x]-row_no1[x];
if (max_difference < row_difference[x])
{ max_difference = row_difference[x];
}
else{}
}
for (int x = 0; x < total_row ; x++)
{
if ((max_difference - row_difference[x]) < 10)
{
new_row_no1[new_total_row] = row_no1[x];
new_row_no2[new_total_row] = row_no2[x];
new_total_row = new_total_row + 1 ;
}
else {}
}
//------------------------------------------------------------------------------------------------------// till here plate processed, divided horizontally and found the no of rows
//--------------------------------------------------------------------------------------------------------cout << "max difference" << max_difference << endl ;
cout << "DEFRAGMENTING THE PLATE VERTICALLY" << endl;
raw_count = 0;
for (int x = 0; x < new_total_row ; x++)
{
cout <<"Number_sequence" << "\t" << x << "\t" << "value1" << "\t" <<
new_row_no1 [x]<<"\t" << "value2" << "\t" << new_row_no2[x] << endl;
48
for (int xx = 0; xx < image_row; xx++) // image_row check
{
pixel_sum = 0;
for (int y = new_row_no1[x]; y < new_row_no2[x] ; y++) // row
row_no1[x]; y < row_no2[x] no pro
{
pixel_sum = pixel_sum + (double)cvGet2D
(myimage,y,xx).val[0];
}
pixel_average = (new_row_no2[x]- new_row_no1[x]) - (pixel_sum/255);
if (pixel_average < 5)
{
if (raw_count > 10) //&&(raw_count < ((570*2)/7))) //
false checkin
{
value1[total_nos] = xx - raw_count;
value2[total_nos] = xx;
raw_count = 0;
total_nos = total_nos + 1;
}
else
{
raw_count = 0 ;
}
}
else
{
raw_count = raw_count + 1;
}
}
}
cout << "ALGORITHM FOR RESIZING STARTS HERE" << endl;
cout << "total nos" << total_nos << endl;
int kk = 0;
int modified_value;
float divisor_x[40];
float divisor_y [40];
double bas = 2;
unsigned short int storage_vector;
49
unsigned short int quadrant [40][4];
for (int n = 0; n < (total_nos ) ; n ++)
{
divisor_x[n] = (value2[n]-value1[n])/ temp_size_x;
if (value2[n]-value2[n-1] < 0)
{
kk = kk + 1;
divisor_y[n] = (new_row_no2[kk]- new_row_no1[kk]) / temp_size_y;
}
else
{
divisor_y[n] = (new_row_no2[kk]- new_row_no1[kk]) / temp_size_y;
}
for (int q = 0; q < temp_size_x; q++)
{
temporary_str = (divisor_x[n] * q) + value1[n];
template_x_coordinate[q] = temporary_str;
}
for (int q = 0; q < temp_size_y; q++)
{
temporary_str = (divisor_y[n] * q)+ new_row_no1[kk];
template_y_coordinate[q] = temporary_str;
}
for (int y=0; y < temp_size_y; y++) // image_column
{
for (int x = 0; x < temp_size_x; x++) // image_row
{
pixelvalue =(double)cvGet2D
(myimage,template_y_coordinate[y],template_x_coordinate[x]).val[0];
if (pixelvalue == 0 )
{
p.val[0]= 0;
p.val[1]= 0;
p.val[2]= 0;
p.val[3]= 0;
cvSet2D (mysample,y,x,p);
}
else
{
50
p.val[0]= 255;
cvSet2D (mysample,y,x,p);
}
}
}
//-------------------------------------------------------------// start defining here algorithm for four quadrant method
//
for (int m = 0; m < 4; m++)
{
value = 16;
storage_vector = 0;
for (int l = 0; l < 2; l++)
{
for (int k = 0; k < 8; k++)
{
black = 128;
value = value - 1 ;
for (int i = 0; i < 16; i++) // 8
{
for (int j = 0; j < 8; j++)
{
width = j + 8*k;
height = i + 16*l + 32*m; // m= 16 l = 8
pixelvalue = (double)cvGet2D (mysample,height,width).val[0]; // ht,wth
if (pixelvalue == 0)
{
black = black + 1;
}
else
{
black = black - 1;
}
}
}
if (black > 60) modified_value = 0; else modified_value = 1; // 0 - black; 1 - white
//use power function and assign the value
storage_vector = storage_vector + (pow (bas,value))* modified_value;
}
}
quadrant [n][m] = storage_vector;
51
}
}
// Algorithm for File Mapping
// code to Generate output vectors from the Template
//fstream file_op("file_quad1.txt",ios::out);
//for (int i = 0; i < total_nos; i ++)
//{
//
for (int j = 0; j < 4; j ++)
//
{
//
file_op << quadrant [i][j] << endl;
//
}
//}
//file_op.close();
char str [40];
unsigned short int quadrant1 [35][4];
fstream file_in("file1.txt",ios::in);
for (int i = 0; i < 36; i ++)
{
for (int j = 0; j < 4; j ++)
{
file_in.getline(str,40);
quadrant1[i][j] = atoi (str);
}
}
file_in.close();
// Algorithm for Template Matching
unsigned short int result_match ;
unsigned short int a = 0;
int tt = 0;
unsigned short int match_percentage = 0 ;
unsigned short int match_percentage1 = 0 ;
unsigned short int match_percentage2= 0 ;
unsigned short int match_percentage3 = 0 ;
unsigned short int match_percentage4 = 0 ;
unsigned short int highest_percentage = 0 ;
unsigned short int mapping_quadrant[36];
unsigned short int mapping_percentile[36];
52
for (int x = 0 ; x < total_nos; x++)
{
tt=0;
highest_percentage = 0;
while (tt < 36)
{
a = 0;
result_match = 0 ;
match_percentage = 0 ;
for (int j = 0; j < 4; j ++)
{
a = ((quadrant1[tt][j])) ^ ((quadrant[x][j]));
cout << a << endl ;
result_match = ((a & 0x0008) == 8 ) + ((a & 0x0004) == 4) + ((a &
0x0002) == 2 ) + ((a & 0x0001)== 1)+ result_match ;
a = a>>4;
result_match = ((a & 0x0008) == 8 ) + ((a & 0x0004) == 4) + ((a &
0x0002) == 2 ) + ((a & 0x0001)== 1)+ result_match;
a = a>>4;
result_match = ((a & 0x0008) == 8 ) + ((a & 0x0004) == 4) + ((a &
0x0002) == 2 ) + ((a & 0x0001)== 1)+ result_match;
a = a>>4 ;
result_match = ((a & 0x0008) == 8 ) + ((a & 0x0004) == 4) + ((a &
0x0002) == 2 ) + ((a & 0x0001)== 1)+ result_match ;
}
match_percentage = ((64 - result_match)*100)/64 ;
if (highest_percentage < match_percentage)
{
highest_percentage = match_percentage;
mapping_quadrant[x] = tt;
mapping_percentile[x] = highest_percentage;
}
else {
}
tt= tt + 1;
}
if (mapping_percentile[x] < 75 )
{
tt=0;
highest_percentage = 0;
53
while (tt < 36)
{
a = 0;
result_match = 0 ;
match_percentage = 0 ;
for (int j = 0; j < 4; j ++)
{
a = ((quadrant1[tt][j])) ^ ((quadrant[x][j]));
cout << a << endl ;
result_match = ((a & 0x0008) == 8 ) + ((a & 0x0004) == 4) + ((a &
0x0002) == 2 ) + ((a & 0x0001)== 1) ;
match_percentage1 = ((16 - result_match)*100)/16;
result_match = 0;
a = a>>4;
result_match = ((a & 0x0008) == 8 ) + ((a & 0x0004) == 4) + ((a &
0x0002) == 2 ) + ((a & 0x0001)== 1);
match_percentage2 = ((16 - result_match)*100)/16;
result_match = 0;
a = a>>4;
result_match = ((a & 0x0008) == 8 ) + ((a & 0x0004) == 4) + ((a &
0x0002) == 2 ) + ((a & 0x0001)== 1);
match_percentage3 = ((16 - result_match)*100)/16 ;
result_match = 0;
a = a>>4 ;
result_match = ((a & 0x0008) == 8 ) + ((a & 0x0004) == 4) + ((a &
0x0002) == 2 ) + ((a & 0x0001)== 1) ;
match_percentage4 = ((16 - result_match)*100)/16 ;
}
match_percentage = (match_percentage1 + match_percentage2 +
match_percentage3 + match_percentage4)/4;
if (highest_percentage < match_percentage)
{
highest_percentage = match_percentage;
mapping_quadrant[x] = tt;
mapping_percentile[x] = highest_percentage;
}
else {
}
tt = tt + 1;
}
}
}
54
for (int i = 0; i < total_nos; i ++)
{
cout << "mapping_quadrant" << "\t" << i << "\t" << mapping_quadrant[i] << "\t" <<
mapping_percentile[i]<< endl;
}
cvNamedWindow("Smile", 1);
cvMoveWindow("Smile", 10, 10);
cvShowImage("Smile", myimage);
//wait for key to close the window
cvWaitKey(0);
cvDestroyWindow( "Smile" );
cvReleaseImage( &myimage );
cvReleaseImage( &mysample );
return 0;
}
55
2. HARDWARE IMPLEMENTATION CODE
/*
* The code below consist of three parts
* 1) Video Preview Code provided by Texas Instrument during the purchase of EVMDM
*
6437 Evaluation kit. Only modified part of this code is shown here.
* 2) Plate Detection - Only Global Variables for plate detection is shown here as they
* were used in the plate recognition. Function for plate detection are not shown below
* 3) Plate Recognition - consist of seven functions and are shown in this code
*/
/* runtime include files */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdarg.h>
#include <math.h>
/* BIOS include files */
#include <std.h>
#include <gio.h>
#include <tsk.h>
#include <trc.h>
/* PSP include files */
#include <psp_i2c.h>
#include <psp_vpfe.h>
#include <psp_vpbe.h>
#include <fvid.h>
#include <psp_tvp5146_extVidDecoder.h>
#include <c6x.h>
/* CSL include files */
#include <soc.h>
#include <cslr_sysctl.h>
/* BSL include files */
#include <evmdm6437.h>
#include <evmdm6437_dip.h>
/* Video Params Defaults */
#include <vid_params_default.h>
#include <csl.h>
56
//#include <csl_cache.h>
#include <bcache.h>
// IMAGE PROCESSING HEADER FILES
/* This example supports either PAL or NTSC depending on position of JP1 */
#define STANDARD_PAL 0
#define STANDARD_NTSC 1
#define FRAME_BUFF_CNT 6
#define image_row1 720
#define image_column1 480
#define template_size_x 64
#define template_size_y 128
static int read_JP1(void);
static CSL_SysctlRegsOvly sysModuleRegs = (CSL_SysctlRegsOvly
)CSL_SYS_0_REGS;
//*******************************
// Pramod global variables
//*******************************
unsigned char my_image[480][720];
int value1 [40];
int value2 [40];
int total_nos = 0;
int new_row_no1 [5];
int new_row_no2 [5];
int new_total_row = 0;
float divisor_x[40];
float divisor_y [40];
unsigned int check[8][8];
unsigned int template_gen[8][8]; // 16 8
char str [40];
FILE * myfile;
int template_x_coordinate [template_size_x];
int template_y_coordinate [template_size_y];
float temp_size_x = template_size_x;
float temp_size_y = template_size_y;
float div_x;
57
float div_y;
int pixel_sum;
int pixel_average; //[480];
int row_no1 [5];
int row_no2 [5];
int total_row = 0 ;
int max_difference = 0;
int row_difference[5];
int raw_count = 0;
unsigned short int storage_vector;
unsigned short int quadrant [40][4];
unsigned short int quadrant1 [35][4];
int my_sample[128][64];
//*******************************************************
// USER DEFINED FUNCTIONS
//*******************************************************
...
...
... STATE USER DEFINED FUNCTION FOR DETECTION HERE
...
...
void image_copy (); // Pass image coordinate, size -- height and width of the detected //
image to this function
void process_image(void * currentFrame);
void defragmentation (int image_column,int image_row);
void resizing_quad_gen ();
void template_matching (int temp_size_y, int temp_size_x);
void file_mapping();
void reprocess_image(int image_column, int image_row);
//*******************************************************
// VARIABLE ARRAYS
//*******************************************************
// Global variables used by detection algorithm
unsigned char I[480][720];
unsigned char I_temp[480][720];
int row_width, col_width;
int start, stop;
//*******************************************************
58
/*
* ======== main ========
*/
void main() {
printf("Video Preview Application\n");
fflush(stdout);
/* Initialize BSL library to read jumper switches: */
EVMDM6437_DIP_init();
sysModuleRegs -> PINMUX0 &= (0x005482A3u);
sysModuleRegs -> PINMUX0 |= (0x005482A3u);
sysModuleRegs -> PINMUX1 &= (0xFFFFFFFEu);
sysModuleRegs -> VPSSCLKCTL = (0x18u);
return;
}
/*
* ======== video_preview ========
*/
void video_preview(void) {
FVID_Frame *frameBuffTable[FRAME_BUFF_CNT];
FVID_Frame *frameBuffPtr;
GIO_Handle hGioVpfeCcdc;
GIO_Handle hGioVpbeVid0;
GIO_Handle hGioVpbeVenc;
int status = 0;
int result;
int i;
int standard;
int width;
int height;
int flag = 1;
...
...
...
...
...
...
// Video Preview Code provided by Texas Instrument with their evaluation
board EVMDM647
... // goes here
59
/* loop forever performing video capture and display */
while ( flag && status == 0 ) {
// ADDED FLAG TO RUN THIS LOOP ONLY
ONE TIME
/* grab a fresh video input frame */
FVID_exchange(hGioVpfeCcdc, &frameBuffPtr);
//*************************
// DETECTION PART
//*********************************
...........
..........
.........
.// FUNCTIONS FOR DETECTION GOES HERE
.........
........
//*********************************
// RECOGNITION PART
//*********************************
image_copy ();
defragmentation (row_width,col_width);
resizing_quad_gen ();
file_mapping();
reprocess_image(image_column1,image_row1);
template_matching (template_size_y,template_size_x);
process_image (frameBuffPtr->frame.frameBufferPtr);
//*******************************************************************
BCACHE_wbInv((void*)(frameBuffPtr->frame.frameBufferPtr), 480*720*2, 1);
/* display the video frame */
FVID_exchange(hGioVpbeVid0, &frameBuffPtr);
flag = 0;
}
}
/*
* ======== read_JP1 ========
* Read the PAL/NTSC jumper.
*
60
* Retry, as I2C sometimes fails:
*/
static int read_JP1(void)
{
int jp1 = -1;
while (jp1 == -1) {
jp1 = EVMDM6437_DIP_get(JP1_JUMPER);
TSK_sleep(1);
}
return(jp1);
}
//******************************************************
// FUNCTIONS FOR RECOGNITION ALGORITHM
//*****************************************************
//*****************************************************
// PROCESS IMAGE TO DIGITAL FORMAT
//*****************************************************
void image_copy ()
{
int x,y;
for (y=0; y < row_width; y++) // image_column
{
for ( x = 0; x < col_width; x++) // image_row
{
if(my_image[y][x] < 150)
{
my_image[y][x] = 0;
}
// THRESHOLD
else
{
my_image[y][x]= 255;
}
}
}
}
61
//******************************************************
// FUNCTION TO DISPLAY RESULTS ON THE TV
//******************************************************
void process_image (void * currentFrame)
{
int x,y,m; // change y
m = 0;
for ( y=0; y < 480; y++) // image_column
{
x=0;
for ( m = 0; m < (720 * 2); m=m+2) // image_row
{
* (((unsigned char * )currentFrame)+ (y * 720 * 2 ) + m) = 0x80;
* (((unsigned char * )currentFrame)+ (y * 720 * 2) + m+1) = my_image[y][x];
x = x + 1;
}
}
}
//*****************************************************
// FUNCTION TO FIND CHARACTERS ON THE PLATE
//*****************************************************
void defragmentation (int image_column,int image_row)
{
int y,x,xx,e;
for ( y = 0; y <image_column ; y++)
{
pixel_sum = 0;
for ( x=0; x < image_row; x++)
{
pixel_sum = pixel_sum + my_image[y][x];
}
pixel_average = (image_row - (pixel_sum/255));
if ((pixel_average < 1)||(y == (image_column -1))) // check a value
62
{
if (raw_count > 5) // false checkin made
{
row_no1[total_row] = y - raw_count;
row_no2[total_row] = y;
raw_count = 0;
total_row = total_row + 1;
}
else
{
raw_count = 0 ;
}
}
else
{
raw_count = raw_count + 1;
}
}
for ( e = 0; e < total_row ; e++)
{
row_difference[e] = row_no2[e]-row_no1[e];
if (max_difference < row_difference[e])
{
max_difference = row_difference[e];
}
else
{
}
}
for ( x = 0; x < total_row ; x++)
{
if ((max_difference - row_difference[x]) < 20)
{
new_row_no1[ new_total_row] = row_no1[x];
new_row_no2[ new_total_row] = row_no2[x];
new_total_row = new_total_row + 1;
}
else {}
}
63
//-------------------------------------------------------------------------------------------------// Till here plate processed, divided horizontally and found the no of rows
//------------------------------------------------------------------------------------------------raw_count = 0 ;
for ( x = 0; x < ( new_total_row) ; x++)
{
for ( xx = 0; xx < image_row; xx++) // image_row check
{
pixel_sum = 0;
for ( y = new_row_no1[x]; y < new_row_no2[x] ; y++) //
{
pixel_sum = pixel_sum + my_image[y][xx]; // troubleshoot if not getting
}
pixel_average = (new_row_no2[x]-new_row_no1[x])- (pixel_sum/255);
if (pixel_average < 5)
{pixel_average = 0;} else {}
if ((pixel_average == 0 )||(xx == (image_row -1)))
{
if (raw_count > 20) //&&(raw_count < ((570*2)/7))) // false checking
{
value1[total_nos] = xx - raw_count;
value2[total_nos] = xx;
raw_count = 0;
total_nos = total_nos + 1;
}
else
{
raw_count = 0 ;
}
}
else
{
raw_count = raw_count + 1;
}
}
}
}
//*******************************************************************
64
// RESIZING AND FOUR QUADRANT ALGORITHM
//******************************************************************
void resizing_quad_gen ()
{
int n,pixel_value,it,j,k,l,m,x,y,q,black,height1,width1,modified_value,value3;
double bas = 2;
int kk = 0;
int temporary_str_x;
int temporary_str_y;
for ( n = 0; n < (total_nos) ; n ++)
{
divisor_x[n] = (value2[n]-value1[n])/ temp_size_x;
if (value2[n]-value2[n-1] < 0)
{
kk = kk + 1;
divisor_y[n] = (new_row_no2[kk]- new_row_no1[kk]) / temp_size_y;
}
else
{
divisor_y[n] = (new_row_no2[kk]- new_row_no1[kk]) / temp_size_y;
}
for ( q = 0; q < temp_size_x; q++)
{
temporary_str_x = (divisor_x[n] * q) + value1[n];
template_x_coordinate[q] = temporary_str_x;
}
for ( q = 0; q < temp_size_y; q++)
{
temporary_str_y = (divisor_y[n] * q)+ new_row_no1[kk];
template_y_coordinate[q] = temporary_str_y;
}
for ( y=0; y < temp_size_y; y++) // image_column flaw---{
for ( x = 0; x < temp_size_x; x++) // image_row
{
pixel_value = my_image[template_y_coordinate[y]][template_x_coordinate[x]];
65
// any value above 50 convert it into 255(white) and below it convert it to 0 (black)
if (pixel_value == 0 )
{
my_sample[y][x] = 0; // define my_sample
}
else
{
my_sample[y][x] = 255;
}
}
}
//----------------------------------------// Algorithm for four quadrant method
//------------------------------------------------for ( m = 0; m < 4; m++)
{
value3 = 16;
storage_vector = 0;
for ( l = 0; l < 2; l++)
{
for ( k = 0; k < 8; k++)
{
black = 128;
value3 = value3 - 1 ;
for ( it = 0; it < 16; it++) // 8
{
for ( j = 0; j < 8; j++)
{
width1 = j + 8*k;
height1 = it + 16*l + 32*m; // m= 16 l = 8
pixel_value = my_sample[height1][width1]; // ht,wth
if (pixel_value == 0)
{
black = black + 1;
}
else
{
black = black - 1;
}
66
}
}
if (black > 60){ modified_value = 0;} else {modified_value = 1;} // 0 black; 1 - white
//use power function and assign the value
storage_vector = storage_vector + (pow(bas,value3))* modified_value;
}
}
quadrant [n][m] = storage_vector;
}
}
}
//*******************************************
// FUNCTION FOR FILE MAPPING
//*******************************************
void file_mapping()
{
char str [40];
int i,j;
myfile = fopen ("file1.txt","r");
for ( i = 0; i < 36; i ++)
{
for ( j = 0; j < 4; j ++)
{
fscanf (myfile,"%s", & str);
quadrant1[i][j] = atoi (str);
}
}
fclose (myfile);
}
//********************************************************
// FUNCTION TO CLEAR IMAGE ON THE TV
//********************************************************
void reprocess_image(int image_column, int image_row)
{
int y,m;
for ( y=0; y < image_column; y++) // image_column
{
67
for ( m = 0; m < image_row; m++) // image_row
{
my_image[y][m] = 255;
}
}
}
//*************************************************
// TEMPLATE MATCHING ALGORITHM
//************************************************
void template_matching (int temp_size_y,int temp_size_x)
{
int x,y,j,i,rr,l,k,q,bit_mapp,pixel_value;
int temporary_str_x;
int temporary_str_y;
unsigned short int result_match ;
unsigned short int a = 0;
unsigned short int match_percentage = 0 ;
unsigned short int match_percentage1 = 0 ;
unsigned short int match_percentage2= 0 ;
unsigned short int match_percentage3 = 0 ;
unsigned short int match_percentage4 = 0 ;
unsigned short int highest_percentage = 0 ;
unsigned short int mapping_quadrant[36];
unsigned short int mapping_percentile[36];
int tt = 0;
int displace;
for ( x = 0 ; x < total_nos; x++)
{
tt=0;
highest_percentage = 0;
while (tt < 36)
{
a = 0;
result_match = 0 ;
match_percentage = 0 ;
for ( j = 0; j < 4; j ++)
{
a = ((quadrant1[tt][j])) ^ ((quadrant[x][j]));
68
result_match = ((a & 0x0008) == 8 ) + ((a & 0x0004) == 4) + ((a & 0x0002) ==
2 ) + ((a & 0x0001)== 1)+ result_match ;
a = a>>4;
result_match = ((a & 0x0008) == 8 ) + ((a & 0x0004) == 4) + ((a & 0x0002) ==
2 ) + ((a & 0x0001)== 1)+ result_match;
a = a>>4;
result_match = ((a & 0x0008) == 8 ) + ((a & 0x0004) == 4) + ((a & 0x0002) ==
2 ) + ((a & 0x0001)== 1)+ result_match;
a = a>>4 ;
result_match = ((a & 0x0008) == 8 ) + ((a & 0x0004) == 4) + ((a & 0x0002) ==
2 ) + ((a & 0x0001)== 1)+ result_match ;
}
match_percentage = ((64 - result_match)*100)/64 ;
if (highest_percentage < match_percentage)
{
highest_percentage = match_percentage;
mapping_quadrant[x] = tt;
mapping_percentile[x] = highest_percentage;
}
else {
}
tt= tt + 1;
}
}
for ( i = 0; i < total_nos; i ++)
{
if (mapping_percentile[i] < 75 )
{
tt=0;
highest_percentage = 0;
while (tt < 36)
{
a = 0;
result_match = 0 ;
match_percentage = 0 ;
for ( j = 0; j < 4; j ++)
{
a = ((quadrant1[tt][j])) ^ ((quadrant[i][j]));
//cout << a << endl ;
result_match = ((a & 0x0008) == 8 ) + ((a & 0x0004) == 4) + ((a & 0x0002) == 2 ) +
69
((a & 0x0001)== 1) ;
match_percentage1 = ((16 - result_match)*100)/16;
result_match = 0;
a = a>>4;
result_match = ((a & 0x0008) == 8 ) + ((a & 0x0004) == 4) + ((a & 0x0002) == 2 ) +
((a & 0x0001)== 1);
match_percentage2 = ((16 - result_match)*100)/16;
result_match = 0;
a = a>>4;
result_match = ((a & 0x0008) == 8 ) + ((a & 0x0004) == 4) + ((a & 0x0002) == 2 ) +
((a & 0x0001)== 1);
match_percentage3 = ((16 - result_match)*100)/16 ;
result_match = 0;
a = a>>4 ;
result_match = ((a & 0x0008) == 8 ) + ((a & 0x0004) == 4) + ((a & 0x0002) == 2 ) +
((a & 0x0001)== 1) ;
match_percentage4 = ((16 - result_match)*100)/16 ;
}
match_percentage = (match_percentage1 + match_percentage2 + match_percentage3 +
match_percentage4)/4;
if (highest_percentage < match_percentage)
{
highest_percentage = match_percentage;
mapping_quadrant[i] = tt;
mapping_percentile[i] = highest_percentage;
}
else {
}
tt = tt + 1;
}
}
}
for ( i = 0; i < ( total_nos ); i ++)
{
rr = mapping_quadrant[i];
for ( l = 0; l < 4; l ++) // i 16
{
a = quadrant1[rr][l];
for ( j = 0; j < 2; j ++)
{
for ( k = 0; k < 8; k ++)
70
{
bit_mapp = (a & 0x8000);
if (bit_mapp == 0)
{
template_gen[j+2*l][k] = 0;
}
else
{
template_gen[j+2*l][k] = 255;
}
a = a<<1;
}
}
}
div_y = 0.0625; // value obtained by dividing 8 by 128 and 8 by 64
div_x = 0.125;
displace = 50;
for ( q = 0; q < temp_size_x; q++)
{
temporary_str_x = (div_x * q) ;
template_x_coordinate[q] = temporary_str_x;
}
for ( q = 0; q < temp_size_y; q++)
{
temporary_str_y = (div_y * q);
template_y_coordinate[q] = temporary_str_y;
}
for ( y=0; y < temp_size_y; y++) // image_column
{
for ( x = 0; x < temp_size_x; x++) // image_row
{
pixel_value =
template_gen[template_y_coordinate[y]][template_x_coordinate[x]]; // any value above
50 convert it into 255(white) and below it convert it to 0 (black)
//printf ("pixel_value %d " , pixel_value);
if (pixel_value == 0 )
{
71
my_image[y+100][x + 70*i + displace ] = 0; // define my_sample
}
else
{
my_image[y+100][x + 70*i + displace] = 255;
}
}
}
}
}
72
REFERENCES
[1] Federal Signal Corporation, “Automatic License Plate Recognition - Investment
Justification and Purchasing Guide”, pp 1-7, August 2008.
[2] Xilinx Inc., “The Xilinx LogiCORE™ IP RGB to YCrCb Color-Space Converter”, pp
1-5, July 2010.
[3] CA Department of Motor Vehicles License
http://www.dmv.ca.gov/pubs/plates/platestitlepage.htm
Plate
Introduction.
[4] Gary Bradski and Adrian Kachler, “Learning OpenCV”, O’Reilly Media Inc, First
Edition, September 2008.
[5] Intel Corp., “Open Source Computer Vision Library”, Reference Manual, December
2000.
[6] Texas Instrument Inc., "TMS 320DM 6437 Digital Media Processor", Texas, pp 1-5,
211-234, June 2008.
[7] Texas Instrument Inc., "TMS320DM643x DMP Peripherals Overview Reference
Guide", pp 15-17,June 2007.
[8] Texas Instrument Inc., "TMS320C6000 Programmers Guide”, Texas, pp 37-84,March
2000.
[9] Naikur Gohil, “Car License Plate Detection”, Masters Project Report, California State
University, Sacramento, Fall 2010.
[10] Texas Instrument Inc., “TMS320C64X+ DSP Cache”, User Guide, pp 14-26,
February 2009.
[11] ITU Recommendation BT.601-5, International Telecommunication Union, 1995.
[12] Clemens Arth, Florian and Horst, “Real-Time License Plate Recognition on an
Embedded DSP-Platform”, Proceedings of IEEE conference on Computer Vision and
Pattern Recognition, pp 1-8, June 2007.
Download