-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathCar_plate_identification_live_script.m
394 lines (312 loc) · 11 KB
/
Car_plate_identification_live_script.m
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
close all;clear; clc;
letter_templates=imageDatastore("Template_letters");
text_plate_letters="";
car_plate="Car_plate_numbers\plate6.jpg";
plate=blackandwhite(car_plate);
plate=oddandeven(plate);
original_plate=plate;
edges=icanny(plate);
figure, montage({plate, edges}) ;
grid on , axis on, title('Car plate, car plate with edges') ;
%% Find Hough Horizontal edges
h = Hough(edges)
figure, h.show(), grid on ,
lines = h.lines()
idisp(plate) , grid on, title(strcat("Detected ",string(numel(lines))," lines")) ;
h.plot('g')
% nonlocal maxima supression
h1 = Hough(edges, 'suppress', 4)
figure, h.show(), grid on ,
lines = h1.lines()
figure, idisp(plate);
h1.plot('g')
gradient=lines.rho.*tan(deg2rad(lines.theta));
low_slopes=find((-0.1<=gradient) & (gradient<=0.1));
rho_lines=zeros(numel(low_slopes),2);
for n=1:numel(low_slopes)
rho_lines(n,1)=lines(low_slopes(n)).rho;
rho_lines(n,2)=low_slopes(n);
end
figure, idisp(plate) ; grid on,
rho_lines=sortrows(rho_lines,1);
disp("Calculating differences")
for n = 1:height(rho_lines)
v_point1=rho_lines(n,1);
v_point2=rho_lines(n+1,1);
difference(n)=v_point2-v_point1;
disp(difference(n))
if n==(height(rho_lines)-1)
break
end
end
Nj=find(difference==max(difference));
lines(rho_lines(Nj,2)).plot('r.');
lines(rho_lines(Nj+1,2)).plot('r.');
horizontalpoint1=lines(rho_lines(Nj,2)).rho;
horizontalpoint2=lines(rho_lines(Nj+1,2)).rho;
%cropped_image=plate(lines(rho_lines(Nj,2)).rho:lines(rho_lines(Nj+1,2)).rho,:,:);
cropped_image=plate(horizontalpoint1:horizontalpoint2,:,:);
figure
idisp(cropped_image);
title("Cropped version");
plate=morphology(cropped_image,round(lines(rho_lines(Nj+1,2)).rho-lines(rho_lines(Nj,2)).rho));
%plate=morphology(cropped_image,300);
plate=medfilt2(plate, [4 4]);
% figure
% idisp(plate);
% title("After median filtering");
% for n=1:Nj
% lines(Nj).plot('r.');
% end
%% Vertical Hough edge transform
vertical_edges = edge(plate, 'Sobel', 'vertical');
% nonlocal maxima supression
[H,T,R]=hough(vertical_edges);
P = houghpeaks(H,5,'threshold',ceil(0.6*max(H(:))));
lines = houghlines(vertical_edges,T,R,P,'FillGap',5);
for n=1:numel(lines)
plate_vertical=insertShape(double(plate),'line',[lines(n).point1(1),lines(n).point1(2),lines(n).point2(1),lines(n).point2(2)],LineWidth=5);
end
figure
idisp(plate_vertical);
title("Vertical edges")
max_difference=0;
index=0;
for n=1:numel(lines)
difference=abs(lines(1).point1(1)-lines(n).point1(1));
if difference>max_difference
max_difference=difference;
index=n;
end
end
verticalpoint1=lines(1).point1(1);
verticalpoint2=lines(index).point1(1);
plate=plate(:,min(verticalpoint1,verticalpoint2):max(verticalpoint1,verticalpoint2),:);
figure
idisp(plate);
title("Cropped vertical version");
%% Creating final image for blob analysis
plate=original_plate(horizontalpoint1:horizontalpoint2,min(verticalpoint1,verticalpoint2):max(verticalpoint1,verticalpoint2),:);
plate=morphology(plate,round(abs(horizontalpoint1-horizontalpoint2)));
plate=medfilt2(plate, [4 4]);
figure
idisp(plate);
title("Final image before blob processing");
%% Finding blobs in image, identifying letters, reordering them,
figure
idisp(plate)
title("Blob imaging")
letters=iblobs(plate);
for n=1:numel(letters)
if letters(n).touch==0
letters(n).plot_box('y')
letter_heights(n)=(letters(n).vmax-letters(n).vmin);
end
end
% Choose the number of clusters (K)
K = 4; % You need to decide the number of clusters
% Perform k-means clustering
[idx, centers] = kmeans(letter_heights, K);
% Initialize arrays to store cluster heights and cluster sizes
cluster_heights = zeros(1, K);
cluster_sizes = zeros(1, K);
max_cluster_size = 0; % Initialize maximum cluster size
max_cluster_height = 0; % Initialize maximum cluster height
max_valid_cluster_size = 12;
% Calculate the mean height for each cluster and count cluster sizes
for k = 1:K
cluster_indices = (idx == k);
cluster_heights(k) = mean(letter_heights(cluster_indices));
cluster_sizes(k) = sum(cluster_indices);
if cluster_sizes(k) < max_valid_cluster_size
if cluster_sizes(k) > max_cluster_size
max_cluster_size = cluster_sizes(k);
max_cluster_height = cluster_heights(k);
end
end
end
% Display the estimated letter heights and cluster sizes
fprintf('Estimated Letter Heights and Cluster Sizes:\n');
for k = 1:K
fprintf('Cluster %d: Height=%.2f, Size=%d\n', k, cluster_heights(k), cluster_sizes(k));
end
%letter_height=cluster_heights(find(cluster_heights==max(cluster_heights(find(cluster_sizes<9)))));
letter_height=max(cluster_heights(find(cluster_sizes<9)));
%letter_height=300;
figure
idisp(plate)
plate_letters=RegionFeature.empty(0);
position=1;
for n=1:numel(letter_heights)
letter_centre=[letters(n).uc, letters(n).vc];
if abs(((letter_heights(n)-letter_height)/letter_height)*100) <=50.0
plate_letters(position)=letters(n);
letters(n).plot_box('g');
position=position+1;
end
end
plate_letters = sortPlateLettersByValue(plate_letters);
for n=1:numel(plate_letters)
possible_letter=plate_letters(n);
if n==1
plate_letters(n)=possible_letter;
end
if n~=1
percentage_difference= abs((possible_letter.uc-plate_letters(n-1).uc)/plate_letters(numel(plate_letters)).uc)*100;
if percentage_difference<=7
disp("Same letter")
if possible_letter.area > plate_letters(n-1).area
plate_letters(n-1)=[];
end
if possible_letter.area < plate_letters(n-1).area
plate_letters(n)=[];
end
end
end
if n >= numel(plate_letters)
break
end
end
nonEmptyIndices = ~arrayfun(@isempty, plate_letters);
% Resize the array to remove empty elements
plate_letters = plate_letters(nonEmptyIndices);
plate_letter_collection=cell(length(plate_letters), 1);
figure
title("Letter")
for n=1:numel(plate_letters)
plate_letter_collection{n}=plate(plate_letters(n).vmin:plate_letters(n).vmax,plate_letters(n).umin:plate_letters(n).umax,:);
idisp(plate_letter_collection{n});
pause(1);
end
%% Iterating over every letter in the blob image matrix to find template letter with highest match
matches=findBestMatches(plate_letter_collection, letter_templates);
text="";
for n=1:numel(matches)
text=strcat(text,stringsplitter(matches{n}));
end
disp(text);
%% Function Definitions
function [image]=blackandwhite(input)
plate=iread(input,'double');
gs = im2gray(plate);
gs = imadjust(gs);
H = fspecial("average",2);
gs = imfilter(gs,H,"replicate");
image=gs;
figure
idisp(plate);
title('before');
end
function [image]=morphology(input,height)
gs=input;
SEdisk = strel("rectangle",[height width(input)]);
%Ibg = imopen(gs,SEdisk);
Ibg = imclose(gs,SEdisk);
gsSub = Ibg - gs;
gfilter=kgauss(2);
gsSub=iconv(gfilter,gsSub);
BW = ~imbinarize(gsSub);
BW=medfilt2(BW,[10,10]);
image=BW;
figure
idisp(image);
title('After morphological operation');
end
function [image]=blackandwhiteletter(input)
plate=iread(input,'double');
gs = im2gray(plate);
gs = imadjust(gs);
H = fspecial("average",2);
gs = imfilter(gs,H,"replicate");
gs=imbinarize(gs);
image=gs;
figure
idisp(plate);
title('before');
end
function [plate_letters] = sortPlateLettersByValue(plate_letters)
% Extract the values from the objects into a numerical array
letter_positions = [plate_letters.uc];
% Sort the values in ascending order and obtain the sorted indices
[sortedValues, sortedIndices] = sort(letter_positions);
% Rearrange the objects based on the sorted indices
plate_letters = plate_letters(sortedIndices);
end
function [your_matrix]=oddandeven(image)
[rows, cols] = size(image);
% Check if either dimension is even
if mod(rows, 2) == 0 || mod(cols, 2) == 0
% If either dimension is even, make it odd
if mod(rows, 2) == 0
rows = rows + 1; % Increase the number of rows by 1
end
if mod(cols,2) == 0
cols = cols + 1; % Increase the number of columns by 1
end
% Create a new matrix with the odd dimensions
new_matrix = ones(rows, cols);
% Copy the data from the old matrix to the new one
new_matrix(1:size(image, 1), 1:size(image, 2)) = image;
% Replace the old matrix in the workspace with the new one
your_matrix = new_matrix;
else
your_matrix=image;
end
end
function weightedAvg = weightedAverage(inputArray)
% Initialize variables to store sum and count for each unique element
uniqueElements = unique(inputArray);
sumByElement = zeros(size(uniqueElements));
countByElement = zeros(size(uniqueElements));
% Calculate sum and count for each unique element
for i = 1:length(uniqueElements)
element = uniqueElements(i);
elementIndices = (inputArray == element);
sumByElement(i) = sum(elementIndices .* inputArray);
countByElement(i) = sum(elementIndices);
end
% Calculate the weighted average
weightedAvg = sum(sumByElement .* countByElement) / sum(countByElement);
end
function bestMatches = findBestMatches(blobImages, templateDatabase)
% Initialize a cell array to store the best match file names
bestMatches = cell(size(blobImages));
% Iterate through each blob letter image
for i = 1:length(blobImages)
% Get the current blob letter image
blobImage = double(blobImages{i});
% Initialize variables to keep track of the best match
bestMatchScore = inf; % Initialize with a high value
bestMatchIndex = 0; % Index of the best match template
% Iterate through each template image in the database
for j = 1:length(templateDatabase.Files)
% Get the current template image
templateImage = double(im2gray(imread(templateDatabase.Files{j})));
% Resize the template image to match the size of the blob image
templateImage = imresize(templateImage, size(blobImage));
% Calculate a similarity score between the blob and template images
% You can use a suitable similarity metric (e.g., mean squared error, correlation)
similarityScore = calculateSimilarity(blobImage, templateImage);
% Update the best match if the current score is better
if similarityScore < bestMatchScore
bestMatchScore = similarityScore;
bestMatchIndex = j;
end
end
% Store the file name of the best match in the result array
bestMatches{i} = templateDatabase.Files{bestMatchIndex};
end
end
function similarityScore = calculateSimilarity(image1, image2)
% errorImage = image1 - image2;
% squaredError = errorImage.^2;
% meanSquaredError = mean(squaredError(:));
% similarityScore = -meanSquaredError; % Negative for lower error values being better
similarityScore=normxcorr2(image1,image2);
end
function letter=stringsplitter(address)
% Define the input file path as a string
parts = strsplit(address, '\');
letter=strsplit(parts{numel(parts)},'.');
letter=letter{1};
end