taga
taga

Reputation: 3885

Extract numbers and letters from license plate image with Python OpenCV

I want to detect and then extract letters and numbers from this image. I have just started to learn OpenCV and I think that this can be done with that lib. You have the image that I used and desired output below. This is the code that I have:

import cv2

# read original image
img = cv2.imread('image.jpg')
cv2.imshow('original', img)
cv2.waitKey(0)


# convert it to gray and apply filter 
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) #convert to grey scale
gray = cv2.bilateralFilter(gray, 11, 17, 17)
cv2.imshow('gray', gray)
cv2.waitKey(0)

#apply treshold
thresh = cv2.threshold(gray, 10, 255, cv2.THRESH_OTSU)[1]
cv2.imshow('thresh', thresh)
cv2.waitKey(0)

This is the image:

enter image description here

My goal is to get separated images of each letter and number (I did this in paint):

enter image description here

So, what should I do to get this? It would be perfect to keep the same order of letters and numbers, for example:

MXF51051

Upvotes: 3

Views: 5732

Answers (1)

nathancy
nathancy

Reputation: 46620

Here's an approach using simple thresholding + contour filtering

  • Convert image to grayscale and Otsu's threshold
  • Find contours and filter using contour area
  • Extract and save ROI

We begin by converting to grayscale and then Otsu's threshold to obtain a binary image

enter image description here

Next we find contours using cv2.findContours(). To keep the same order of letters/numbers, we use imutils.contours.sort_contours() with the left-to-right parameter to ensure that when we iterate through the contours, we have each contour in the correct order. For each contour, we filter using a minimum and maximum area threshold to ensure that we only keep contours with the desired text. Once we have the filtered ROI, we extract/save the ROI using Numpy slicing. Here's the filtered mask with only the desired text

enter image description here

Detected numbers and letters

enter image description here

The extracted ROIs in the correct order

enter image description here

import cv2
import numpy as np
from imutils import contours

image = cv2.imread('1.jpg')
mask = np.zeros(image.shape, dtype=np.uint8)
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
thresh = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU)[1]

cnts = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
cnts = cnts[0] if len(cnts) == 2 else cnts[1]
(cnts, _) = contours.sort_contours(cnts, method="left-to-right")
ROI_number = 0
for c in cnts:
    area = cv2.contourArea(c)
    if area < 800 and area > 200:
        x,y,w,h = cv2.boundingRect(c)
        ROI = 255 - thresh[y:y+h, x:x+w]
        cv2.drawContours(mask, [c], -1, (255,255,255), -1)
        cv2.imwrite('ROI_{}.png'.format(ROI_number), ROI)
        ROI_number += 1

cv2.imshow('mask', mask)
cv2.imshow('thresh', thresh)
cv2.waitKey()

Upvotes: 5

Related Questions