You are not logged in.
Hello everyone!
Mesa177 Thank you alot for this amazing post...i was wondering if i may contact you regarding this project I have started working on it lately.
As I have posted earlier, any questions can be directly posted on this thread concerning this particular project. If you deem any question for whatsoever reason as private, then by all means PM me.
Might as well continue with this post since Beast_C is showing interest in it, plus it's long overdue.
For better viewing of code and images, and for better referencing to the post number, I'll write each stage in a separate post (hope the moderators don't mind).
For the image masking stage (a continuation of my written code in post # 9):
% 2 - Image Masking:
%
% The result of SCW segmentation is then used to identify which regions of
% the input image (currently studied from the five images) are accepted
% (logical ANDing).
%
figure(3)
for i = 1:M1 % Image masking to form AND image
for j = 1:N1
if (I1_SCW(i,j))
I1_AND(i,j) = I1(i,j);
else
I1_AND(i,j) = 0;
end
end
end
imshow(I1_AND,[]);
The resulting image would be:
Last edited by mesa177 (July 2 2012)
For the Sauvola binarization:
% 3 - Sauvola Binarization (SB):
%
% The accepted regions are then thresholded according to Sauvola
% statistical means for each of the studied image.
%
figure(4)
I1_AND_ext = horzcat(I1_AND(:,1:5),I1_AND,I1_AND(:,N1-3:N1));
I1_AND_ext = vertcat(I1_AND_ext(1:5,:),I1_AND_ext,I1_AND_ext(M1-3:M1,:));
[M1_ext,N1_ext] = size(I1_AND_ext);
for i = 6:M1_ext-4 % Sauvola binarization (SB)
for j = 6:N1_ext-4
b = I1_AND_ext(i-5:i+4,j-5:j+4);
m = mean(mean(b));
s = std(std(b));
T = m + (1 + 0.5*(s/128 - 1));
if (I1_AND_ext(i,j) > T)
I1_SB_ext(i,j) = 1;
else
I1_SB_ext(i,j) = 0;
end
clear b m s T
end
end
I1_SB = I1_SB_ext(6:M1_ext-4,6:N1_ext-4);
imshow(I1_SB,[]);
clear I1_AND_ext I1_SB_ext M1_ext N1_ext
The resulting image would be:
Last edited by mesa177 (July 2 2012)
For the connected-component analysis (CCA), stage object labeling:
(more info on Gaussian blurring is found here, and the concept of convolution here)
% Generating Gaussian mask to be used for blurring thresholded picture
% before performing object labeling
% The code block below is commented after identifying the best Sigma value for applying the Gaussian filter
% sig = fix(randn*10); % Generating gradient of Gaussian masks for filtering
% % along x-axis (fx) and y-axis (fy)
% while (sig == 0)||(mod(sig,2)==0)||(abs(sig)>5)
% sig = fix(randn*10); % Ensure that masks formed are odd matrices
% end % each of whose size is no greater than 15x15
% sig = abs(sig); % Sigma should be positive
% After generating several Gaussian masks, best result obtained for sig = 1
sig = 1;
n = 3*sig;
for i=1:n
for j=1:n
g(i,j) = exp(-(i^2+j^2)/2*sig^2);
end
end
figure(5)
f1 = conv2(double(I1_SB),double(g)); % Convolution of the Gaussian filter and the SB image
f1 = f1(1:M1,1:N1);
[W1,num1] = bwlabel(f1,8); % CCA of SB image with thickened contours
imshow(W1,[]); % using Gaussian filter
The SB (Sauvola binarized) image after applying the Gaussian filter is:
The result of the Canny edge detection on the filtered SB image is:
For those who are wondering why we apply the Gaussian filter before doing the edge detection, here's the result of edge detection without the filtering process:
Last edited by mesa177 (July 2 2012)
Now, before finding the parameters of the LP (i.e. aspect ratio, orientation angle, and Euler's number) on the image under study to continue the CCA phase, it is important to identify the limits of these parameters (maximum and minimum required values to which the LP should be restricted). Generally, this should be done on a pool of images (like 50 plus images), but seeing that I was restricted to a pool of 5 images (my professor back then applied that restriction), that was what I did: use 5 images.
Note: The code for identifying the limits of each parameter is run on a separate m-file.
The code for detecting the LP aspect ratio limits is:
% Detecting Aspect Ratios of LP
% This program detects the aspect ratio of each of the five studied license
% plates. First, the objects in each image is labelled with bwlabel
% (classical approach of connected component labeling with 8-connectivity),
% then the label(s) identifying the boarders of the license plates are
% used to extract the position coordinates. The aspect ratio is then
% calculated according to the equation: (cmax - cmin + 1)/(rmax - rmin + 1).
clear all
clc
ob_cnt = 0;
% Generating Gaussian mask to be used for blurring thresholded picture
% before performing object labeling
% sig = fix(randn*10); % Generating gradient of Gaussian masks for filtering
% % along x-axis (fx) and y-axis (fy)
% while (sig == 0)||(mod(sig,2)==0)||(abs(sig)>5)
% sig = fix(randn*10); % Ensure that masks formed are odd matrices
% end % each of whose size is no greater than 15x15
% sig = abs(sig); % Sigma should be positive
% After generating several Gaussian masks, best result obtained for sig = 1
sig = 1;
n = 3*sig;
for i=1:n
for j=1:n
g(i,j) = exp(-(i^2+j^2)/2*sig^2);
end
end
figure(ob_cnt+1)
I1 = imread('image 1.jpg'); % Importing picture of license plate 1
I1 = rgb2gray(I1);
imshow(I1,[]); % Show grayscale picture
[M1,N1] = size(I1);
figure(ob_cnt+2)
I_bin1 = edge(I1,'canny'); % Performing edge detection with Canny method
imshow(I_bin1,[]); % Show edge detection
figure(ob_cnt+3)
f1 = conv2(double(I_bin1),double(g));
f1 = f1(1:M1,1:N1);
[W1,num1] = bwlabel(f1,8); % Labeling with Matlab command bwlabel
imshow(W1,[]);
figure(ob_cnt+4)
% Extracting LP from middle section where expected to be (using a cropping algorithm which is not shown
% here)
imshow(W1(600:910,990:1500),[]);
figure(ob_cnt+5)
% Tracking label of LP boarders at middle section where the LP is expected to be. This is done by conducting
% a frequency count on each object label found in the extracted LP zone; since the LP is the largest object in
% the restricted zone, the object label of the second highest frequency count (the first corresponding to the
% image background) corresponds to the LP itself. This process is not shown here; instead, the object label
% found i.e. 342 is used.
L1 = zeros(M1,N1);
[r1,c1,v1] = find(W1==342); % Final result
label1 = vertcat(r1',c1');
for i = 1:length(label1)
L1(label1(1,i),label1(2,i)) = W1(label1(1,i),label1(2,i));
end
imshow(L1,[]);
% clear L1 % Used for clearing image L1 upon label tracking until correct
% label is found
r1_max = max(label1(1,:))
r1_min = min(label1(1,:))
c1_max = max(label1(2,:))
c1_min = min(label1(2,:))
a1 = (c1_max - c1_min + 1)/(r1_max - r1_min + 1)
%--------------------------------------------------------------------------
ob_cnt = ob_cnt + 5;
figure(ob_cnt+1)
I2 = imread('image 2.jpg'); % Importing picture of license plate 2
I2 = rgb2gray(I2);
imshow(I2,[]); % Show grayscale picture
[M2,N2] = size(I2);
figure(ob_cnt+2)
I_bin2 = edge(I2,'canny'); % Performing edge detection with Canny method
imshow(I_bin2,[]); % Show edge detection
figure(ob_cnt+3)
f2 = conv2(double(I_bin2),double(g));
f2 = f2(1:M2,1:N2);
[W2,num2] = bwlabel(f2,8); % Labeling with Matlab command bwlabel
imshow(W2,[]);
figure(ob_cnt+4)
% Extracting LP from middle section where expected to be
imshow(W2(750:1100,900:1650),[]);
figure(ob_cnt+5)
% Tracking label of LP boarders at middle section where the LP is expected to be
L2 = zeros(M2,N2);
[r2,c2,v2] = find(W2==364); % Final result
label2 = vertcat(r2',c2');
for i = 1:length(label2)
L2(label2(1,i),label2(2,i)) = W2(label2(1,i),label2(2,i));
end
imshow(L2,[]);
% clear L2 % Used for clearing image L2 upon label tracking until correct
% % label is found
r2_max = max(label2(1,:))
r2_min = min(label2(1,:))
c2_max = max(label2(2,:))
c2_min = min(label2(2,:))
a2 = (c2_max - c2_min + 1)/(r2_max - r2_min + 1)
%--------------------------------------------------------------------------
ob_cnt = ob_cnt + 5;
figure(ob_cnt+1)
I3 = imread('image 3.jpg'); % Importing picture of license plate 3
I3 = rgb2gray(I3);
imshow(I3,[]); % Show grayscale picture
[M3,N3] = size(I3);
figure(ob_cnt+2)
I_bin3 = edge(I3,'canny'); % Performing edge detection with Canny method
imshow(I_bin3,[]); % Show edge detection
figure(ob_cnt+3)
f3 = conv2(double(I_bin3),double(g));
f3 = f3(1:M3,1:N3);
[W3,num3] = bwlabel(f3,8); % Labeling with Matlab command bwlabel
imshow(W3,[]);
figure(ob_cnt+4)
% Extracting LP from middle section where expected to be
imshow(W3(700:1100,1100:1700),[]);
figure(ob_cnt+5)
% Tracking label of LP boarders at middle section where the LP is expected to be
L3 = zeros(M3,N3);
[r3,c3,v3] = find(W3==369); % Final result
label3 = vertcat(r3',c3');
for i = 1:length(label3)
L3(label3(1,i),label3(2,i)) = W3(label3(1,i),label3(2,i));
end
imshow(L3,[]);
% clear L3 % Used for clearing image L3 upon label tracking until correct
% % label is found
r3_max = max(label3(1,:))
r3_min = min(label3(1,:))
c3_max = max(label3(2,:))
c3_min = min(label3(2,:))
a3 = (c3_max - c3_min + 1)/(r3_max - r3_min + 1)
%--------------------------------------------------------------------------
ob_cnt = ob_cnt + 5;
figure(ob_cnt+1)
I4 = imread('image 4.jpg'); % Importing picture of license plate 4
I4 = rgb2gray(I4);
imshow(I4,[]); % Show grayscale picture
[M4,N4] = size(I4);
figure(ob_cnt+2)
I_bin4 = edge(I4,'canny'); % Performing edge detection with Canny method
imshow(I_bin4,[]); % Show edge detection
figure(ob_cnt+3)
f4 = conv2(double(I_bin4),double(g));
f4 = f4(1:M4,1:N4);
[W4,num4] = bwlabel(f4,8); % Labeling with Matlab command bwlabel
imshow(W4,[]);
figure(ob_cnt+4)
% Extracting LP from middle section where expected to be
imshow(W4(620:1020,1000:1650),[]);
figure(ob_cnt+5)
% Tracking label of LP boarders at middle section where the LP is expected to be
L4 = zeros(M4,N4);
[r4,c4,v4] = find(W4==8); % Final result
label4 = vertcat(r4',c4');
for i = 1:length(label4)
L4(label4(1,i),label4(2,i)) = W4(label4(1,i),label4(2,i));
end
imshow(L4,[]);
% clear L4 % Used for clearing image L4 upon label tracking until correct
% % label is found
r4_max = max(label4(1,:))
r4_min = min(label4(1,:))
c4_max = max(label4(2,:))
c4_min = min(label4(2,:))
a4 = (c4_max - c4_min + 1)/(r4_max - r4_min + 1)
%--------------------------------------------------------------------------
ob_cnt = ob_cnt + 5;
figure(ob_cnt+1)
I5 = imread('image 5.jpg'); % Importing picture of license plate 5
I5 = rgb2gray(I5);
imshow(I5,[]); % Show grayscale picture
[M5,N5] = size(I5);
figure(ob_cnt+2)
I_bin5 = edge(I5,'canny'); % Performing edge detection with Canny method
imshow(I_bin5,[]); % Show edge detection
figure(ob_cnt+3)
f5 = conv2(double(I_bin5),double(g));
f5 = f5(1:M5,1:N5);
[W5,num5] = bwlabel(f5,8); % Labeling with Matlab command bwlabel
imshow(W5,[]);
figure(ob_cnt+4)
% Extracting LP from middle section where expected to be
imshow(W5(600:1100,710:1850),[]);
figure(ob_cnt+5)
% Tracking label of LP boarders at middle section where the LP is expected to be
L5 = zeros(M5,N5);
[r5,c5,v5] = find(W5==124); % Final result
label5 = vertcat(r5',c5');
for i = 1:length(label5)
L5(label5(1,i),label5(2,i)) = W5(label5(1,i),label5(2,i));
end
imshow(L5,[]);
% clear L5 % Used for clearing image L5 upon label tracking until correct
% % label is found
r5_max = max(label5(1,:))
r5_min = min(label5(1,:))
c5_max = max(label5(2,:))
c5_min = min(label5(2,:))
a5 = (c5_max - c5_min + 1)/(r5_max - r5_min + 1)
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
The code for detecting the LP orientation angle limits is:
% Detecting Orientation Angles of LP
% This program detects the orientation angle of each of the five studied
% license plates. First, the objects in each image is labelled with bwlabel
% (classical approach of connected component labeling with 8-connectivity),
% then the labeled matrix is used for calculating the orientation angle,
% which is calculated according to the equation:
% tan(phi_i) = 2[r_sum(c_sum(rcWi(r,c))]/[r_sum(c_sum(r^2Wi(r,c)) -
% r_sum(c_sum(c^2Wi(r,c))]
clear all
clc
ob_cnt = 0;
% Generating Gaussian mask to be used for blurring thresholded picture
% before performing object labeling
% sig = fix(randn*10); % Generating gradient of Gaussian masks for filtering
% % along x-axis (fx) and y-axis (fy)
% while (sig == 0)||(mod(sig,2)==0)||(abs(sig)>5)
% sig = fix(randn*10); % Ensure that masks formed are odd matrices
% end % each of whose size is no greater than 15x15
% sig = abs(sig); % Sigma should be positive
% After generating several Gaussian masks, best result obtained for sig = 1
sig = 1;
n = 3*sig;
for i=1:n
for j=1:n
g(i,j) = exp(-(i^2+j^2)/2*sig^2);
end
end
figure(ob_cnt+1)
I1 = imread('image 1.jpg'); % Importing picture of license plate 1
I1 = rgb2gray(I1);
imshow(I1,[]); % Show grayscale picture
[M1,N1] = size(I1);
figure(ob_cnt+2)
I_bin1 = edge(I1,'canny'); % Performing edge detection with Canny method
imshow(I_bin1,[]); % Show edge detection
figure(ob_cnt+3)
f1 = conv2(double(I_bin1),double(g));
f1 = f1(1:M1,1:N1);
[W1,num1] = bwlabel(f1,8); % Labeling with Matlab command bwlabel
imshow(W1,[]);
figure(ob_cnt+4)
L1 = zeros(M1,N1);
[r1,c1,v1] = find(W1==342);
label1 = vertcat(r1',c1');
for i = 1:length(label1)
L1(label1(1,i),label1(2,i)) = W1(label1(1,i),label1(2,i));
end
imshow(L1,[]);
for i = 1:M1
for j = 1:N1
rc_component1(i,j) = i*j*L1(i,j);
end
end
for i = 1:M1
for j = 1:N1
r2_component1(i,j) = i^2*L1(i,j);
end
end
for i = 1:M1
for j = 1:N1
c2_component1(i,j) = j^2*L1(i,j);
end
end
phi1 = atand((2*sum(sum(rc_component1)))/...
(sum(sum(r2_component1))-sum(sum(c2_component1))))
%--------------------------------------------------------------------------
ob_cnt = ob_cnt + 4;
figure(ob_cnt+1)
I2 = imread('image 2.jpg'); % Importing picture of license plate 2
I2 = rgb2gray(I2);
imshow(I2,[]); % Show grayscale picture
[M2,N2] = size(I2);
figure(ob_cnt+2)
I_bin2 = edge(I2,'canny'); % Performing edge detection with Canny method
imshow(I_bin2,[]); % Show edge detection
figure(ob_cnt+3)
f2 = conv2(double(I_bin2),double(g));
f2 = f2(1:M2,1:N2);
[W2,num2] = bwlabel(f2,8); % Labeling with Matlab command bwlabel
imshow(W2,[]);
figure(ob_cnt+4)
L2 = zeros(M2,N2);
[r2,c2,v2] = find(W2==364);
label2 = vertcat(r2',c2');
for i = 1:length(label2)
L2(label2(1,i),label2(2,i)) = W2(label2(1,i),label2(2,i));
end
imshow(L2,[]);
for i = 1:M2
for j = 1:N2
rc_component2(i,j) = i*j*L2(i,j);
end
end
for i = 1:M2
for j = 1:N2
r2_component2(i,j) = i^2*L2(i,j);
end
end
for i = 1:M2
for j = 1:N2
c2_component2(i,j) = j^2*L2(i,j);
end
end
phi2 = atand((2*sum(sum(rc_component2)))/...
(sum(sum(r2_component2))-sum(sum(c2_component2))))
%--------------------------------------------------------------------------
ob_cnt = ob_cnt + 4;
figure(ob_cnt+1)
I3 = imread('image 3.jpg'); % Importing picture of license plate 3
I3 = rgb2gray(I3);
imshow(I3,[]); % Show grayscale picture
[M3,N3] = size(I3);
figure(ob_cnt+2)
I_bin3 = edge(I3,'canny'); % Performing edge detection with Canny method
imshow(I_bin3,[]); % Show edge detection
figure(ob_cnt+3)
f3 = conv2(double(I_bin3),double(g));
f3 = f3(1:M3,1:N3);
[W3,num3] = bwlabel(f3,8); % Labeling with Matlab command bwlabel
imshow(W3,[]);
figure(ob_cnt+4)
L3 = zeros(M3,N3);
[r3,c3,v3] = find(W3==369);
label3 = vertcat(r3',c3');
for i = 1:length(label3)
L3(label3(1,i),label3(2,i)) = W3(label3(1,i),label3(2,i));
end
imshow(L3,[]);
for i = 1:M3
for j = 1:N3
rc_component3(i,j) = i*j*L3(i,j);
end
end
for i = 1:M3
for j = 1:N3
r2_component3(i,j) = i^2*L3(i,j);
end
end
for i = 1:M3
for j = 1:N3
c2_component3(i,j) = j^2*L3(i,j);
end
end
phi3 = atand((2*sum(sum(rc_component3)))/...
(sum(sum(r2_component3))-sum(sum(c2_component3))))
%--------------------------------------------------------------------------
ob_cnt = ob_cnt + 4;
figure(ob_cnt+1)
I4 = imread('image 4.jpg'); % Importing picture of license plate 4
I4 = rgb2gray(I4);
imshow(I4,[]); % Show grayscale picture
[M4,N4] = size(I4);
figure(ob_cnt+2)
I_bin4 = edge(I4,'canny'); % Performing edge detection with Canny method
imshow(I_bin4,[]); % Show edge detection
figure(ob_cnt+3)
f4 = conv2(double(I_bin4),double(g));
f4 = f4(1:M4,1:N4);
[W4,num4] = bwlabel(f4,8); % Labeling with Matlab command bwlabel
imshow(W4,[]);
figure(ob_cnt+4)
L4 = zeros(M4,N4);
[r4,c4,v4] = find(W4==8);
label4 = vertcat(r4',c4');
for i = 1:length(label4)
L4(label4(1,i),label4(2,i)) = W4(label4(1,i),label4(2,i));
end
imshow(L4,[]);
for i = 1:M4
for j = 1:N4
rc_component4(i,j) = i*j*L4(i,j);
end
end
for i = 1:M4
for j = 1:N4
r2_component4(i,j) = i^2*L4(i,j);
end
end
for i = 1:M4
for j = 1:N4
c2_component4(i,j) = j^2*L4(i,j);
end
end
phi4 = atand((2*sum(sum(rc_component4)))/...
(sum(sum(r2_component4))-sum(sum(c2_component4))))
%--------------------------------------------------------------------------
ob_cnt = ob_cnt + 4;
figure(ob_cnt+1)
I5 = imread('image 5.jpg'); % Importing picture of license plate 5
I5 = rgb2gray(I5);
imshow(I5,[]); % Show grayscale picture
[M5,N5] = size(I5);
figure(ob_cnt+2)
I_bin5 = edge(I5,'canny'); % Performing edge detection with Canny method
imshow(I_bin5,[]); % Show edge detection
figure(ob_cnt+3)
f5 = conv2(double(I_bin5),double(g));
f5 = f5(1:M5,1:N5);
[W5,num5] = bwlabel(f5,8); % Labeling with Matlab command bwlabel
imshow(W5,[]);
figure(ob_cnt+4)
L5 = zeros(M5,N5);
[r5,c5,v5] = find(W5==124);
label5 = vertcat(r5',c5');
for i = 1:length(label5)
L5(label5(1,i),label5(2,i)) = W5(label5(1,i),label5(2,i));
end
imshow(L5,[]);
for i = 1:M5
for j = 1:N5
rc_component5(i,j) = i*j*L5(i,j);
end
end
for i = 1:M5
for j = 1:N5
r2_component5(i,j) = i^2*L5(i,j);
end
end
for i = 1:M5
for j = 1:N5
c2_component5(i,j) = j^2*L5(i,j);
end
end
phi5 = atand((2*sum(sum(rc_component5)))/...
(sum(sum(r2_component5))-sum(sum(c2_component5))))
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
As for the Euler number, the limit is always 3, because in each LP there should be at least three characters. Hence, no code needed to identify limit.
The extracted LP zone in one of the pool images (which is also the studied image) is:
The image resulting from the LP's label tracking (not necessary to perform, but it would give you a good idea about the accuracy of your algorithm concerning aspect ratio) for the same pool image is:
The limit values of the aspect ratio are 1.5 and 5.5, while those of the orientation angle are 105 and 140 (offset by pi or 180 degrees, no reason for the offset except that I wanted to maintain a positive value for the angle).
Last edited by mesa177 (July 3 2012)
This is absolutely awesome Mesa, very nice. I'm very interested in the result and I'm sure as he'll going to try and port it to python as an exercise.
Edit: you may want to toss in a license as no license means it defaults to copyright.
@xterm; Do whatever pleases you with the code, I couldn't care less. Port it, use it, go crazy, I don't mind. This project was just a final assignment on one of my masters courses, and the first post shows what papers I heavily relied on concerning the algorithms.
Continuing with the CCA phase parameters identification for the image under study:
figure(ob_cnt+6)
cnt1 = 0;
for k = 1:num1 % Calculate aspect ratio
L1 = zeros(M1,N1);
[r1,c1,v1] = find(W1==k);
label1 = vertcat(r1',c1');
for i = 1:size(label1,2)
L1(label1(1,i),label1(2,i)) = W1(label1(1,i),label1(2,i));
end
r1_max = max(label1(1,:));
r1_min = min(label1(1,:));
c1_max = max(label1(2,:));
c1_min = min(label1(2,:));
a1(k) = (c1_max - c1_min + 1)/(r1_max - r1_min + 1);
clear L1 r1 c1 v1 label1
end
for k = 1:num1 % Calculate orientation angle
L1 = zeros(M1,N1);
[r1,c1,v1] = find(W1==k);
label1 = vertcat(r1',c1');
for i = 1:size(label1,2)
L1(label1(1,i),label1(2,i)) = W1(label1(1,i),label1(2,i));
rc_component1(label1(1,i),label1(2,i)) = label1(1,i)*label1(2,i)...
*L1(label1(1,i),label1(2,i));
r2_component1(label1(1,i),label1(2,i)) = label1(1,i)^2*...
L1(label1(1,i),label1(2,i));
c2_component1(label1(1,i),label1(2,i)) = label1(2,i)^2*...
L1(label1(1,i),label1(2,i));
end
phi1(k) = atand((2*sum(sum(rc_component1)))/...
(sum(sum(r2_component1))-sum(sum(c2_component1))));
clear L1 r1 c1 v1 label1 rc_component1 r2_component1 c2_component1
end
for k = 1:num1 % Calculate Euler's number
L1 = zeros(M1,N1);
[r1,c1,v1] = find(W1==k);
label1 = vertcat(r1',c1');
for i = 1:size(label1,2)
L1(label1(1,i),label1(2,i)) = W1(label1(1,i),label1(2,i));
end
L1_ed = edge(L1,'canny');
euler_num1(k) = bweuler(L1_ed,8);
clear L1 r1 c1 v1 label1 L1_ed
end
Now to extract the LPs in the image (extracting the objects which meat the standards i.e. parameter limitations):
I1_ob = zeros(M1,N1);
I1_f = zeros(M1,N1);
for k = 1:num1 % Retrieve objects with specific aspect ratio,
% orientation angle, and Euler's number
if ((a1(k) > 1.5)&&(a1(k) < 5.5))&&...
(((phi1(k)+180) > 105)&&((phi1(k)+180) < 140))&&...
(euler_num1(k) >= 3)
L1 = zeros(M1,N1);
[r1,c1,v1] = find(W1==k);
label1 = vertcat(r1',c1');
for i = 1:size(label1,2)
L1(label1(1,i),label1(2,i)) = W1(label1(1,i),label1(2,i));
end
for i = 1:length(label1)
I1_ob(label1(1,i),label1(2,i)) = L1(label1(1,i),label1(2,i));
end
r1_max = max(label1(1,:));
r1_min = min(label1(1,:));
c1_max = max(label1(2,:));
c1_min = min(label1(2,:));
A1(cnt1+1,:) = [r1_max,r1_min,c1_max,c1_min];
I1_f(r1_min:r1_max,c1_min:c1_max) = ...
I1(r1_min:r1_max,c1_min:c1_max);
cnt1 = cnt1 + 1;
clear L1 r1 c1 v1 label1 r1_max r1_min c1_max c1_min
end
end
The resulting extracted LP in its binary form is:
Last edited by mesa177 (July 3 2012)
For the studied image, there is no need to perform the image inversion. However, in some cases it is necessary.
The code for the image inversion is:
if (~cnt1) % Detect if image inversion is needed
clear I1_SCW I1_AND I1_SB W1 I1_ob f1 a1 phi1 euler_num1
figure(1)
I11 = uint8(255*ones(M1,N1)-double(I1)); % Invert image
I1 = I11;
clear I11
imshow(I1,[]);
% Repeat prior steps of SCW, image masking, SB, and CCA
figure(2)
I1_ext = horzcat(I1(:,1:12),I1,I1(:,N1-10:N1));
I1_ext = vertcat(I1_ext(1:4,:),I1_ext,I1_ext(M1-2:M1,:));
[M1_ext,N1_ext] = size(I1_ext);
for i = 5:M1_ext-3
for j = 13:N1_ext-11
A_SCW = I1_ext(i-2:i+1,j-6:j+5);
B_SCW = I1_ext(i-4:i+3,j-12:j+11);
mA = mean(mean(A_SCW));
mB = mean(mean(B_SCW));
if (mA/mB < TS)
I1_SCW_ext(i,j) = 1;
else
I1_SCW_ext(i,j) = 0;
end
clear A_SCW B_SCW mA mB
end
end
I1_SCW = I1_SCW_ext(5:M1_ext-3,13:N1_ext-11);
imshow(I1_SCW,[]); % Show SCW segmentation
clear I1_ext I1_SCW_ext M1_ext N1_ext
figure(3)
for i = 1:M1 % Image masking to form AND image
for j = 1:N1
if (I1_SCW(i,j))
I1_AND(i,j) = I1(i,j);
else
I1_AND(i,j) = 0;
end
end
end
imshow(I1_AND,[]);
figure(4)
I1_AND_ext = horzcat(I1_AND(:,1:5),I1_AND,I1_AND(:,N1-3:N1));
I1_AND_ext = vertcat(I1_AND_ext(1:5,:),I1_AND_ext,I1_AND_ext(M1-3:M1,:));
[M1_ext,N1_ext] = size(I1_AND_ext);
for i = 6:M1_ext-4 % Sauvola binarization (SB)
for j = 6:N1_ext-4
b = I1_AND_ext(i-5:i+4,j-5:j+4);
m = mean(mean(b));
s = std(std(b));
T = m + (1 + 0.5*(s/128 - 1));
if (I1_AND_ext(i,j) > T)
I1_SB_ext(i,j) = 1;
else
I1_SB_ext(i,j) = 0;
end
clear b m s T
end
end
I1_SB = I1_SB_ext(6:M1_ext-4,6:N1_ext-4);
imshow(I1_SB,[]);
clear I1_AND_ext I1_SB_ext M1_ext N1_ext
figure(ob_cnt+5)
f1 = conv2(double(I1_SB),double(g));
f1 = f1(1:M1,1:N1);
[W1,num1] = bwlabel(f1,8); % CCA of SB image with thickened contours
imshow(W1,[]); % using Gaussian filter
figure(6)
cnt1 = 0;
for k = 1:num1 % Calculate aspect ratio
L1 = zeros(M1,N1);
[r1,c1,v1] = find(W1==k);
label1 = vertcat(r1',c1');
for i = 1:size(label1,2)
L1(label1(1,i),label1(2,i)) = W1(label1(1,i),label1(2,i));
end
r1_max = max(label1(1,:));
r1_min = min(label1(1,:));
c1_max = max(label1(2,:));
c1_min = min(label1(2,:));
a1(k) = (c1_max - c1_min + 1)/(r1_max - r1_min + 1);
clear L1 r1 c1 v1 label1
end
for k = 1:num1 % Calculate orientation angle
L1 = zeros(M1,N1);
[r1,c1,v1] = find(W1==k);
label1 = vertcat(r1',c1');
for i = 1:size(label1,2)
L1(label1(1,i),label1(2,i)) = W1(label1(1,i),label1(2,i));
rc_component1(label1(1,i),label1(2,i)) = label1(1,i)*...
label1(2,i)*...
L1(label1(1,i),label1(2,i));
r2_component1(label1(1,i),label1(2,i)) = label1(1,i)^2*...
L1(label1(1,i),label1(2,i));
c2_component1(label1(1,i),label1(2,i)) = label1(2,i)^2*...
L1(label1(1,i),label1(2,i));
end
phi1(k) = atand((2*sum(sum(rc_component1)))/...
(sum(sum(r2_component1))-sum(sum(c2_component1))));
clear L1 r1 c1 v1 label1 rc_component1 r2_component1 c2_component1
end
for k = 1:num1 % Calculate Euler's number
L1 = zeros(M1,N1);
[r1,c1,v1] = find(W1==k);
label1 = vertcat(r1',c1');
for i = 1:size(label1,2)
L1(label1(1,i),label1(2,i)) = W1(label1(1,i),label1(2,i));
end
L1_ed = edge(L1,'canny');
euler_num1(k) = bweuler(L1_ed,8);
clear L1 r1 c1 v1 label1 L1_ed
end
I1_ob = zeros(M1,N1);
I1_f = zeros(M1,N1);
for k = 1:num1 % Retrieve objects with specific aspect
% ratio, orientation angle, and Euler's
% number
if ((a1(k) > 1.5)&&(a1(k) < 5.5))&&...
(((phi1(k)+180) > 105)&&((phi1(k)+180) < 140))&&...
(euler_num1(k) >= 3)
L1 = zeros(M1,N1);
[r1,c1,v1] = find(W1==k);
label1 = vertcat(r1',c1');
for i = 1:size(label1,2)
L1(label1(1,i),label1(2,i)) = W1(label1(1,i),label1(2,i));
end
for i = 1:length(label1)
I1_ob(label1(1,i),label1(2,i)) = L1(label1(1,i),label1(2,i));
end
r1_max = max(label1(1,:));
r1_min = min(label1(1,:));
c1_max = max(label1(2,:));
c1_min = min(label1(2,:));
A1(cnt1+1,:) = [r1_max,r1_min,c1_max,c1_min];
I1_f(r1_min:r1_max,c1_min:c1_max) = ...
I1(r1_min:r1_max,c1_min:c1_max);
cnt1 = cnt1 + 1;
clear L1 r1 c1 v1 label1 r1_max r1_min c1_max c1_min
end
end
end
Naturally, it would be common sense to squeeze the SCW, image masking, SB, and CCA processes in a nice function and call it once before image inversion and another time after, but for the sake of explanation I reposted the code.
Seeing that performing image inversion on the studied image is pointless, I chose another image from my pool to exemplify the situation:
In grayscale:
If you apply the SCW and image inversion, nothing of the LP remains and hence no objects i.e. LPs are detected. So image inversion is performed:
The resulting SCW:
And the image masking:
And the SB:
Which finally yields after the CCA the binary LP:
Last edited by mesa177 (July 2 2012)
If after image inversion no LPs are detected, an error is displayed:
if (~cnt1)
disp('No LPs in image');
end
Otherwise, the code continues and the grayscale LP object is displayed:
imshow(I1_ob,[]); % Located regions of LPs in image 1
figure(7)
imshow(I1_f,[]); % Extracted LPs in image 1
save A1.txt -ascii -tabs A1 % Saving the matrix ensures that the dimensions of the LP can be derived for later
% stages and the LPR process doesn't have to be conducted again
% Furthermore, the matrix elements will be used as well
Displayed grayscale LP for the first non-inverted image (successful):
Displayed grayscale LP for inverted image (partially successful):
Since only the first image is successful in yielding the LP as a whole, the coding hereon concentrates on that image.
Last edited by mesa177 (July 2 2012)
For the second stage, we perform the character segmentation for the LP(s) extracted, or LPCS.
Note: the code of the LPCS stage is run on a separate m-file than the LPR stage. Hence, all initializations are re-conducted. Also, the entire LPCS process is repeated for each LP extracted from the LPR stage; thus, the LPCS code is incorporated in a for loop as follows:
for cnt = 1:size(A1,1) % Performing CS for each extracted LP
...
end % For the original for loop
First, we start by specifying how many LPs have been recognized in the LPR stage through extracting boundary coordinates of each:
% Character Segmentation of LP
%
% This code implements the character segmentation (CS) as follows:
%
% 1 - Specifying Sub-images:
%
% Using the matrix Ai, the boundary coordinates of identified LPs are used
% to extract each LP as a sub-image and subject it to CS processing.
%
%--------------------------------------------------------------------------
% Initialization Stage
clear all
clc
ob_cnt = 0;
TS = 0.9; % Threshold for segmentation rule
sig = 1;
n = 3*sig;
for i=1:n
for j=1:n
g(i,j) = exp(-(i^2+j^2)/2*sig^2);
end
end
%--------------------------------------------------------------------------
load A1.txt A1 % Loading matrix with coordinates of LP boundaries
I1 = imread('image 1.jpg');
I1 = rgb2gray(I1);
for cnt = 1:size(A1,1) % Performing CS for each extracted LP
% Starting sub-image specification
LP1 = I1(A1(cnt,2):A1(cnt,1),A1(cnt,4):A1(cnt,3));
figure(ob_cnt+1)
imshow(LP1,[]);
[M1(cnt),N1(cnt)] = size(LP1);
ar1(cnt) = N1(cnt)/M1(cnt);
The image of the first (and in this case only) LP extracted is:
Before cropping them, the sub-images require some pre-processing, namely edge detection, connected-component labeling (CCL), and slant correction:
% 2 - Pre-processing Sub-images:
%
% Before cropping, some pre-processing is required. The grayscale
% sub-images are subjected to edge detection and then connected component
% labeling. This allows the specification of the objects in the image. The
% object with the aspect ratio closest to that recorded in previous LPR
% stage (error margin is 0.011) corresponds to the LP boarders. The label
% corresponding to the this aspect ratio is used to isolate the LP boarders
% in a separate image. Since the algorithm does not account for tilted LPs,
% the derived aspect ratio of the LP might not be the actual one. As such,
% the aspect ratio of the LP is calculated from a frontal partition of the
% separate LP-boarder image; the larger value is considered as the actual
% aspect ratio of the LP. This value determines the standard size of the
% cropped LP. Non-tilted LPs would have almost identical results to the
% already calculated aspect ratio. If the actual aspect ratio is smaller
% than derived aspect ratio with an error exceeding 0.01, the LP is tilted
% in the image. This tilt is corrected by a slant correction algorithm that
% is based upon feature point and principal component analysis. This allows
% the re-orientation of the original sub-image back into place (along
% horizontal line).
%
% Starting sub-image pre-processing
LP1_ed = edge(LP1,'canny'); % Canny edge detection
f1 = conv2(double(LP1_ed),double(g)); % Gaussian filtering
f1 = f1(1:M1(cnt),1:N1(cnt));
[W1,num1] = bwlabel(f1,8);
for k = 1:num1 % Extracting LP boarders
[r1,c1,v1] = find(W1==k);
label1 = vertcat(r1',c1');
r1_max = max(label1(1,:));
r1_min = min(label1(1,:));
c1_max = max(label1(2,:));
c1_min = min(label1(2,:));
a1(k) = (c1_max - c1_min + 1)/(r1_max - r1_min + 1);
clear r1 c1 v1 label1 r1_max r1_min c1_max c1_min
end
[rLPB1,cLPB1,vLPB1] = find(abs(a1-ar1(cnt)) < 0.11);
LPB1 = zeros(M1(cnt),N1(cnt));
p = find(max(a1(cLPB1))); % Ensure that only LP boarder label remains
[r1,c1,v1] = find(W1==cLPB1(p));
label1 = vertcat(r1',c1');
for i = 1:size(label1,2)
LPB1(label1(1,i),label1(2,i)) = W1(label1(1,i),label1(2,i));
end
clear p r1 c1 v1 label1 a1 rLPB1 cLPB1 vLPB1
% Finding actual LP aspect ratio
[r1,c1,v1] = find(LPB1(:,1:fix(N1(cnt)/4))~=0);
label1 = vertcat(r1',c1');
r1_max = max(label1(1,:));
r1_min = min(label1(1,:));
c1_max = max(label1(2,:));
c1_min = min(label1(2,:));
a1_LPB_f = (c1_max - c1_min + 1)/(r1_max - r1_min + 1);
clear r1 c1 v1 label1 r1_max r1_min c1_max c1_min
f = 0; % Flag to identify if rotation is needed
if (abs(ar1(cnt)/4-a1_LPB_f) > 0.01) % Correcting LP slant orientation
LP1_bin = edge(LPB1,'log');
[rf1,cf1,vf1] = find(LP1_bin==1);
m1 = mean(rf1);
m2 = mean(cf1);
S1(1,1) = sum(sum((rf1-m1*ones(1,size(rf1,2)))*...
(rf1-m1*ones(1,size(rf1,2)))'));
S1(1,2) = sum(sum((rf1-m1*ones(1,size(rf1,2)))*...
(cf1-m2*ones(1,size(cf1,2)))'));
S1(2,1) = sum(sum((rf1-m1*ones(1,size(rf1,2)))*...
(cf1-m2*ones(1,size(cf1,2)))'));
S1(2,2) = sum(sum((cf1-m2*ones(1,size(cf1,2)))*...
(cf1-m2*ones(1,size(cf1,2)))'));
[EV1,E1] = eigs(S1);
E1_max = max(diag(E1));
[rE1,cE1,vE1] = find(E1==E1_max);
EV1_PC = EV1(:,cE1);
phi1 = asind(EV1_PC(2));
figure(ob_cnt+2)
LP1_r = imrotate(LP1,phi1,'bilinear');
imshow(LP1_r,[]);
figure(ob_cnt+3)
LPB1_r = imrotate(LPB1,phi1,'bilinear');
imshow(LPB1_r,[]);
[M1_r(cnt),N1_r(cnt)] = size(LP1_r);
f = 1;
end
The slant correction yields the following image:
For the sub-image cropping (i.e. modifying the LP size into a standard one for further processing):
(Note: Before commencing with the cropping, if the LP requires slant correction, the new LP aspect ratio is identified)
% 3 - Cropping Sub-images:
%
% Using bicubic interpolation, the original/oriented sub-images are cropped
% into one of two standard sizes: if LP actual aspect ratio is greater than
% or equal to 3, the standard size would be 202 x 902 pixels; otherwise,
% the size would be 522 x 1002 pixels. If an image has a dimension smaller
% than the crop limit, its size is magnified by appending zeros at the
% sides (equal distributions on both upper and lower edges for rows or left
% and right edges for columns).
%
if (f) % Finding actual LP aspect ratio for cropping
[r1,c1,v1] = find(LPB1_r~=0);
label1 = vertcat(r1',c1');
r1_max = max(label1(1,:));
r1_min = min(label1(1,:));
c1_max = max(label1(2,:));
c1_min = min(label1(2,:));
LPB1_r = LPB1_r(r1_min:r1_max,c1_min:c1_max);
LP1_r = LP1_r(r1_min:r1_max,c1_min:c1_max);
[M1_r(cnt),N1_r(cnt)] = size(LP1_r);
a1_LPB(cnt) = (c1_max - c1_min + 1)/(r1_max - r1_min + 1);
clear r1 c1 v1 label1 r1_max r1_min c1_max c1_min
else
a1_LPB(cnt) = ar1(cnt);
end
figure(ob_cnt+4)
if (a1_LPB(cnt) >= 3) % Cropping LP to standard size
if (f)
cr_r_a1 = fix((M1_r(cnt)-100)/2) + 2*mod(M1_r(cnt)-100,2);
cr_r_b1 = fix((M1_r(cnt)-100)/2) - mod(M1_r(cnt)-100,2);
cr_c_a1 = fix((N1_r(cnt)-450)/2) + 2*mod(N1_r(cnt)-450,2);
cr_c_b1 = fix((N1_r(cnt)-450)/2) - mod(N1_r(cnt)-450,2);
LP1_cr = LP1_r(cr_r_a1:M1_r(cnt)-cr_r_b1,...
cr_c_a1:N1_r(cnt)-cr_c_b1);
else
cr_r_a1 = fix((M1(cnt)-100)/2) + 2*mod(M1(cnt)-100,2);
cr_r_b1 = fix((M1(cnt)-100)/2) - mod(M1(cnt)-100,2);
cr_c_a1 = fix((N1(cnt)-450)/2) + 2*mod(N1(cnt)-450,2);
cr_c_b1 = fix((N1(cnt)-450)/2) - mod(N1(cnt)-450,2);
LP1_cr = LP1_r(cr_r_a1:M1(cnt)-cr_r_b1,...
cr_c_a1:N1(cnt)-cr_c_b1);
end
else
if (f)
cr_r_a1 = fix((M1_r(cnt)-260)/2) + 2*mod(M1_r(cnt)-260,2);
cr_r_b1 = fix((M1_r(cnt)-260)/2) - mod(M1_r(cnt)-260,2);
cr_c_a1 = fix((N1_r(cnt)-500)/2) + 2*mod(N1_r(cnt)-500,2);
cr_c_b1 = fix((N1_r(cnt)-500)/2) - mod(N1_r(cnt)-500,2);
LP1_cr = LP1_r(cr_r_a1:M1_r(cnt)-cr_r_b1,...
cr_c_a1:N1_r(cnt)-cr_c_b1);
else
cr_r_a1 = fix((M1(cnt)-260)/2) + 2*mod(M1(cnt)-260,2);
cr_r_b1 = fix((M1(cnt)-260)/2) - mod(M1(cnt)-260,2);
cr_c_a1 = fix((N1(cnt)-500)/2) + 2*mod(N1(cnt)-500,2);
cr_c_b1 = fix((N1(cnt)-500)/2) - mod(N1(cnt)-500,2);
LP1_cr = LP1_r(cr_r_a1:M1(cnt)-cr_r_b1,...
cr_c_a1:N1(cnt)-cr_c_b1);
end
end
LP1_cr_bi = imresize(LP1_cr,2,'bicubic');
imshow(LP1_cr_bi,[]);
[M1_bi(cnt),N1_bi(cnt)] = size(LP1_cr_bi);
figure(ob_cnt+5) % Apply median filter to remove speckle noise
LP1_bi = medfilt2(LP1_cr_bi,[5,5]);
imshow(LP1_bi,[]);
The cropped LP image is:
Last edited by mesa177 (July 3 2012)
For the LP partitioning (regions E for English characters and A for Arabic characters):
% 4 - Dividing LP into 2 Partitions (English and Arabic):
%
% Unlike most countries, the Lebanese LPs are composed of English and
% Arabic segments. There are two formats for an LP: one with aspect ratio
% greater than or equal to 3 and one less than 3. The first format has the
% English segment of the LP followed by the Arabic segment (along the
% horizontal direction). The other format has the English segment above the
% Arabic segment (along vertical direction). So, to enhance operation speed
% and facilitate process of character recognition later on, the LP is
% divided into 2 segments according to its format. Stage 3 of the CS
% operation has already specified a standerdized size for each LP format.
% Thus, LPs with standard size 202 x 902 pixels are of Format 1 while those
% with size 522 x 1002 pixels are of Format 2. Format 1 LPs are divided
% along the vertical direction into two equal segments, while Format 2 LPs
% are divided along the horizontal direction into two equal segments. The
% English segment is noted by "E" while the Arabic segment by "A". Since
% each segment of the Lebanese license plate also contains the word
% "Lebanon" in its respective language, some of the rows in Format 1 LPs
% or some of the columns in Format 2 LPs are eliminated to remove those
% regions. The standard size of each segment is 117 x 452 in Format 1 and
% 117 x 452 in Format 2 (segments E and A are of equal standard sizes).
%
% LP Partitioning
if (a1_LPB(cnt) >= 3) % LP is of Format 1
LP1_1 = LP1_bi(20:fix(M1_bi(cnt)*2/3)+2,1:N1_bi(cnt)/2+1);
LP1_2 = LP1_bi(fix(M1_bi(cnt)*1/3)+19:M1_bi(cnt),...
N1_bi(cnt)/2:N1_bi(cnt));
else % LP is of Format 2
LP1_1 = LP1_bi(1:fix(M1_bi(cnt)*2/3)+2,1:N1_bi(cnt)/2+1);
LP1_2 = LP1_bi(fix(M1_bi(cnt)*1/3):M1_bi(cnt),...
N1_bi(cnt)/2:N1_bi(cnt));
end
figure(ob_cnt+6)
subplot(2,1,1)
imshow(LP1_1,[]);
subplot(2,1,2)
imshow(LP1_2,[]);
[M1_ErA(cnt),N1_ErA(cnt)] = size(LP1_1);
Regions E and A are shown as subplots on the same image:
For the SCW of regions E and A:
% 5 - SCW Segmentation of Characters:
%
% Each of Format 1 E and Format 1 A or Format 2 E and Format 2 A partitions
% have their characters segmented, starting with statistical thresholding
% SCW segmentation.
%
% SCW segmentation of characters
figure(ob_cnt+7)
subplot(2,1,1)
LP1_ext = horzcat(LP1_1(:,1:4),LP1_1,...
LP1_1(:,N1_ErA(cnt)-2:N1_ErA(cnt)));
LP1_ext = vertcat(LP1_ext(1:8,:),LP1_ext,...
LP1_ext(M1_ErA(cnt)-6:M1_ErA(cnt),:));
[M1_ext(cnt),N1_ext(cnt)] = size(LP1_ext);
for i = 9:M1_ext-7
for j = 5:N1_ext-3
A_SCW = LP1_ext(i-4:i+3,j-2:j+1);
B_SCW = LP1_ext(i-8:i+7,j-4:j+3);
mA = mean(mean(A_SCW));
mB = mean(mean(B_SCW));
if (mA/mB < TS)
LP1_SCW_ext(i,j) = 1;
else
LP1_SCW_ext(i,j) = 0;
end
clear A_SCW B_SCW mA mB
end
end
LP1_SCW1 = LP1_SCW_ext(9:M1_ext-7,5:N1_ext-3);
imshow(LP1_SCW1,[]); % Show SCW segmentation for LP E
clear LP1_ext LP1_SCW_ext M1_ext N1_ext
subplot(2,1,2)
LP1_ext = horzcat(LP1_2(:,1:4),LP1_2,...
LP1_2(:,N1_ErA(cnt)-2:N1_ErA(cnt)));
LP1_ext = vertcat(LP1_ext(1:8,:),LP1_ext,...
LP1_ext(M1_ErA(cnt)-6:M1_ErA(cnt),:));
[M1_ext(cnt),N1_ext(cnt)] = size(LP1_ext);
for i = 9:M1_ext-7
for j = 5:N1_ext-3
A_SCW = LP1_ext(i-4:i+3,j-2:j+1);
B_SCW = LP1_ext(i-8:i+7,j-4:j+3);
mA = mean(mean(A_SCW));
mB = mean(mean(B_SCW));
if (mA/mB < TS)
LP1_SCW_ext(i,j) = 1;
else
LP1_SCW_ext(i,j) = 0;
end
clear A_SCW B_SCW mA mB
end
end
LP1_SCW2 = LP1_SCW_ext(9:M1_ext-7,5:N1_ext-3);
imshow(LP1_SCW2,[]); % Show SCW segmentation for LP A
clear LP1_ext LP1_SCW_ext M1_ext N1_ext
The resulting image is:
For the image inversion of regions E and A:
% 6 - Image Inversion:
%
% Each partition subjected to SCW segmentation is inverted to allow the
% characters to be in black and the background in white.
%
% Image inversion
figure(ob_cnt+8)
subplot(2,1,1)
LP1_in1 = ~LP1_SCW1;
imshow(LP1_in1,[]);
subplot(2,1,2)
LP1_in2 = ~LP1_SCW2;
imshow(LP1_in2,[]);
The resulting image is:
Before proceeding with the CCA for regions E and A, it is fundamental to find the parameter limits (just as in post # 30). The two parameters at hand are the orientation angle and the height of the character in each region.
The code for detecting the orientation angle limits is:
% Detecting Orientation Angles of Segmented Characters in LP
% This program detects the orientation angle of each of the segmented
% characters five studied license plates. First, the objects in each image
% is labelled with bwlabel (classical approach of connected component
% labeling with 8-connectivity), then the labeled matrix identifying the
% boarders of the license plates is used for calculating the orientation
% angle of the segmented characters,. This is calculated according to the
% equation:
% tan(phi_i) = 2[r_sum(c_sum(rcWi(r,c))]/[r_sum(c_sum(r^2Wi(r,c)) -
% r_sum(c_sum(c^2Wi(r,c))]
clear all
clc
ob_cnt = 0;
% Generating Gaussian mask to be used for blurring thresholded picture
% before performing object labeling
% sig = fix(randn*10); % Generating gradient of Gaussian masks for filtering
% % along x-axis (fx) and y-axis (fy)
% while (sig == 0)||(mod(sig,2)==0)||(abs(sig)>5)
% sig = fix(randn*10); % Ensure that masks formed are odd matrices
% end % each of whose size is no greater than 15x15
% sig = abs(sig); % Sigma should be positive
% After generating several Gaussian masks, best result obtained for sig = 1
sig = 1;
n = 3*sig;
for i=1:n
for j=1:n
g(i,j) = exp(-(i^2+j^2)/2*sig^2);
end
end
figure(ob_cnt+1)
I1 = imread('image 1.jpg'); % Importing picture of license plate 1
I1 = rgb2gray(I1);
imshow(I1,[]); % Show grayscale picture
[M1,N1] = size(I1);
figure(ob_cnt+2)
I_bin1 = edge(I1,'canny'); % Performing edge detection with Canny method
imshow(I_bin1,[]); % Show edge detection
figure(ob_cnt+3)
f1 = conv2(double(I_bin1),double(g));
f1 = f1(1:M1,1:N1);
[W1,num1] = bwlabel(f1,8); % Labeling with Matlab command bwlabel
imshow(W1,[]);
figure(ob_cnt+4)
% Extracting LP from middle section where expected to be
LP1 = W1(600:910,990:1500);
imshow(LP1,[]);
[M1,N1] = size(LP1);
for i = 1:M1
for j = 1:N1
rc_component1(i,j) = i*j*LP1(i,j);
end
end
for i = 1:M1
for j = 1:N1
r2_component1(i,j) = i^2*LP1(i,j);
end
end
for i = 1:M1
for j = 1:N1
c2_component1(i,j) = j^2*LP1(i,j);
end
end
phi1 = atand((2*sum(sum(rc_component1)))/...
(sum(sum(r2_component1))-sum(sum(c2_component1))))
%--------------------------------------------------------------------------
ob_cnt = ob_cnt + 4;
figure(ob_cnt+1)
I2 = imread('image 2.jpg'); % Importing picture of license plate 2
I2 = rgb2gray(I2);
imshow(I2,[]); % Show grayscale picture
[M2,N2] = size(I2);
figure(ob_cnt+2)
I_bin2 = edge(I2,'canny'); % Performing edge detection with Canny method
imshow(I_bin2,[]); % Show edge detection
figure(ob_cnt+3)
f2 = conv2(double(I_bin2),double(g));
f2 = f2(1:M2,1:N2);
[W2,num2] = bwlabel(f2,8); % Labeling with Matlab command bwlabel
imshow(W2,[]);
figure(ob_cnt+4)
% Extracting LP from middle section where expected to be
LP2 = W2(750:1100,900:1650);
imshow(LP2,[]);
[M2,N2] = size(LP2);
for i = 1:M2
for j = 1:N2
rc_component2(i,j) = i*j*LP2(i,j);
end
end
for i = 1:M2
for j = 1:N2
r2_component2(i,j) = i^2*LP2(i,j);
end
end
for i = 1:M2
for j = 1:N2
c2_component2(i,j) = j^2*LP2(i,j);
end
end
phi2 = atand((2*sum(sum(rc_component2)))/...
(sum(sum(r2_component2))-sum(sum(c2_component2))))
%--------------------------------------------------------------------------
ob_cnt = ob_cnt + 4;
figure(ob_cnt+1)
I3 = imread('image 3.jpg'); % Importing picture of license plate 3
I3 = rgb2gray(I3);
imshow(I3,[]); % Show grayscale picture
[M3,N3] = size(I3);
figure(ob_cnt+2)
I_bin3 = edge(I3,'canny'); % Performing edge detection with Canny method
imshow(I_bin3,[]); % Show edge detection
figure(ob_cnt+3)
f3 = conv2(double(I_bin3),double(g));
f3 = f3(1:M3,1:N3);
[W3,num3] = bwlabel(f3,8); % Labeling with Matlab command bwlabel
imshow(W3,[]);
figure(ob_cnt+4)
% Extracting LP from middle section where expected to be
LP3 = W3(700:1100,1100:1700);
imshow(LP3,[]);
[M3,N3] = size(LP3);
for i = 1:M3
for j = 1:N3
rc_component3(i,j) = i*j*LP3(i,j);
end
end
for i = 1:M3
for j = 1:N3
r2_component3(i,j) = i^2*LP3(i,j);
end
end
for i = 1:M3
for j = 1:N3
c2_component3(i,j) = j^2*LP3(i,j);
end
end
phi3 = atand((2*sum(sum(rc_component3)))/...
(sum(sum(r2_component3))-sum(sum(c2_component3))))
%--------------------------------------------------------------------------
ob_cnt = ob_cnt + 4;
figure(ob_cnt+1)
I4 = imread('image 4.jpg'); % Importing picture of license plate 4
I4 = rgb2gray(I4);
imshow(I4,[]); % Show grayscale picture
[M4,N4] = size(I4);
figure(ob_cnt+2)
I_bin4 = edge(I4,'canny'); % Performing edge detection with Canny method
imshow(I_bin4,[]); % Show edge detection
figure(ob_cnt+3)
f4 = conv2(double(I_bin4),double(g));
f4 = f4(1:M4,1:N4);
[W4,num4] = bwlabel(f4,8); % Labeling with Matlab command bwlabel
imshow(W4,[]);
figure(ob_cnt+4)
% Extracting LP from middle section where expected to be
LP4 = W4(620:1020,1000:1650);
imshow(LP4,[]);
[M4,N4] = size(LP4);
for i = 1:M4
for j = 1:N4
rc_component4(i,j) = i*j*LP4(i,j);
end
end
for i = 1:M4
for j = 1:N4
r2_component4(i,j) = i^2*LP4(i,j);
end
end
for i = 1:M4
for j = 1:N4
c2_component4(i,j) = j^2*LP4(i,j);
end
end
phi4 = atand((2*sum(sum(rc_component4)))/...
(sum(sum(r2_component4))-sum(sum(c2_component4))))
%--------------------------------------------------------------------------
ob_cnt = ob_cnt + 4;
figure(ob_cnt+1)
I5 = imread('image 5.jpg'); % Importing picture of license plate 5
I5 = rgb2gray(I5);
imshow(I5,[]); % Show grayscale picture
[M5,N5] = size(I5);
figure(ob_cnt+2)
I_bin5 = edge(I5,'canny'); % Performing edge detection with Canny method
imshow(I_bin5,[]); % Show edge detection
figure(ob_cnt+3)
f5 = conv2(double(I_bin5),double(g));
f5 = f5(1:M5,1:N5);
[W5,num5] = bwlabel(f5,8); % Labeling with Matlab command bwlabel
imshow(W5,[]);
figure(ob_cnt+4)
% Extracting LP from middle section where expected to be
LP5 = W5(600:1100,710:1850);
imshow(LP5,[]);
[M5,N5] = size(LP5);
for i = 1:M5
for j = 1:N5
rc_component5(i,j) = i*j*LP5(i,j);
end
end
for i = 1:M5
for j = 1:N5
r2_component5(i,j) = i^2*LP5(i,j);
end
end
for i = 1:M5
for j = 1:N5
c2_component5(i,j) = j^2*LP5(i,j);
end
end
phi5 = atand((2*sum(sum(rc_component5)))/...
(sum(sum(r2_component5))-sum(sum(c2_component5))))
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
The code for detecting the height limits is:
% Detecting Aspect Ratios of LP
% This program detects the height of each of the five studied license
% plates. First, the objects in each image is labelled with bwlabel
% (classical approach of connected component labeling with 8-connectivity),
% then the label(s) identifying the boarders of the license plates are
% used to extract the position coordinates. The height is then
% calculated according to the equation: rmax - rmin + 1.
clear all
clc
ob_cnt = 0;
% Generating Gaussian mask to be used for blurring thresholded picture
% before performing object labeling
% sig = fix(randn*10); % Generating gradient of Gaussian masks for filtering
% % along x-axis (fx) and y-axis (fy)
% while (sig == 0)||(mod(sig,2)==0)||(abs(sig)>5)
% sig = fix(randn*10); % Ensure that masks formed are odd matrices
% end % each of whose size is no greater than 15x15
% sig = abs(sig); % Sigma should be positive
% After generating several Gaussian masks, best result obtained for sig = 1
sig = 1;
n = 3*sig;
for i=1:n
for j=1:n
g(i,j) = exp(-(i^2+j^2)/2*sig^2);
end
end
figure(ob_cnt+1)
I1 = imread('image 1.jpg'); % Importing picture of license plate 1
I1 = rgb2gray(I1);
imshow(I1,[]); % Show grayscale picture
[M1,N1] = size(I1);
figure(ob_cnt+2)
I_bin1 = edge(I1,'canny'); % Performing edge detection with Canny method
imshow(I_bin1,[]); % Show edge detection
figure(ob_cnt+3)
f1 = conv2(double(I_bin1),double(g));
f1 = f1(1:M1,1:N1);
[W1,num1] = bwlabel(f1,8); % Labeling with Matlab command bwlabel
imshow(W1,[]);
figure(ob_cnt+4)
% Extracting LP from middle section where expected to be
imshow(W1(600:910,990:1500),[]);
figure(ob_cnt+5)
% Extracting character from LP
CS1 = W1(660:720,1080:1110);
imshow(CS1,[]);
r1_max = 720;
r1_min = 660;
h1 = r1_max - r1_min + 1
%--------------------------------------------------------------------------
ob_cnt = ob_cnt + 5;
figure(ob_cnt+1)
I2 = imread('image 2.jpg'); % Importing picture of license plate 2
I2 = rgb2gray(I2);
imshow(I2,[]); % Show grayscale picture
[M2,N2] = size(I2);
figure(ob_cnt+2)
I_bin2 = edge(I2,'canny'); % Performing edge detection with Canny method
imshow(I_bin2,[]); % Show edge detection
figure(ob_cnt+3)
f2 = conv2(double(I_bin2),double(g));
f2 = f2(1:M2,1:N2);
[W2,num2] = bwlabel(f2,8); % Labeling with Matlab command bwlabel
imshow(W2,[]);
figure(ob_cnt+4)
% Extracting LP from middle section where expected to be
imshow(W2(750:1100,900:1650),[]);
figure(ob_cnt+5)
% Extracting character from LP
CS2 = W2(780:880,1170:1210);
imshow(CS2,[]);
r2_max = 880;
r2_min = 780;
h2 = r2_max - r2_min + 1
%--------------------------------------------------------------------------
ob_cnt = ob_cnt + 5;
figure(ob_cnt+1)
I3 = imread('image 3.jpg'); % Importing picture of license plate 3
I3 = rgb2gray(I3);
imshow(I3,[]); % Show grayscale picture
[M3,N3] = size(I3);
figure(ob_cnt+2)
I_bin3 = edge(I3,'canny'); % Performing edge detection with Canny method
imshow(I_bin3,[]); % Show edge detection
figure(ob_cnt+3)
f3 = conv2(double(I_bin3),double(g));
f3 = f3(1:M3,1:N3);
[W3,num3] = bwlabel(f3,8); % Labeling with Matlab command bwlabel
imshow(W3,[]);
figure(ob_cnt+4)
% Extracting LP from middle section where expected to be
imshow(W3(700:1100,1100:1700),[]);
figure(ob_cnt+5)
% Extracting character from LP
CS3 = W3(785:870,1270:1340);
imshow(CS3,[]);
r3_max = 870;
r3_min = 785;
h3 = r3_max - r3_min + 1
%--------------------------------------------------------------------------
ob_cnt = ob_cnt + 5;
figure(ob_cnt+1)
I4 = imread('image 4.jpg'); % Importing picture of license plate 4
I4 = rgb2gray(I4);
imshow(I4,[]); % Show grayscale picture
[M4,N4] = size(I4);
figure(ob_cnt+2)
I_bin4 = edge(I4,'canny'); % Performing edge detection with Canny method
imshow(I_bin4,[]); % Show edge detection
figure(ob_cnt+3)
f4 = conv2(double(I_bin4),double(g));
f4 = f4(1:M4,1:N4);
[W4,num4] = bwlabel(f4,8); % Labeling with Matlab command bwlabel
imshow(W4,[]);
figure(ob_cnt+4)
% Extracting LP from middle section where expected to be
imshow(W4(620:1020,1000:1650),[]);
figure(ob_cnt+5)
% Extracting character from LP
CS4 = W4(675:770,1190:1260);
imshow(CS4,[]);
r4_max = 770;
r4_min = 675;
h4 = r4_max - r4_min + 1
%--------------------------------------------------------------------------
ob_cnt = ob_cnt + 5;
figure(ob_cnt+1)
I5 = imread('image 5.jpg'); % Importing picture of license plate 5
I5 = rgb2gray(I5);
imshow(I5,[]); % Show grayscale picture
[M5,N5] = size(I5);
figure(ob_cnt+2)
I_bin5 = edge(I5,'canny'); % Performing edge detection with Canny method
imshow(I_bin5,[]); % Show edge detection
figure(ob_cnt+3)
f5 = conv2(double(I_bin5),double(g));
f5 = f5(1:M5,1:N5);
[W5,num5] = bwlabel(f5,8); % Labeling with Matlab command bwlabel
imshow(W5,[]);
figure(ob_cnt+4)
% Extracting LP from middle section where expected to be
imshow(W5(600:1100,710:1850),[]);
figure(ob_cnt+5)
% Extracting character from LP
CS5 = W5(815:945,970:1025);
imshow(CS5,[]);
r5_max = 945;
r5_min = 815;
h5 = r5_max - r5_min + 1
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
An example of a segmented character would be:
After determining the CCA parameter limits, it's time to conduct the CCA and character counting on each of the regions E and A:
% 7 - CCA with Object Count:
%
% With labeling the image segments, the characters can be identified by
% restricting the orientation and height of the objects.
%
figure(ob_cnt+9)
% CCA on inverted form of LP SCW segmentation
subplot(2,1,1)
f11 = conv2(double(LP1_in1),double(g));
f11 = f11(1:M1_ErA(cnt),1:N1_ErA(cnt));
[W11,num11] = bwlabel(LP1_in1,8);
imshow(W11,[]);
subplot(2,1,2)
f12 = conv2(double(LP1_in2),double(g));
f12 = f12(1:M1_ErA(cnt),1:N1_ErA(cnt));
[W12,num12] = bwlabel(LP1_in2,8);
imshow(W12,[]);
figure(ob_cnt+10)
subplot(2,1,1)
cnt11 = 0;
for k = 1:num11 % Calculate orientation angle
L1 = zeros(M1_ErA(cnt),N1_ErA(cnt));
[r1,c1,v1] = find(W11==k);
label1 = vertcat(r1',c1');
for i = 1:size(label1,2)
L1(label1(1,i),label1(2,i)) = W11(label1(1,i),label1(2,i));
rc_component1(label1(1,i),label1(2,i)) = label1(1,i)*...
label1(2,i)*...
L1(label1(1,i),label1(2,i));
r2_component1(label1(1,i),label1(2,i)) = label1(1,i)^2*...
L1(label1(1,i),label1(2,i));
c2_component1(label1(1,i),label1(2,i)) = label1(2,i)^2*...
L1(label1(1,i),label1(2,i));
end
phi11(k) = atand((2*sum(sum(rc_component1)))/...
(sum(sum(r2_component1))-sum(sum(c2_component1))));
clear L1 r1 c1 v1 label1 rc_component1 r2_component1 c2_component1
end
for k = 1:num11 % Calculate height
L1 = zeros(M1_ErA(cnt),N1_ErA(cnt));
[r1,c1,v1] = find(W11==k);
label1 = vertcat(r1',c1');
r1_max = max(label1(1,:));
r1_min = min(label1(1,:));
h11(k) = r1_max - r1_min + 1;
clear r1 c1 v1 label1 r1_max r1_min
end
LP1_ob1 = zeros(M1_ErA(cnt),N1_ErA(cnt));
for k = 1:num11 % Retrieve objects with specific
% orientation angle and height
if (((phi11(k)+180) > 110)&&((phi11(k)+180) < 165))&&...
(h11(k) >= 50)
L1 = zeros(M1_ErA(cnt),N1_ErA(cnt));
[r1,c1,v1] = find(W11==k);
label1 = vertcat(r1',c1');
for i = 1:size(label1,2)
L1(label1(1,i),label1(2,i)) = W11(label1(1,i),label1(2,i));
end
for i = 1:length(label1)
LP1_ob1(label1(1,i),label1(2,i)) = L1(label1(1,i),label1(2,i));
end
cnt11 = cnt11 + 1;
clear L1 r1 c1 v1 label1
end
end
imshow(LP1_ob1,[]);
subplot(2,1,2)
cnt12 = 0;
for k = 1:num12 % Calculate orientation angle
L1 = zeros(M1_ErA(cnt),N1_ErA(cnt));
[r1,c1,v1] = find(W12==k);
label1 = vertcat(r1',c1');
for i = 1:size(label1,2)
L1(label1(1,i),label1(2,i)) = W12(label1(1,i),label1(2,i));
rc_component1(label1(1,i),label1(2,i)) = label1(1,i)*...
label1(2,i)*...
L1(label1(1,i),label1(2,i));
r2_component1(label1(1,i),label1(2,i)) = label1(1,i)^2*...
L1(label1(1,i),label1(2,i));
c2_component1(label1(1,i),label1(2,i)) = label1(2,i)^2*...
L1(label1(1,i),label1(2,i));
end
phi12(k) = atand((2*sum(sum(rc_component1)))/...
(sum(sum(r2_component1))-sum(sum(c2_component1))));
clear L1 r1 c1 v1 label1 rc_component1 r2_component1 c2_component1
end
for k = 1:num12 % Calculate height
L1 = zeros(M1_ErA(cnt),N1_ErA(cnt));
[r1,c1,v1] = find(W12==k);
label1 = vertcat(r1',c1');
r1_max = max(label1(1,:));
r1_min = min(label1(1,:));
h12(k) = r1_max - r1_min + 1;
clear r1 c1 v1 label1 r1_max r1_min
end
LP1_ob2 = zeros(M1_ErA(cnt),N1_ErA(cnt));
for k = 1:num12 % Retrieve objects with specific
% orientation angle and height
if (((phi12(k)+180) > 110)&&((phi12(k)+180) < 165))&&...
(h12(k) >= 50)
L1 = zeros(M1_ErA(cnt),N1_ErA(cnt));
[r1,c1,v1] = find(W12==k);
label1 = vertcat(r1',c1');
for i = 1:size(label1,2)
L1(label1(1,i),label1(2,i)) = W12(label1(1,i),label1(2,i));
end
for i = 1:length(label1)
LP1_ob2(label1(1,i),label1(2,i)) = L1(label1(1,i),label1(2,i));
end
cnt12 = cnt12 + 1;
clear L1 r1 c1 v1 label1
end
end
imshow(LP1_ob2,[]);
figure(ob_cnt+11)
subplot(2,1,1)
LP1_C1 = ~LP1_ob1;
imshow(LP1_C1,[]);
subplot(2,1,2)
LP1_C2 = ~LP1_ob2;
imshow(LP1_C2,[]);
The result of the CCA on the inverted regions E and A is:
After performing the object count (i.e. character count for each region E and A) and re-inverting the image to obtain the original grayscale shades, the following image is obtained:
For the character box-fitting of the characters on each region E and A:
% 8 - Character Box-Fitting:
%
% The row and column standard deviations are used on each character
% (object) to fit it into a box (character isolation with determined
% boundaries). The number of boxes (characters) is tracked with counter c.
%
% Character box-fitting
figure(ob_cnt+12)
R_STD_LP1_1 = std(LP1_C1');
C_STD_LP1_1 = std(LP1_C1);
subplot(2,2,1)
area(R_STD_LP1_1);
title('Row Standard Deviation of E in LP');
subplot(2,2,2)
area(C_STD_LP1_1);
title('Column Standard Deviation of E in LP');
R_STD_LP1_2 = std(LP1_C2');
C_STD_LP1_2 = std(LP1_C2);
subplot(2,2,3)
area(R_STD_LP1_2);
title('Row Standard Deviation of A in LP');
subplot(2,2,4)
area(C_STD_LP1_2);
title('Column Standard Deviation of A in LP');
figure(ob_cnt+13)
subplot(2,1,1)
LP1_F1 = zeros(M1_ErA(cnt),N1_ErA(cnt));
[r1, c1, v1] = find(C_STD_LP1_1>(sum(C_STD_LP1_1)/length(C_STD_LP1_1)));
label1 = vertcat(r1,c1);
for i = 1:size(label1,2)
LP1_F1(:,label1(2,i)) = LP1_C1(:,label1(2,i));
end
imshow(LP1_F1,[]);
clear r1 c1 v1 label1
subplot(2,1,2)
LP1_F2 = zeros(M1_ErA(cnt),N1_ErA(cnt));
[r1, c1, v1] = find(C_STD_LP1_2>(sum(C_STD_LP1_2)/length(C_STD_LP1_2)));
label1 = vertcat(r1,c1);
for i = 1:size(label1,2)
LP1_F2(:,label1(2,i)) = LP1_C2(:,label1(2,i));
end
imshow(LP1_F2,[]);
clear r1 c1 v1 label1
figure(ob_cnt+14)
R_STD_LP1_1up = std(LP1_F1');
C_STD_LP1_1up = std(LP1_F1);
subplot(2,2,1)
area(R_STD_LP1_1up);
title('Updated Row Standard Deviation of E in LP');
subplot(2,2,2)
area(C_STD_LP1_1up);
title('Updated Column Standard Deviation of E in LP');
R_STD_LP1_2up = std(LP1_F2');
C_STD_LP1_2up = std(LP1_F2);
subplot(2,2,3)
area(R_STD_LP1_2up);
title('Updated Row Standard Deviation of A in LP');
subplot(2,2,4)
area(C_STD_LP1_2up);
title('Updated Column Standard Deviation of A in LP');
figure(ob_cnt+15)
[r1, c1, v1] = find(C_STD_LP1_1up == 0);
for i = 2:length(c1)
horz_proj_LP1_1(i) = sum([C_STD_LP1_1up(i-1),C_STD_LP1_1up(i)]);
end
[r2, c2, v2] = find(horz_proj_LP1_1 ~= 0);
j = 1; % Dummy counter
for i = c2(1):c2(end)
CS_LP1_1(j) = c1(i);
j = j+1;
end
[r3, c3, v3] = find(c1 == CS_LP1_1(1));
CS_LP1_1 = horzcat(c1(c3-1),CS_LP1_1); % Inducing starting line of segmentation
clear r1 c1 v1 r2 c2 v2 r3 c3 v3 j
temp = CS_LP1_1;
clear CS_LP1_1
j = 2;
CS_LP1_1(1) = temp(1); % Same starting line of segmentation
for i = 2:length(temp)-1
if ((temp(i+1)-temp(i))<15)
CS_LP1_1(j) = temp(i+1);
else
CS_LP1_1(j) = temp(i);
j = j+1;
end
end
for i = 2:length(CS_LP1_1)
subplot(1,length(CS_LP1_1)-1,i-1)
imshow(LP1_F1(:,CS_LP1_1(i-1):CS_LP1_1(i)),[]);
end
clear temp horz_proj_LP1_1 j
figure(ob_cnt+16)
[r1, c1, v1] = find(C_STD_LP1_2up == 0);
for i = 2:length(c1)
horz_proj_LP1_2(i) = sum([C_STD_LP1_2up(i-1),C_STD_LP1_2up(i)]);
end
[r2, c2, v2] = find(horz_proj_LP1_2 ~= 0);
j = 1; % Dummy counter
for i = c2(1):c2(end)
CS_LP1_2(j) = c1(i);
j = j+1;
end
[r3, c3, v3] = find(c1 == CS_LP1_2(1));
CS_LP1_2 = horzcat(c1(c3-1),CS_LP1_2); % Inducing starting line of segmentation
clear r1 c1 v1 r2 c2 v2 r3 c3 v3 j
temp = CS_LP1_2;
clear CS_LP1_2
j = 2;
CS_LP1_2(1) = temp(1); % Same starting line of segmentation
for i = 2:length(temp)-1
if ((temp(i+1)-temp(i))<15)
CS_LP1_2(j) = temp(i+1);
else
CS_LP1_2(j) = temp(i);
j = j+1;
end
end
for i = 2:length(CS_LP1_2)
subplot(1,length(CS_LP1_2)-1,i-1)
imshow(LP1_F2(:,CS_LP1_2(i-1):CS_LP1_2(i)),[]);
end
clear temp horz_proj_LP1_2 j
The result of the first row and column standard deviation analysis is:
So the updated binary view of regions E and A would be:
The updated row and column standard deviation analysis is:
This would yield the following segmented characters for region E:
and for region A:
Seeing that the lovely hematology analyzer has finished its 4 hour cleaning cycle, this means I have to get back to work. Will continue this post later, stay tuned :)
Hi mesa!
Any news about this wonderful project?
:)