How to extract a license plate from a black and white image
I have this homework where I have to extract a license plate from photographs of cars. I don't need to identify numbers and letters (this is a colleague's job). I have to do it in Matlab. I have already done the plate identification part, but now I cannot figure out how to correctly extract the license plate part from the picture.
You can see in the image below what I have done so far:
Now I don't know how to crop the white part, and moreover, it should be something like this:
I mean it has to rotate so that it falls into a horizontal position.
This is a project to be done by two people. The first one (i) must provide the second only the license plate from any images and the second one must use OCR. This is what the professor asked.
I'm out of ideas. The answer is probably simple, but I've been working all day and I can't seem to find a solution.
source to share
Note. The variables are in a different language, but I believe the code is readable as it is. I'm sorry, but right now I don't have time to work on this :(
Now this algorithm is not the best, but it is a starting point. I don't have time to work on this now, but it has certainly improved. For example, as seen in the pictures below, the license plate space is filled very nicely, but in some pictures, the last line of white pixels is not the same length as above and so you might end up with half the license plate. One solution might be: just before getting the corners of the license plate, make all the white lines the same length (with the length of the longest line).
BW = edge(rgb2gray(imagine), 'canny');
%# hough transform
[H T R] = hough(BW);
P = houghpeaks(H, 4, 'threshold',ceil(0.75*max(H(:))));
lines = houghlines(BW, T, R, P);
% shearing transformata
slopes = vertcat(lines.point2) - vertcat(lines.point1);
slopes = slopes(:,2) ./ slopes(:,1);
TFORM = maketform('affine', [1 -slopes(1) 0 ; 0 1 0 ; 0 0 1]);
imagine2 = imtransform(imagine, TFORM);
%# show image with lines overlayed, and the aligned/rotated image
axes(handles.ImagineRotita)
imshow(imagine2);
imagineGrey = rgb2gray(imagine2);
%-----------------------------------------------------------------
axes(handles.ImaginePrel1)
imshow(imagineGrey);
imagineFiltrata = medfilt2(imagineGrey,[3 3]);
axes(handles.ImagineFilt)
imshow(imagineFiltrata);
SE = strel('disk',1);
GrayDil = imdilate(imagineGrey,SE);
GrayEr = imerode(imagineGrey,SE);
gdiff = imsubtract(GrayDil,GrayEr);
gdiff = mat2gray(gdiff);
gdiff = conv2(gdiff,[1 1;1 1]);
gdiff = imadjust(gdiff,[0.5 0.7],[0 1],0.1);
B = logical(gdiff);
er = imerode(B,strel('line',50,0));
out1 = imsubtract(B,er);
imagineSobel = imfill(out1,'holes');
H = bwmorph(imagineSobel,'thin',1);
H = imerode(H,strel('line',3,90));
final = bwareaopen(H,100);
Iprops = regionprops(final,'BoundingBox','Image');
axes(handles.ImagineSobel)
imshow(final);
imagineCuratata = imclearborder(final,18);
imagineCuratata = bwareaopen(imagineCuratata,200);
axes(handles.ImagineSobelEd)
imshow(imagineCuratata);
fileID = fopen('ImagineRezultata.txt','wb');
dlmwrite('ImagineRezultata.txt',imagineCuratata);
fclose('all');
imagineCuratata2 = imagineCuratata;
[dimX,dimY] = size(imagineCuratata2);
%-----------------------------------------------------------------
%-----------The licence plate is filled with white pixels---------
PrimPixelAlbStanga = 0;
PrimPixelAlbDreapta = 0;
Flag = 0;
for i = 1:dimX
for j = 1:dimY
if Flag == 0
if imagineCuratata2(i,j) == 1
PrimPixelAlbStanga = j;
Flag = 1;
end
end
if Flag == 1
if imagineCuratata2(i,j) == 1
PrimPixelAlbDreapta = j;
end
end
end
if PrimPixelAlbStanga > 0
for k = PrimPixelAlbStanga:PrimPixelAlbDreapta
imagineCuratata2(i,k) = 1;
end
end
PrimPixelAlbStanga = 0;
PrimPixelAlbDreapta = 0;
Flag = 0;
end
%-----------------------------------------------------------------
%-----------------------------------------------------------------
%----------The smaller lines with white pixels are removed--------
%----------this is to eliminate all the smaller lines that--------
%--------------remained for example the logo sometimes------------
PrimPixelAlbStanga = 0;
PrimPixelAlbDreapta = 0;
Flag = 0;
for i = 1:dimX
for j = 1:dimY
if Flag == 0
if imagineCuratata2(i,j) == 1
PrimPixelAlbStanga = j;
Flag = 1;
end
end
if Flag == 1
if imagineCuratata2(i,j) == 1
PrimPixelAlbDreapta = j;
end
end
end
if PrimPixelAlbStanga > 0
if (PrimPixelAlbDreapta - PrimPixelAlbStanga) < 40
for k = PrimPixelAlbStanga:PrimPixelAlbDreapta
imagineCuratata2(i,k) = 0;
end
end
end
PrimPixelAlbStanga = 0;
PrimPixelAlbDreapta = 0;
Flag = 0;
end
axes(handles.ImagineCropata)
imshow(imagineCuratata2);
%-----------------------------------------------------------------
%-----------------------------------------------------------------
%---------the corners of the licence plate are determined---------
imagineCuratata2 = bwareaopen(imagineCuratata2,500);
PrimaCoordX = 0;
PrimaCoordY = 0;
UltimaCoordX = 0;
UltimaCoordY = 0;
determinat = 0;
for i = 1:dimX
for j = 1:dimY
if imagineCuratata2(i,j) == 1
if determinat == 0
PrimaCoordX = j;
PrimaCoordY = i;
determinat = 1;
else
UltimaCoordX = j;
UltimaCoordY = i;
end
end
end
end
PrimaCoordColX = 0;
PrimaCoordColY = 0;
UltimaCoordColX = 0;
UltimaCoordColY = 0;
determinatCol = 0;
for j = 1:dimY
for i = 1:dimX
if imagineCuratata2(i,j) == 1
if determinatCol == 0
PrimaCoordColX = j;
PrimaCoordColY = i;
determinatCol = 1;
else
UltimaCoordColX = j;
UltimaCoordColY = i;
end
end
end
end
xmin = 0;
ymin = 0;
width = 0;
height = 0;
if PrimaCoordX < dimX/2
xmin = PrimaCoordX;
ymin = PrimaCoordY;
else
xmin = PrimaCoordColX;
ymin = PrimaCoordY;
end
xmin = xmin - xmin * 0.1;
ymin = ymin * 1.1;
if PrimaCoordX < dimX/2
width = UltimaCoordX - PrimaCoordX;
height = UltimaCoordY - PrimaCoordY;
else
width = UltimaCoordColX - PrimaCoordColX;
height = UltimaCoordY - PrimaCoordY;
end
rect = [xmin ymin abs(width) abs(height)];
RezultatCropat = imcrop(imagine2, rect);
axes(handles.ImagineCropataSiFilt)
imshow(RezultatCropat);
end
The results of what I have done can be seen in these figures:
source to share
If you are trying to physically manipulate an image to create the final anti-aliased representation from any number of corner originals, this may not be the case.
If you have defined the slab boundary identification logic then you can trick it and then run it through the OCR application. This will give you some text, then you can just create a flat image with that text.
Now if you need to grab any graphics from a tablet as well, you will need to track down a database of all possible graphics and then code a compare / match routine so you can identify the license plate graphics, but then use your "flat" version from the database to create an anti-aliased image, which then outputs the OCR'd text.
For example, I only cleared the license plate and searched images.google.com (using the "search by image" functionality, I found many "flattened" versions of the image that you could use as your template.
source to share