'Quality of filtering with masks and contours cv2 for OCR car-plate recognition (HSV)
I have been trying for a while to read car-plates from a video collected from a camera. I have been successful insofar as building the Computer Vision algorithm to detect plates (I have used YOLOv5). Now the problem comes when I do have my bounding rectangle with the plate, and I do need to read the plate number through an OCR. I present as follows two different examples, highlighting the specific problem. I was wondering if there were any state-of-art methods to generalize the algorithm's ability to pick up plates with OCR. This HSV filter I am applying does not generalize well to all images (or at least my intuition says the problem should be that one).
In this one there is no problem whatsoever:
This one is the original one:
And this is the same algorithm as above applied in that:
Code follows (Using colab):
import numpy as np
from PIL import Image
import pytesseract
from google.colab.patches import cv2_imshow
import cv2
img_naples = np.array(Image.open(img_name))
x, y, widthbox, heightbox = bbox_plate
x_left = x
y_up = y
x_right = x+widthbox
y_down = y + heightbox
plate_naples_rgb = img_naples[y_up:y_down,x_left:x_right]
plate_naples_rgb = cv2.resize(
plate_naples_rgb, None, fx = 2, fy = 2,
interpolation = cv2.INTER_CUBIC)
result = np.zeros(plate_naples_rgb.shape, dtype=np.uint8)
#Application of HSV filtering
hsv = cv2.cvtColor(plate_naples_rgb, cv2.COLOR_BGR2HSV)
lower = np.array([0,13,21])
upper = np.array([176,111,110])
#Different upper bound filters trials
#(hMin = 0 , sMin = 0, vMin = 91), (hMax = 179 , sMax = 255, vMax = 255)
#(hMax = 131 , sMax = 126, vMax = 90)
mask = cv2.inRange(hsv, lower, upper)
# Perform morph close and merge for 3-channel ROI extraction
kernel = cv2.getStructuringElement(cv2.MORPH_RECT, (3,3))
close = cv2.morphologyEx(mask, cv2.MORPH_CLOSE, kernel, iterations=1)
extract = cv2.merge([close,close,close])
cnts = cv2.findContours(close, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
cnts = cnts[0] if len(cnts) == 2 else cnts[1]
for c in cnts:
x,y,w,h = cv2.boundingRect(c)
area = w * h
print('Area', area)
#if 100 < area < 500:
# cv2.rectangle(plate_naples_rgb, (x, y), (x + w, y + h), (36,255,12), 3)
# result[y:y+h, x:x+w] = extract[y:y+h, x:x+w]
# Invert image and throw into Pytesseract
invert = 255 - result
data = pytesseract.image_to_string(invert, lang='eng',config='--psm 6')
print(data)
cv2_imshow(plate_naples_rgb)
cv2_imshow(close)
cv2_imshow(result)
cv2_imshow(invert)
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|



