TrialAndError
TrialAndError

Reputation: 87

Find Contours not accurate

I have a question to find the contours of this image I've used the findcontour is not very accurate am I doing wrong ?

Here's my result but its not accurate.

Here's the image I've used

gs = cv2.cvtColor(img,cv2.COLOR_RGB2GRAY)
blur = cv2.GaussianBlur(gs, (3,3),0)
ret_otsu,im_bw_otsu = cv2.threshold(blur,0,255,cv2.THRESH_BINARY_INV+cv2.THRESH_OTSU)

kernel = np.ones((50,50),np.uint8)
closing = cv2.morphologyEx(im_bw_otsu, cv2.MORPH_CLOSE, kernel)
_, contours, hierarchy = cv2.findContours(closing,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)

plottedContour = cv2.drawContours(gs,contours,-1,(0,255,0),2)
cv2.imshow('CONTOUR',plottedContour)

Upvotes: 2

Views: 1040

Answers (2)

nathancy
nathancy

Reputation: 46600

The idea is to obtain a binary image the filter for the largest contour with the assumption that the banana is the main object in the image. From here we can draw a rectangle using cv2.rectangle or draw around the contour with cv2.drawContours. Optionally, we can also crop the ROI using Numpy slicing.

Drawn rectangle

enter image description here

Drawn contour

enter image description here

Extracted ROI

enter image description here

Code

import cv2

# Load image, grayscale, blur, Otsu's threshold
image = cv2.imread('1.jpg')
original = image.copy()
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 and sort for largest contour
cnts = cv2.findContours(thresh, cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)
cnts = cnts[0] if len(cnts) == 2 else cnts[1]
cnts = sorted(cnts, key=cv2.contourArea, reverse=True)

for c in cnts:
    # Crop ROI
    x,y,w,h = cv2.boundingRect(c)
    ROI = original[y:y+h, x:x+w]
    cv2.imwrite('ROI.png', ROI)

    # Draw rectangle
    cv2.rectangle(image, (x, y), (x + w, y + h), (36,255,12), 2)

    # Draw contours
    # cv2.drawContours(image, [c], -1, (36,255,12), 2)
    break

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

Upvotes: 1

kpie
kpie

Reputation: 11080

Looks like you might want to look at additional contours,

cv2.drawContours(gs,contours,-1,(0,255,0),2)
cv2.drawContours(gs,contours,0,(0,255,0),2)
cv2.drawContours(gs,contours,1,(0,255,0),2)
cv2.drawContours(gs,contours,2,(0,255,0),2)
...

Upvotes: 1

Related Questions