Lodi
Lodi

Reputation: 580

Remove background from image of the same color of written content

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:

current-processed-license-plate

I need to achieve the final result below:

enter image description here

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

Answers (1)

fmw42
fmw42

Reputation: 53089

Here is one way in Python/OpenCV.

  • Read the input
  • Shave off 3 pixels all around to remove the white border
  • Pad back 3 black pixels plus 10 more black pixels all around as buffer for morphology, since white region is close to top edge of image
  • Convert to gray
  • Threshold
  • Apply morphology close to remove small black regions
  • Find contours
  • Draw a white filled contour on a black background for the largest contour as a mask
  • Use the mask to color the outer black regions of the thresholded image white
  • Save the results

Input:

enter image description here

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):

enter image description here

Mask image:

enter image description here

Result image:

enter image description here

Upvotes: 2

Related Questions