3

I'm trying to extract the coordinates of a big white region in an image as follows: Here's the original image:

Original Image

Using a small square kernel, I applied a closing operation to fill small holes and help identify larger structures in the image as follows:

import cv2
import numpy as np
import imutils 

original = cv2.imread("Plates\\24.png")
original = cv2.resize(original, None, fx=3, fy=3, interpolation=cv2.INTER_CUBIC)
gray = cv2.cvtColor(original, cv2.COLOR_BGR2GRAY)
    
# next, find regions in the image that are light
squareKern = cv2.getStructuringElement(cv2.MORPH_RECT, (3, 3))
light = cv2.morphologyEx(gray, cv2.MORPH_CLOSE, squareKern)
light = cv2.threshold(light, 0, 255, cv2.THRESH_BINARY | cv2.THRESH_OTSU)[1]

the resulting image is as follows:

Resulting Image 1

Here's another example:

Resulting Image 2

What I wish to be able to do is to detect the large white region in the plate as follows:

Needed output

Keeping in mind that contours will not work well with many examples

7
  • Are you performing vehicle number plate detection and extraction ? Commented May 9, 2021 at 11:46
  • @KnowledgeGainer, Yes Commented May 9, 2021 at 11:55
  • 1
    This would help you : medium.com/programming-fever/… Commented May 9, 2021 at 11:57
  • Are the coordinates included in the original image? Commented May 9, 2021 at 13:15
  • I would suggest training a small CNN model, something like pertained yolov4-tiny would be perfect for this problem. Checkout this repo github.com/AlexeyAB/darknet Commented May 9, 2021 at 13:34

1 Answer 1

2

With the one image you provided:

enter image description here

I came up with 2 approaches as to how this problem can be solved:

Approach 1

Contour Area Comparison

As you can see there are 3 large contours in the image; the top rectangle and the two rectangles below it, of which you want to detect as a whole.

So I used a threshold on your image, detected the contours of the thresholded image, and indexed the second largest contour and the third largest contour (the largest is the top rectangle which you want to ignore).

Here is the thresholded image:

enter image description here

I stacked the two contours together and detected the bounding box of the two contours:

import cv2
import numpy as np

img = cv2.imread("image.png")

def process(img):
    img_gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    _, thresh = cv2.threshold(img_gray, 128, 255, cv2.THRESH_BINARY)
    img_blur = cv2.GaussianBlur(thresh, (5, 5), 2)
    img_canny = cv2.Canny(img_blur, 0, 0)
    return img_canny

def get_contours(img):
    contours, _ = cv2.findContours(process(img), cv2.RETR_TREE, cv2.CHAIN_APPROX_NONE)
    r1, r2 = sorted(contours, key=cv2.contourArea)[-3:-1]
    x, y, w, h = cv2.boundingRect(np.r_[r1, r2])
    cv2.rectangle(img, (x, y), (x + w, y + h), (0, 0, 255), 2)

get_contours(img)
cv2.imshow("img_processed", img)
cv2.waitKey(0)

Output:

enter image description here


Approach 2

Threshold Masking

As the 2 bottom rectangles are whiter than the top rectangle of the plate, I used a threshold to mask out the top of the plate:

enter image description here

I used the canny edge detector on the mask shown above.

import cv2

def process(img):
    img_gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
    _, thresh = cv2.threshold(img_gray, 163, 255, cv2.THRESH_BINARY)
    img_canny = cv2.Canny(thresh, 0, 0)
    img_dilate = cv2.dilate(img_canny, None, iterations=7)
    return cv2.erode(img_dilate, None, iterations=7)

def get_contours(img):
    contours, _ = cv2.findContours(process(img), cv2.RETR_TREE, cv2.CHAIN_APPROX_NONE)
    x, y, w, h = cv2.boundingRect(max(contours, key=cv2.contourArea))
    cv2.rectangle(img, (x, y), (x + w, y + h), (0, 0, 255), 2)

img = cv2.imread("egypt.png")
get_contours(img)
cv2.imshow("img_processed", img)
cv2.waitKey(0)

Output:

enter image description here

Of course, this method may not work properly if the top of the plate isn't brighter than the bottom.

Sign up to request clarification or add additional context in comments.

3 Comments

This answer is very detailed but sadly both approaches failed.
@MichaelCurrie Which image did you use?
Sorry - actually now I see you did detect the region the question wanted. But for my use case I need the entire white region including the top :D

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.