Reputation: 309
I am using cv2.fitEllipse()
to fit an ellipse over a contour. This function returns the center coordinates, major and minor axis, and rotation angle. I want to know if the rotation angle is the same as the angle of the major axis from the positive horizontal axis given here(src: Wikipedia):
If not, then is there any way to get the coefficients of the ellipse in the equation below:
and then directly compute the angle.
Upvotes: 2
Views: 10371
Reputation: 53089
This will show you about the fitEllipse angle in Python/OpenCV.
Input:
import cv2
import numpy as np
import math
# read input
img = cv2.imread('labrador2.jpg')
# convert to gray
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# threshold
thresh = cv2.threshold(gray, 100 , 255, cv2.THRESH_BINARY)[1]
# find largest contour
contours = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
contours = contours[0] if len(contours) == 2 else contours[1]
big_contour = max(contours, key=cv2.contourArea)
# fit contour to ellipse and get ellipse center, minor and major diameters and angle in degree
ellipse = cv2.fitEllipse(big_contour)
(xc,yc),(d1,d2),angle = ellipse
print(xc,yc,d1,d1,angle)
# draw ellipse in green
result = img.copy()
cv2.ellipse(result, ellipse, (0, 255, 0), 3)
# draw circle at center
xc, yc = ellipse[0]
cv2.circle(result, (int(xc),int(yc)), 10, (255, 255, 255), -1)
# draw major axis line in red
rmajor = max(d1,d2)/2
if angle > 90:
angle = angle - 90
else:
angle = angle + 90
print(angle)
x1 = xc + math.cos(math.radians(angle))*rmajor
y1 = yc + math.sin(math.radians(angle))*rmajor
x2 = xc + math.cos(math.radians(angle+180))*rmajor
y2 = yc + math.sin(math.radians(angle+180))*rmajor
cv2.line(result, (int(x1),int(y1)), (int(x2),int(y2)), (0, 0, 255), 3)
# draw minor axis line in blue
rminor = min(d1,d2)/2
if angle > 90:
angle = angle - 90
else:
angle = angle + 90
print(angle)
x1 = xc + math.cos(math.radians(angle))*rminor
y1 = yc + math.sin(math.radians(angle))*rminor
x2 = xc + math.cos(math.radians(angle+180))*rminor
y2 = yc + math.sin(math.radians(angle+180))*rminor
cv2.line(result, (int(x1),int(y1)), (int(x2),int(y2)), (255, 0, 0), 3)
cv2.imwrite("labrador2_ellipse.jpg", result)
cv2.imshow("labrador2_thresh", thresh)
cv2.imshow("labrador2_ellipse", result)
cv2.waitKey(0)
cv2.destroyAllWindows()
Result:
Upvotes: 10