Reputation: 43
I am not able to properly find the center of a triangle using openCV, the center point was drawn at the bottom tip of the triangle. Can anyone help me what is wrong in the code?
import cv2
import numpy as np
import stackImages as stack
img = cv2.imread('triangle.jpg',0)
NewImg = img.copy()
ret,thresh = cv2.threshold(img,127,255,0)
contours,hierarchy = cv2.findContours(thresh, 1, 2)
cnt = contours[0]
M = cv2.moments(cnt)
cx = int(M['m10']/M['m00'])
cy = int(M['m01']/M['m00'])
cv2.circle(NewImg, (cx, cy), 2, (0, 0, 255), 3)
cv2.putText(NewImg, "centroid", (cx, cy),cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 0, 255), 2)
while (True):
#imgStack = stack.stackImages(0.8,([img, NewImg]))
cv2.imshow('Sample', NewImg)
if cv2.waitKey(1) & 0xFF == ord('q'):
cv2.destroyAllWindows()
break
Upvotes: 2
Views: 188
Reputation: 4877
You may find multiple contours, and you want the one with the biggest area.
# Sort all contours by increasing area
contours_s = sorted(contours, key=cv2.contourArea)
# Find the second largest contour (the largest is the entire image
cnt = contours_s[-2]
copy = cv2.cvtColor(thresh, cv2.COLOR_GRAY2RGB)
cv2.drawContours(copy, [cnt], 0, (0, 0, 255))
cv2.imshow(copy)
Upvotes: 2
Reputation: 1619
If you want to have triangle as the largest contour to be returned, you can apply edge detection. Also its better to use grab_contours
from imutils
to avoid errors in getting the contours.
import cv2
import numpy as np
import imutils
img = cv2.imread('triangle.jpg',0)
NewImg = img.copy()
blur = cv2.GaussianBlur(img, (3, 3), 0)
edged = cv2.Canny(blur, 50, 200)
cnts = cv2.findContours(edged, cv2.RETR_LIST, cv2.CHAIN_APPROX_SIMPLE)
cnts = imutils.grab_contours(cnts)
cnt = sorted(cnts, key = cv2.contourArea, reverse = True)[0]
M = cv2.moments(cnt)
cx = int(M['m10']/M['m00'])
cy = int(M['m01']/M['m00'])
cv2.circle(NewImg, (cx, cy), 2, (0, 0, 255), 3)
cv2.putText(NewImg, "centroid", (cx, cy),cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 0, 255), 2)
while (True):
cv2.imshow('Sample', NewImg)
if cv2.waitKey(1) & 0xFF == ord('q'):
cv2.destroyAllWindows()
break
Upvotes: 1
Reputation: 4367
There is nothing wrong with your code. Just cos of you didn't choose the mode for findContours() and its choosing the default one and finding outer or some other contours. Just change your line with this:
contours,hierarchy = cv2.findContours(thresh,cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE)
Upvotes: 1
Reputation: 2191
In Opencv the object needs to be in white and the background black, so when you are applying threshold use cv2.THRESH_BINARY_INV
as the third argument.
Upvotes: 1