正椭圆的外接矩形可以直接根据椭圆中心以及长短半轴确定,但一般的斜椭圆就要复杂一些,本文记录计算斜椭圆外接矩形的过程。
问题描述
如上述动图所示,给定一个一般但中心为原点的椭圆,长半轴 a, 短半轴 b,角度 alpha。
- 需要求得在给定 a,b,alpha 下椭圆的外接矩形,可以将问题简化为在给定数据下求图中 height 变量。
一般化方程
- 正椭圆方程为:
- 当顺时针旋转角度 alpha 后,x,y 值可以表示为:
- 带入正椭圆方程得到中心在原点的一般椭圆方程:
- 展开得到:
- 对此我们将该种类的椭圆方程一般化,有方程:
- 对应得到:
- 即我们讨论的椭圆方程总可以化成一般方程的形式,之后我们均在一般化方程基础上讨论解法
方法一
求解思路
- 需要解得 y 对 x 导数为 0 的点,取绝对值即可
解决方法
- 我们的目的是寻找 frac{partial y}{partial x} 为 0 的点,那么直接对 x 求偏导:
- 令 frac{partial y}{partial x} = 0,有:
- 不考虑 A = 0 的情况下:
- 带入一般方程:
- 得到高度:
方法二
解决思路
- 将一般方程的 y 看做常数,x 为自变量
- 如果解得 x,那么就相当于给定 y = t 的情况下,椭圆与该直线的交点 x 坐标
- 那么问题转化成了一元二次方程,当解的个数仅有一个的时候,直线 y=t与椭圆相切,也就是我们想要找的值
- height=|t|
解决方法
- 关于 x 的一元二次方程
- 解为:
- x 仅有1个解等价于:
- 与上一方法殊途同归:
python 实现
来自知乎大佬
- 函数输入为:
参数 | 含义 |
---|---|
major_radius | 主轴的半径 |
minor_radius | 短轴半径 |
angle | (顺时针)旋转角度 |
center_x | 中心点横坐标 |
center_y | 中心点纵坐标 |
- 首先是根据前三个函数输入得到椭圆参数方程的参数
'''
根据椭圆的主轴和次轴半径以及旋转角度(默认圆心在原点),得到椭圆参数方程的参数,
椭圆参数方程为:
A * x^2 B * x * y C * y^2 D = 0
'''
def get_ellipse_param(major_radius, minor_radius, angle):
a, b = major_radius, minor_radius
sin_theta = np.sin(-angle)
cos_theta = np.cos(-angle)
A = a**2 * sin_theta**2 b**2 * cos_theta**2
B = 2 * (a**2 - b**2) * sin_theta * cos_theta
C = a**2 * cos_theta**2 b**2 * sin_theta**2
F = -a**2 * b**2
return A, B, C, D
- 根据参数计算矩形框的值两个点的坐标:
'''
根据椭圆参数方程的参数,得到椭圆的外接矩形top-left和right-bottom坐标。
'''
def calculate_rectangle(A, B, C, D):
'''
椭圆上下外接点的纵坐标值
'''
y = np.sqrt(4*A*D / (B**2 - 4*A*C))
y1, y2 = -np.abs(y), np.abs(y)
'''
椭圆左右外接点的横坐标值
'''
x = np.sqrt(4*C*D / (B**2 - 4*C*A))
x1, x2 = -np.abs(x), np.abs(x)
return (x1, y1), (x2, y2)
- 综合两个函数
'''
按照数据集接口返回矩形框
'''
def get_rectangle(major_radius, minor_radius, angle, center_x, center_y):
A, B, C, D = get_ellipse_param(major_radius, minor_radius, angle)
p1, p2 = calculate_rectangle(A, B, C, D)
return (center_x p1[0], center_y p1[1]), (center_x p2[0], center_y p2[1])
mtutils 库
- python 中的 OpenCV 有输出斜椭圆的结构 ellipse
- 在库 mtutils 中的 ellipse2bbox 可以直接将该椭圆作为输入,得到外接矩形
from mtutils import ellipse2bbox
bbox = ellipse2bbox(ellipse)
参考资料
- https://zhuanlan.zhihu.com/p/82184417
- https://bbs.csdn.net/topics/390834307