Shalin Shah
Shalin Shah

Reputation: 8183

Circular contour detection in an image python opencv

I am trying to have the circle detected in the following image.

enter image description here

So I did color thresholding and finally got this result.

enter image description here

Because of the lines in the center being removed, the circle is split into many small parts, so if I do contour detection on this, it can only give me each contour separately.

enter image description here

But is there a way I can somehow combine the contours so I could get a circle instead of just pieces of it?

Here is my code for color thresholding:

blurred = cv2.GaussianBlur(img, (9,9), 9)

ORANGE_MIN = np.array((12, 182, 221),np.uint8)
ORANGE_MAX = np.array((16, 227, 255),np.uint8)

hsv_disk = cv2.cvtColor(blurred,cv2.COLOR_BGR2HSV)
disk_threshed = cv2.inRange(hsv_disk, ORANGE_MIN, ORANGE_MAX)

Upvotes: 1

Views: 2603

Answers (2)

user1196549
user1196549

Reputation:

The task is much easier when performed with the red plane only.

enter image description here

Upvotes: 1

ZdaR
ZdaR

Reputation: 22954

I guess there was problem with the thresholds for color segmentation, So the idea here was to generate a binary mask. By inspection your region of interest seems to be brighter than the other regions of input image, so thresholding can simply be done on a grayScale image to simplify the context. Note: You may change this step as per your requirement. After satisfying with the threshold output, you may use cv2.convexHull() to get the convex shape of your contour.

Also keep in mind to select the largest contour and ignore the small contours. The following code can be used to generate the required output:

import cv2
import numpy as np

# Loading the input_image
img = cv2.imread("/Users/anmoluppal/Downloads/3xGG4.jpg")
# Converting the input image to grayScale
img_gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# Thresholding the image to get binary mask.
ret, img_thresh = cv2.threshold(img_gray, 145, 255, cv2.THRESH_BINARY)

# Dilating the mask image
kernel = np.ones((3,3),np.uint8)
dilation = cv2.dilate(img_thresh,kernel,iterations = 3)

# Getting all the contours
_, contours, __ = cv2.findContours(dilation, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)

# Finding the largest contour Id
largest_contour_area = 0
largest_contour_area_idx = 0

for i in xrange(len(contours)):
    if (cv2.contourArea(contours[i]) > largest_contour_area):
        largest_contour_area = cv2.contourArea(contours[i])
        largest_contour_area_idx = i

# Get the convex Hull for the largest contour
hull = cv2.convexHull(contours[largest_contour_area_idx])

# Drawing the contours for debugging purposes.
img = cv2.drawContours(img, [hull], 0, [0, 255, 0])
cv2.imwrite("./garbage.png", img) 

enter image description here

Upvotes: 0

Related Questions