I have a (gray-scale) license plate image which looks like this:
The threshold image from which I took contours is this:
Now when I draw the contours which I have taken from the threshold image onto the original image I get this result:
At this point, everything is OK, I have a contour that is slightly uneven (it's not a perfect rectangle) and it is tilted. To fix the tilt I try to perform perspective transformation, but the problem is that the cv2.minAreaRect(contour) when drawn seems to return this (red outline), indicating that the tilt angle is zero, which it actually shows as -0.0:
Here is the code:
import numpy as np
import cv2
from imutils.perspective import order_points
clahe = cv2.createCLAHE(clipLimit=2.0, tileGridSize=(8,8))
def clean2_plate(plate):
equalized = clahe.apply(plate)
blurred = cv2.bilateralFilter(equalized, 11, 75, 75)
thresh_otsu = cv2.threshold(blurred, 0, 255, cv2.THRESH_BINARY | cv2.THRESH_OTSU)[1]
contours = cv2.findContours(thresh_otsu, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)[0]
contours = sorted(contours, key=cv2.contourArea, reverse=True)[:5]
for cnt in contours:
x, y, w, h = cv2.boundingRect(cnt)
final_img = plate[y:y+h, x:x+w]
if clean_ratio_check(w, h, debug): # if certain height-width conditions are met
return final_img, cnt
print("Plate cleaning failed!")
return plate_orig, None
def perspective_transformation(img, cnt, debug=False):
"""Perform perspective transformation for distorted license plates."""
hull = cv2.convexHull(cnt, returnPoints=True)
box = cv2.minAreaRect(hull)
box = cv2.boxPoints(box)
box = np.array(box, dtype="int")
src_pts = order_points(box)
# use Euclidean distance to get width & height
width = int(np.linalg.norm(src_pts[0] - src_pts[1]))
height = int(np.linalg.norm(src_pts[0] - src_pts[3]))
dst_pts = np.array([[0,0], [width,0], [width,height], [0,height]], dtype=np.float32)
M = cv2.getPerspectiveTransform(src_pts, dst_pts)
warped_img = cv2.warpPerspective(img, M, (width, height))
return warped_img
# MAIN
img = cv2.imread('input_img.png')
clean_plate, clean_cnt = clean2_plate(plate)
if clean_cnt is not None:
plate_rot = perspective_transformation(clean_plate, clean_cnt)
cv2_imshow(plate_rot)
My question is why the cv2.minAreaRect(contour) does not return an angle, as the image is visible tilted.




