基于Python实现椭圆拟合

资源下载地址:https://download.csdn.net/download/sheziqiong/85836974
资源下载地址:https://download.csdn.net/download/sheziqiong/85836974

椭圆拟合

实验目的和要求

尝试使用 cv.fitEllipse()函数,对图像进行椭圆拟合

实验内容和原理

椭圆拟合

该函数使用的是最小二乘法拟合,要求输入的点至少有 6 个。

函数中对应的参数如下:

对输入图像的预处理

输入一张 RGB 图片,先转换为灰度图,本来打算先转换为二值图像再进行边缘检测的,但是发现二值化容易使阴影成为新的边缘,并丢失原有边缘信息,于是直接对灰度图进行了边缘检测。在边缘检测前还进行了降噪

边缘检测

用 Sobel Kernel 进行滤波,来计算 x 和 y 方向的导数。

对于每个像素,检测它是否为局部最大值,如果不是就设置为 0

输入的两个参数为 min 和 max,用来限定寻找的边缘范围(大于 max 的肯定是边缘,小于 min 的肯定不是,在 min 和 max 之间的则通过判断连通性等方式来判断。

实验步骤与分析

读入图片

读入后先去掉高频的信息(降噪)。然后保存一个 RGB 图像信息,存储一个 gray 灰度图信息。边缘信息 edge 直接从 gray 中提取,min 取到 100,max 取到 200。

FILENAME = "dota2items4.bmp"
img = cv.imread(FILENAME)
img = cv.GaussianBlur(img, (5, 5), 0)
rgb = cv.cvtColor(img, cv.COLOR_BGR2RGB)
gray = cv.cvtColor(img, cv.COLOR_BGR2GRAY)
# _, thresh = cv.threshold(gray, 130, 255, cv.THRESH_BINARY + cv.THRESH_OTSU)
edge = cv.Canny(gray, 100, 200)

使用 fitEllipse()函数

Ells 数组储存椭圆信息,recs 储存可以旋转的最小矩阵,recs2 储存正矩形信息。Cols 用于储存随机生成的颜色信息,方便区分不同椭圆和矩阵之间的对应关系

img = rgb
edge_ = cv.cvtColor(edge, cv.COLOR_GRAY2RGB)
ells = []
recs = []
recs2 = []
cols = []
contours, nothing = cv.findContours(edge, cv.RETR_TREE, cv.CHAIN_APPROX_SIMPLE)
for index, contour in enumerate(contours):
    if contour.shape[0] > 50:
        ells.append(cv.fitEllipse(contour))
        recs2.append(cv.boundingRect(contour))
        recs.append(cv.minAreaRect(contour))

random.seed(10)
for i in range(len(ells)):
    cols.append([random.randint(0, 256) for j in range(3)])

绘制椭圆与矩形

同时在 RGB 图像和边缘图像中绘制,这是椭圆

for index, ell in enumerate(ells):
        cv.ellipse(img, ell, cols[index], 2)
        cv.ellipse(edge_, ell, cols[index], 2)

这是可旋转的矩形

for index, rec in enumerate(recs):
    box = cv.boxPoints(rec) # cv2.boxPoints(rect) for OpenCV 3.x
    box = np.int0(box)
    cv.drawContours(img,[box],0,cols[index],1)
    cv.drawContours(edge_,[box],0,cols[index],1)

绘制正矩形

for index, rec2 in enumerate(recs2):
    x,y,w,h = rec2
    cv.rectangle(img,(x,y),(x+w,y+h),cols[index],1)
    cv.rectangle(edge_,(x,y),(x+w,y+h),cols[index],1)

实验结果

输入图像

图里左上角的 Hyper stone 具有很多同心圆信息,右上的 Clarity 有不规则曲线和直线信息,右下的 Tango 有圆形信息且整体外形近似椭圆,正下方的 Force Staff 有近似的圆形信息和直线。

输出:

  • RGB

图像因为进行过高斯滤波而稍微模糊

  • GrayScale

  • Thresh

可以看出,二值化后的图像失去了很多细节信息,同时引入了阴影的边缘信息,这是我们不太想要的

  • Edge

根据灰度图生成了图像的边缘信息

Ellipse on Edge

大部分边缘信息拟合良好,但是图中红色箭头标出的浅蓝色椭圆很奇怪,通过分析,它对应的 contour 是左边浅蓝色矩形内部的信息,并不知道为什么会发生这样的事,也许是 bug?(这个现象同样在 Lena 图片中出现,根据搜索到的信息,可能是最小二乘法造成的问题)

下图为 Lena 照片下半部分,看得出左边深蓝色矩阵和右边的椭圆对应,但并没有任何重合。

Ellipse on RGB

看得出,那个浅蓝色椭圆与整个图片格格不入

心得体会

本来想直接用那种波点图像就算了,看见同学做了对奇怪的游戏 CG 的拟合,于是考虑到继续使用 Lena 姐姐的照片,但是羽毛帽的细节信息太多,导致效果并不十分好。于是找了 DOTA2 的物品图标(虽然效果很好,但是分辨率实在太低,于是找了二次创作的高清图像,效果还不错,各种情况下的效果都能看见)

比如这里非常标准的椭圆

这里对形状近似的物体的拟合

这个粉色应该是在拟合瓶子的左下边缘。

通过调大拟合时使用的点的数量阈值以及画的线的粗细,可以删除一些不靠谱的结果,防止出现一大团乱七八糟的线 的效果(如下)

(对应的其实是)


)]

这个粉色应该是在拟合瓶子的左下边缘。

资源下载地址:https://download.csdn.net/download/sheziqiong/85836974
资源下载地址:https://download.csdn.net/download/sheziqiong/85836974

  • 4
    点赞
  • 34
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 1
    评论
### 回答1: Python中可以使用scipy库中的插值函数和numpy库中的最小二乘法函数来曲面。 1.使用插值函数 插值函数可以根据给定的散点数据,计算出一个曲面,可以利用scipy.interpolate库中的interp2d或interp2d类函数进行二维插值。 例如,可以使用以下代码进行二维线性插值: ```python import numpy as np from scipy.interpolate import interp2d x = np.array([0, 1, 2, 3]) y = np.array([0, 1, 2, 3]) z = np.array([[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12], [13, 14, 15, 16]]) f = interp2d(x, y, z, kind='linear') xnew = np.linspace(0, 3, 10) ynew = np.linspace(0, 3, 10) znew = f(xnew, ynew) ``` 其中,x,y,z分别为数据的散点坐标和值。kind参数指定插值方法,此处采用线性插值。f是二维插值函数,可以通过f(xnew,ynew)来计算曲面的值。 2.使用最小二乘法 最小二乘法是一种常用的曲面方法,可以使用numpy库中的polyfit函数进行多项式,也可以使用curve_fit函数进行非线性。 例如,使用多项式可以使用以下代码: ```python import numpy as np import matplotlib.pyplot as plt x = np.array([0, 1, 2, 3, 4, 5]) y = np.array([0, 1, 3, 5, 7, 9]) z = np.polyfit(x, y, 2) p = np.poly1d(z) xp = np.linspace(0, 5, 100) plt.plot(x, y, '.', xp, p(xp), '-') plt.show() ``` 其中,x,y为数据的散点坐标,z为多项式的系数,p是一个多项式函数,xp为曲线的横坐标。 最小二乘法也可以用于非线性,例如使用scipy库中的curve_fit函数: ```python import numpy as np import matplotlib.pyplot as plt from scipy.optimize import curve_fit def func(x, a, b, c): return a * np.exp(-b * x) + c x = np.linspace(0, 4, 50) y = func(x, 2.5, 1.3, 0.5) yn = y + 0.2 * np.random.normal(size=len(x)) popt, pcov = curve_fit(func, x, yn) plt.plot(x, yn, 'b-', label='data') plt.plot(x, func(x, *popt), 'r-', label='fit') plt.legend() plt.show() ``` 其中,func函数为的函数,popt为函数的参数,pcov为参数的协方差矩阵,可以用于计算误差等信息。 ### 回答2: Python可以通过使用Scipy库中的多项式函数来实现散点曲面。具体实现方法如下: 1. 引入需要的库 在Python中打开一个新的文件或者打开一个Python环境,首先需要引入需要的库,如下所示: import numpy as np from scipy import optimize import matplotlib.pyplot as plt 2. 准备数据点 将需要的数据点按照自变量和因变量分别存储在一个列表或数组中,如下所示: x = np.array([0.2, 0.4, 0.6, 0.8, 1.0]) y = np.array([0.6, 0.8, 1.0, 1.2, 1.4]) z = np.array([0.8, 0.9, 1.1, 1.3, 1.5]) 3. 曲面 使用多项式函数进行曲面,如下所示: def fit_func(params, x, y): a, b, c, d, e, f = params return a * x**2 + b * y**2 + c * x * y + d * x + e * y + f def err_func(params, x, y, z): return fit_func(params, x, y) - z p0 = np.array([1, 1, 1, 1, 1, 1]) p, success = optimize.leastsq(err_func, p0, args=(x, y, z)) 4. 绘制曲面 通过绘制多个散点的方式,将曲面可视化,如下所示: fig = plt.figure() ax = fig.add_subplot(111, projection='3d') xs, ys = np.meshgrid(x, y) zs = fit_func(p, xs, ys) ax.scatter(x, y, z, color='red', marker='o') ax.plot_surface(xs, ys, zs, rstride=1, cstride=1, color='green', alpha=0.5) ax.set_xlabel('X Label') ax.set_ylabel('Y Label') ax.set_zlabel('Z Label') plt.show() 绘制的散点图显示了曲面和原始数据点之间的比较。如果散点图显示曲面和数据点间距离较大,可能需要提高多项式函数的阶数或者使用其他方法进行优化。 ### 回答3: 散点曲面是一种在三维空间内对离散点进行曲面的方法。Python语言具有强大的科学计算功能,可以方便地实现散点曲面的计算工作。其基本步骤包括: 1. 导入必要的库 在Python中进行散点曲面需要引入3个库:numpy、matplotlib、scipy。其中,numpy库用于计算向量矩阵,matplotlib库用于可视化结果,scipy库提供了曲面的函数库。 2. 加载数据 需要首先加载数据,将离散的散点数据读取进来,存储为一个二维数组。在Python中,可以使用numpy.loadtxt()函数读取数据。 3. 生成对象 在Python中,需要根据散点数据生成对象,可以使用scipy库中的ndimage.map_coordinates()函数生成。该函数会在空间内生成一组网格点,对象可以接受网格点上的离散点,进行曲面操作。 4. 进行曲面 通过调用对象的fit()函数,传入离散点数据,进行曲面操作。Python中提供了多种曲面函数,如二次曲面、三次曲面等。具体的函数可以根据需求进行选择。 5. 可视化结果 在Python中,可以使用matplotlib库将结果进行可视化。可以使用scatter()函数绘制原始散点数据,使用plot_surface()函数绘制结果曲面。 总结起来,Python通过numpy、matplotlib、scipy三个库的协调使用,可以简单实现散点曲面的计算。虽然Python在科学计算领域上表现出色,但是在使用过程中还需要注意掌握相关的科学计算知识,以及掌握基本的Python编程语言基础。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

shejizuopin

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值