Reputation: 580
I need to process a license plate image directly from my webcam, using python with it's OpenCV library.
Currently I already achieved a certain point where I can recognize the license plate characters individually, but I still need to remove a background from the image.
This background have the same colour as the characters, so colour filters are not working so well. Besides from that, my image still needs some adjustments and cleaning, that my threshold morphologic alterations are not being able to process.
My current image is below:
I need to achieve the final result below:
I achieved this current lines of code, but with all my tentatives, argument modifications and applied filters, I still can't achieve my goal.
import cv2
cv2.imread("plate_from_webcam.png")
img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
(thresh, imgPB) = cv2.threshold(img, 156, 255, cv2.THRESH_BINARY)
kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (1, 2))
imgPB = cv2.morphologyEx(imgPB, cv2.MORPH_OPEN, kernel)
imgRoi = imgPB[y:y + h, x:x + w]
cv2.imshow("ROI", imgRoi)
What should be the next steps to achieve the desired results?
Upvotes: 0
Views: 720
Reputation: 53089
Here is one way in Python/OpenCV.
Input:
import cv2
import numpy as np
# read image
img = cv2.imread("license2.png")
hh, ww = img.shape[:2]
# shave off 3 pixels all around to remove outer white border
img = img[3:hh-3, 3:ww-3]
# pad 3 black pixels back all around plus another 10 all around as buffer for later morphology
img = cv2.copyMakeBorder(img, 13,13,13,13, cv2.BORDER_CONSTANT, (0,0,0))
# convert img to grayscale
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# threshold
thresh = cv2.threshold(gray,0,255,cv2.THRESH_BINARY)[1]
# apply morphology to remove small black spots
kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (7,7))
thresh = cv2.morphologyEx(thresh, cv2.MORPH_CLOSE, kernel)
hh2, ww2 = thresh.shape[:2]
# shave off 10 pixels all around
thresh = thresh[10:hh2-10, 10:ww2-10]
# get largest outer contour
cnts = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
cnts = cnts[0] if len(cnts) == 2 else cnts[1]
big_contour = max(cnts, key=cv2.contourArea)
# draw filled contour on black background
mask = np.zeros_like(thresh)
cv2.drawContours(mask, [big_contour], -1, (255), cv2.FILLED)
# use mask to make outside of thresholded license into white
# put white in result where mask is black
result = thresh.copy()
result[mask == 0] = 255
# write results
cv2.imwrite("license2_thresh.png", thresh)
cv2.imwrite("license2_mask.png", mask)
cv2.imwrite("license2_result.png", result)
# display it
cv2.imshow("thresh", thresh)
cv2.imshow("mask", mask)
cv2.imshow("result", result)
cv2.waitKey(0)
Thresholded image (after morphology processing):
Mask image:
Result image:
Upvotes: 2