Ha Bom
Ha Bom

Reputation: 2917

cv2.findContours() acts strangely?

I'm finding contours in an image. With every contour I found, I print out its bouding rect and area and then draw it to the image. Funnily, I found that 5 contours that have been drawed while there were only 4 contours printed. Anyone knows what happened here?

>>contour 1
>>(0, 0, 314, 326)
>>101538.5
>>contour 2
>>(75, 117, 60, 4)
>>172.0
>>contour 3
>>(216, 106, 3, 64)
>>124.0
>>contour 4
>>(62, 18, 138, 9)
>>383.5

enter image description here enter image description here

import cv2 
import numpy as np

img = cv2.imread('1.png')

imgray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
ret,thresh = cv2.threshold(imgray,127,255,0)

_, contours, hier = cv2.findContours(thresh, cv2.RETR_TREE, 
cv2.CHAIN_APPROX_SIMPLE)

for i,c in enumerate(contours):
    rect = cv2.boundingRect(c)
    area = cv2.contourArea(c)
    print("contour " + str(i+1))
    print(rect)
    print(area)

cv2.drawContours(img, contours, -1, (0,255,0), 1)

cv2.imshow('img', img)
cv2.waitKey(0)
cv2.destroyAllWindows()

Upvotes: 1

Views: 228

Answers (1)

Ishara Dayarathna
Ishara Dayarathna

Reputation: 3611

cv2.RETR_TREE is the reason you are getting this. It retrieves all the contours and creates a full family hierarchy list. In contour detection you are expected to use white objects in black background. Otherwise because of hierarchy list you would get results as you are getting now. For more details check documentation.

So make sure you find contours of white objects in black background. Add cv2.bitwise_not() function to convert the image.

. . .

imgray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
cv2.bitwise_not(imgray,imgray)

. . .

OUTPUT:

4
contour 1
(76, 118, 58, 2)
56.0
contour 2
(217, 107, 1, 62)
0.0
contour 3
(63, 19, 136, 7)
110.5
contour 4
(248, 1, 66, 45)
55.5

Upvotes: 1

Related Questions