首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >旋转角度在fitEllipse方法中的实际位置在哪里?

旋转角度在fitEllipse方法中的实际位置在哪里?
EN

Data Science用户
提问于 2020-11-07 13:35:49
回答 1查看 1.9K关注 0票数 3

Main任务:我使用fitEllipse()方法对椭圆进行拟合,然后计算生成的椭圆的水平轴和长轴之间的旋转角。我将使用来自fitEllipse()方法的第三个返回参数- \theta (旋转角度)来完成这个任务。

Main问题:我无法找到这个角度位于哪个轴之间的确切信息。

其他:如果我是对的,小轴的长度和椭圆中的长轴的长度是相同的,就像旋转矩形中的两面一样。

来源

  1. 从文档在此( nb节)9)看,这个角度似乎介于水平轴和第一面之间,它是如何编写在CvBox2D剖面中的。所以,这意味着这个角度可以是水平轴和短轴或长轴之间的。但是:
  2. 在本条(第3节),第一个例子很好,但是在第二个例子中,角度应该在水平轴和高度之间,而不是宽度(参考前面提到的第一点)。
  3. 在本文中,它表明角在垂直轴与矩形的一侧之间。

So,fitEllipse()方法中的旋转角在哪里?

任何提示的工作方式都是受欢迎的。

EN

回答 1

Data Science用户

回答已采纳

发布于 2020-11-07 22:48:49

我实现了以下简单代码:

代码语言:javascript
复制
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)

我以这个图像为例:

我得到了以下图像结果:

每个椭圆的旋转角度是:

  1. 椭圆nb: 1有角: 55.63788986206055
  2. 椭圆nb: 2有角: 108.58539581298828
  3. 椭圆nb: 3有角: 170.23861694335938
  4. 椭圆nb: 4有角: 73.59089660644531

<#>So,我的结论是,在fitEllipse()方法中,垂直轴和长方形(=大椭圆轴)之间的角是旋转角。

增编

如果你从opencv-python如何定义轴(正x轴向右,正y轴向下)的角度看这个问题,那么这个角度是在水平轴和小椭圆直径之间定义的。为了演示这一点,在白色画布上绘制了不同的角度。

代码语言:javascript
复制
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返回的角度,也可以绘制拟合的椭圆的角度。

代码语言:javascript
复制
(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)

在这里,你可以看到,角度是在水平轴和小直径之间。记住每个椭圆的旋转角度:

  1. 椭圆nb: 1有角: 55.63788986206055
  2. 椭圆nb: 2有角: 108.58539581298828
  3. 椭圆nb: 3有角: 170.23861694335938
  4. 椭圆nb: 4有角: 73.59089660644531

结论

在opencv中,正x向右,正y在图像中向下,这意味着椭圆的旋转角最好是在正x轴和小椭圆直径之间(向正y轴向下)。

然而,如果你翻转轴(在你的头脑中),使正y轴向上,正x轴在图像的右边,那么你也可以解释椭圆旋转角度在正y轴和大椭圆直径之间(向正x轴的右边)。

票数 1
EN
页面原文内容由Data Science提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://datascience.stackexchange.com/questions/85064

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档