Main任务:我使用fitEllipse()方法对椭圆进行拟合,然后计算生成的椭圆的水平轴和长轴之间的旋转角。我将使用来自fitEllipse()方法的第三个返回参数- \theta (旋转角度)来完成这个任务。
Main问题:我无法找到这个角度位于哪个轴之间的确切信息。
其他:如果我是对的,小轴的长度和椭圆中的长轴的长度是相同的,就像旋转矩形中的两面一样。
来源:
So,fitEllipse()方法中的旋转角在哪里?
任何提示的工作方式都是受欢迎的。
发布于 2020-11-07 22:48:49
我实现了以下简单代码:
import cv2
import numpy as np
nr_im = 9876
font = cv2.FONT_HERSHEY_SIMPLEX
fontScale = 1
colorText = (0, 0, 255)
thickness = 2
img = cv2.imread('testing/' + str(nr_im) + '.jpg')
original = img.copy()
blured_img = cv2.GaussianBlur(img,(17,17),5)
image = cv2.cvtColor(img, cv2.COLOR_BGR2HSV)
lower = np.array([0, 0, 140], dtype="uint8")
upper = np.array([0, 0, 255], dtype="uint8")
mask = cv2.inRange(image, lower, upper)
# Morphological Closing: Get rid of the noise inside the object
mask = cv2.morphologyEx(mask, cv2.MORPH_CLOSE, cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (25, 25)))
# Find contours
cnts, _ = cv2.findContours(mask, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_NONE)
print(len(cnts))
cntsElps = []
for num_cnt, cnt in enumerate(cnts):
genEllipse= cv2.fitEllipse(cnt)
cntsElps.append(genEllipse)
cv2.ellipse(original,genEllipse,(0,255,0),2)
cv2.putText(original, str(num_cnt+1), (int(genEllipse[0][0]),int(genEllipse[0][1])), font, fontScale, colorText, thickness, cv2.LINE_AA)
print("Ellipse nb: " + str(num_cnt+1) + " has angle: " + str(genEllipse[2]) + "\n")
cv2.imwrite('testing/' + str(nr_im) + '_' + 'trash2' + '.png', original)我以这个图像为例:

我得到了以下图像结果:

每个椭圆的旋转角度是:
<#>So,我的结论是,在fitEllipse()方法中,垂直轴和长方形(=大椭圆轴)之间的角是旋转角。
如果你从opencv-python如何定义轴(正x轴向右,正y轴向下)的角度看这个问题,那么这个角度是在水平轴和小椭圆直径之间定义的。为了演示这一点,在白色画布上绘制了不同的角度。
import math
import cv2
import numpy as np
# create white canvas
img = np.zeros([512, 512, 3], dtype=np.uint8)
img.fill(255)
xc = 256
yc = 256
angles = list(range(0, 360, 30))
# radii = np.linspace(30, 200, len(angles))
radii = [175] * len(angles)
for idx, (angle, radius) in enumerate(zip(angles, radii)):
xtop = xc + math.cos(math.radians(angle)) * radius
ytop = yc + math.sin(math.radians(angle)) * radius
cv2.line(img, (int(xtop), int(ytop)), (int(xc), int(yc)), (0, 0, 255), 1)
# Put the contour index in the ellipse
cv2.putText(img, f'{round(math.radians(angle) / math.pi, 2)} pi', (int(xtop), int(ytop)),
cv2.FONT_HERSHEY_SIMPLEX, 0.6, (0, 0, 255),
2, cv2.LINE_AA)
cv2.imwrite('opencv_angles.jpg', img)
cv2.imshow('Definition of angle', img)
cv2.waitKey(0)
cv2.destroyAllWindows()
图像中的文本以弧度表示这条线的角度。
使用fitEllipse返回的角度,也可以绘制拟合的椭圆的角度。
(xc, yc), (width, height), angle = genEllipse
rminor = min(width, height) / 2
xtop = xc + math.cos(math.radians(angle)) * rminor
ytop = yc + math.sin(math.radians(angle)) * rminor
cv2.line(result, (int(xtop), int(ytop)), (int(xc), int(yc)), (0, 0, 255), 3)
在这里,你可以看到,角度是在水平轴和小直径之间。记住每个椭圆的旋转角度:
在opencv中,正x向右,正y在图像中向下,这意味着椭圆的旋转角最好是在正x轴和小椭圆直径之间(向正y轴向下)。
然而,如果你翻转轴(在你的头脑中),使正y轴向上,正x轴在图像的右边,那么你也可以解释椭圆旋转角度在正y轴和大椭圆直径之间(向正x轴的右边)。
https://datascience.stackexchange.com/questions/85064
复制相似问题