0
votes

I am facing a contour problem, so that you can read the license plate in a correct way, it is best to take out the contours, and thus perhaps apply some OCR.

For example if I want to use this photo, you can see that on the axis it has a white outline, how could I eliminate those white outlines in a generic way? for can be used on more license plates

enter image description here

I am thinking of applying a threshold in the 2 axis (horizontally and vertically) again to clean possible white borders, any ideas?

A little what I'm have made:

# Creating copies of the original images
output_cp = output.copy()
img_cp = straightened.copy()

# threshold
ret,thresh = cv2.threshold(output_cp, 215, 255, cv2.THRESH_BINARY_INV)
imshow(thresh)

enter image description here

But then when It suposed to work, doesn't work because it is a binary image, pseudo-code, when xxx I don't know what contour apply:

mask = np.zeros(image.shape, np.uint8)
mask_cnt = cv2.drawContours(mask.copy(), [xxx], 0, (255,255,255,255), -1)
removed = cv2.subtract(mask_cnt, image)
plt.figure()
plt.imshow(removed, cmap='gray')

Any help is welcome!

1
On the axes ? What do you mean ?Yves Daoust
Sorry, I mean axis, X and YSebastián
Where are those axis ?Yves Daoust
Do you mean the last image i attached? the black lines represent the white outline of the image (horizontally), a mask was used so that the white of the original image is black as the backgroundSebastián
My question is about the axes.Yves Daoust

1 Answers

1
votes

To remove the white margin around the plate, you can :

This remove the margin and also correct the orientation of the plate which should make it much easier to read by any OCR.

Here is a python implementation of my solution:

#!/usr/bin/env python3
import numpy as np
import cv2

img = cv2.imread("plate.png")
gray = cv2.cvtColor(img, cv2.COLOR_RGB2GRAY)

# invert image and detect contours
inverted = cv2.bitwise_not(gray)
contours, hierarchy = cv2.findContours(inverted,cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)

# get the biggest contour
biggest_index = -1
biggest_area = -1
i = 0
for c in contours:
    area = cv2.contourArea(c)
    if area > biggest_area:
        biggest_area = area
        biggest_index = i
    i = i+1

print("biggest area: " + str(biggest_area) + " index: " + str(biggest_index))

cv2.drawContours(img, contours, biggest_index, [0,0,255])
center, size, angle = cv2.minAreaRect(contours[biggest_index])

rot_mat = cv2.getRotationMatrix2D(center, angle, 1.)

#cv2.warpPerspective()
print(size)
dst = cv2.warpAffine(gray, rot_mat, (int(size[0]), int(size[1])))

mask = dst * 0
x1 = max([int(center[0] - size[0] / 2)+1, 0])
y1 = max([int(center[1] - size[1] / 2)+1, 0])
x2 = int(center[0] + size[0] / 2)-1
y2 = int(center[1] + size[1] / 2)-1

point1 = (x1, y1)
point2 = (x2, y2)
print(point1)
print(point2)

cv2.rectangle(dst, point1, point2, [0,0,0])
cv2.rectangle(mask, point1, point2, [255,255,255], cv2.FILLED)

masked = cv2.bitwise_and(dst, mask)

cv2.imshow("img", img)
cv2.imshow("dst", dst)
cv2.imshow("masked", masked)
cv2.imshow("mask", mask)
key = -1;
while key != 27:
    key = cv2.waitKey(1)

And the resulting image : enter image description here

This is not perfect, but a good start I think, slightly different approche than thresholding.

You might also try to apply some morphological operator to close some gap or remove dirty parts.