python椭圆拟合 不用fitellipse
时间: 2023-07-07 21:46:17 浏览: 185
如果你不想使用`cv2.fitEllipse`函数,你可以使用numpy的线性代数库`np.linalg`和`np.polyfit`函数来拟合椭圆。
以下是一个简单的示例代码:
```python
import cv2
import numpy as np
# 读取图像
img = cv2.imread('ellipse.png')
# 转换为灰度图像
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# 二值化处理
ret, thresh = cv2.threshold(gray, 127, 255, cv2.THRESH_BINARY)
# 查找轮廓
contours, hierarchy = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
# 获取第一个轮廓
cnt = contours[0]
# 获取椭圆拟合的参数
(x, y), (MA, ma), angle = cv2.fitEllipse(cnt)
# 将轮廓转换为(x,y)坐标数组
coord = cnt[:, 0, :]
# 将坐标系平移至拟合椭圆的中心
x0, y0 = x, y
coord[:, 0] -= x0
coord[:, 1] -= y0
# 计算椭圆的旋转角度
theta = np.deg2rad(angle)
# 构造系数矩阵
D = np.vstack([coord[:, 0] ** 2, coord[:, 0] * coord[:, 1], coord[:, 1] ** 2]).T
# 构造常数矩阵
B = np.ones((coord.shape[0], 1))
# 使用最小二乘法求解系数向量
C = np.linalg.lstsq(D, B, rcond=None)[0]
# 将系数向量转换为参数向量
a = C[0, 0]
b = C[1, 0] / 2
c = C[2, 0]
d = -1
# 计算椭圆的长轴和短轴长度
delta = np.sqrt(b ** 2 - a * c)
MA_new = np.sqrt(2 * (a + c + delta))
ma_new = np.sqrt(2 * (a + c - delta))
# 计算椭圆的旋转角度
if b == 0:
angle_new = 0
elif a > c:
angle_new = np.arctan(2 * b / (a - c)) / 2
else:
angle_new = np.pi / 2 + np.arctan(2 * b / (a - c)) / 2
# 将椭圆的参数转换回原始坐标系
x_new, y_new = x0, y0
theta_new = -np.rad2deg(angle_new)
MA_new, ma_new = int(MA_new), int(ma_new)
# 绘制拟合得到的椭圆
cv2.ellipse(img, (int(x_new), int(y_new)), (MA_new, ma_new), theta_new, 0, 360, (0, 255, 0), 2)
# 显示结果
cv2.imshow('Ellipse Fitting', img)
cv2.waitKey(0)
cv2.destroyAllWindows()
```
在这个示例代码中,我们首先读取了一张图像,然后将其转换为灰度图像并进行二值化处理。接下来,我们使用`cv2.findContours`函数查找图像中的轮廓,并获取第一个轮廓。然后,我们使用`cv2.fitEllipse`函数获取椭圆拟合的参数。
接着,我们将轮廓的坐标系平移至拟合椭圆的中心,并计算椭圆的旋转角度。然后,我们构造系数矩阵和常数矩阵,并使用最小二乘法求解系数向量。最后,我们将系数向量转换为椭圆的参数向量,并将其转换回原始坐标系。最后,我们使用`cv2.ellipse`函数绘制拟合得到的椭圆,并显示结果。
阅读全文