I want to detect a specific shape which is combination of 2 shapes Pentagon and a square. However side of a square should be around 3 times of a pentagon to match a valid shape as shown in the image.
I'm learning different image processing techniques for my requirement.
Contour Detection: Issue is knowing there are 7 corners is not enough as x : 3x need to be validated.
Haar features: Issue is images consist of background and there are text inside these object. So haar will not optimal method in my opinion.
My idea
I think may be I can detect lines corners and using side lengths I can do some math and identify the image.Is there any image processing technique that use mathematical distance, scale, location to identify object?
Original image
matching
not matching
Here's a simple approach:
Obtain binary image. Load image, convert to grayscale, Gaussian blur, then Otsu's threshold.
Filter for desired contour. We find contours then filter using a combination of contour approximation + contour area. With the observation that the shapes have a large area difference, we can use a predetermined threshold area to identify between the two.
Input ->
Binary image ->
Detected shape
Result
Match
Input ->
Binary image ->
Detected shape
Result
No Match
Since you didn't specify a language, I implemented in Python
import cv2
import numpy as np
# Load image, grayscale, Gaussian blur, Otsus threshold
image = cv2.imread('1.png')
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
blur = cv2.GaussianBlur(gray, (3,3), 0)
thresh = cv2.threshold(blur, 0, 255, cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU)[1]
# Find contours
cnts = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
cnts = cnts[0] if len(cnts) == 2 else cnts[1]
for c in cnts:
peri = cv2.arcLength(c, True)
approx = cv2.approxPolyDP(c, 0.04 * peri, True)
area = cv2.contourArea(c)
# Filter using contour approximation and area filtering (Remove small noise)
if len(approx) > 4 and len(approx) < 8 and area > 200:
# This is the larger version
if area >= 5500:
print('Match')
# Smaller version
elif area < 5500:
print('No Match')
cv2.drawContours(image, [c], -1, (255,0,12), 3)
cv2.imshow('thresh', thresh)
cv2.imshow('image', image)
cv2.waitKey()