OpenCV(24-6):图像轮廓之六:椭圆拟合和直线拟合
椭圆拟合法的基本思路是:对于给定平面上的一组样本点,寻找一个椭圆,使其尽可能接近这些样本点。也就是说,将图像中的一组数据以椭圆方程为模型进行拟合,使某一椭圆方程尽量满足这些数据,并求出该椭圆方程的各个参数。在OpenCV中,函数cv2.fitEllipse()可以用来构建最优拟合椭圆,还可以在返回值内分别返回椭圆的中心点,轴长,旋转角度信息。就椭圆拟合而言,就是先假设椭圆参数,得到每个待拟合点到该
24.8 椭圆拟合和直线拟合
cv2.ellipse()椭圆拟合 (方向)
椭圆拟合法的基本思路是:对于给定平面上的一组样本点,寻找一个椭圆,使其尽可能接近这些样本点。也就是说,将图像中的一组数据以椭圆方程为模型进行拟合,使某一椭圆方程尽量满足这些数据,并求出该椭圆方程的各个参数。
就椭圆拟合而言,就是先假设椭圆参数,得到每个待拟合点到该椭圆的距离之和,也就是点到假设椭圆的误差,求出使这个和最小的参数。
在OpenCV中,函数cv2.fitEllipse()可以用来构建最优拟合椭圆,还可以在返回值内分别返回椭圆的中心点,轴长,旋转角度信息。使用这种形式,能够直观地获取椭圆的方向等信息。
函数原型:
(x,y),(MA,ma),angle = cv2.ellipse(points)
ellipse = cv2.ellipse(points)
参数:
- points: 待拟合直线的点的集合,可以是检测处理轮廓结果
返回值:
- ellopse:椭圆
- (x,y):椭圆的中心点,(MA,ma):椭圆水平方向轴与垂直方向轴的长度,angle:椭圆的旋转角度
cv2.fitLine()直线拟合
直线拟合就是将图像中的对象拟合成一条直线过程,在OPenCV中拟合直线的API是:
函数原型:output = cv2.fitLine(points, distType, param, reps, aeps)
参数:
- points: 待拟合直线的点的集合,可以是检测处理轮廓结果
- distType: 距离公式,在进行拟合是,要使输入点到拟合直线的距离之和最小,常用的用以下几种:cv2.DIST_L1: 曼哈顿距离、cv2.DIST_L2: 欧式距离、cv2.DIST_C:切比雪夫距离
- param:距离参数,可以设为0
- reps,aeps: 用于表示拟合曲线所需要的径向和角度精度,通常设为0.01。
返回:
- output:[vx,vy,x,y]的1*4 的数组,前两个表示直线的方向,即vy/vx表示斜率,后两位表示直线上的一个点。
示例
import cv2
import numpy as np
import matplotlib.pyplot as plt
# 1 图像读取
img = cv2.imread('C:/Users/xxx/Downloads/arrow.png')
img2 =img.copy()
imgray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
# 2 转换为二值图
ret,thresh = cv2.threshold(imgray,127,255,0)
# 3 轮廓提取
contours, hierarchy = cv2.findContours(thresh,1,2)
# 4 将轮廓绘制在图像上
temp = np.zeros(img.shape, np.uint8) # 生成黑背景
img1 = cv2.drawContours(temp, contours, -1, (0,0,255), 2)
cnt=contours[0]
# 5 椭圆拟合
ellipse = cv2.fitEllipse(cnt)
img2 = cv2.ellipse(img2,ellipse,(0,255,0),2)
# 6 直线拟合
rows,cols = img.shape[:2]
[vx,vy,x,y] = cv2.fitLine(cnt, cv2.DIST_L2,0,0.01,0.01)
lefty = int((-x*vy/vx) + y)
righty = int(((cols-x)*vy/vx)+y)
img2 = cv2.line(img2,(cols-1,righty),(0,lefty),(255,0,0),2)
# 7 图像显示
names = ['原图','轮廓检测结果','椭圆、直线拟合']
images = [img,img1,img2]
plt.figure(figsize=(25.6,9.6))
for i in range(1):
for j in range(3):
plt.subplot(1,3,i*3+j+1),plt.imshow(images[i*3+j])
plt.title(names[i*3+j],fontsize=30), plt.xticks([]), plt.yticks([])
num=i*3+j
if num >= len(names)-1:
break
plt.show()
运行结果为:

火山引擎开发者社区是火山引擎打造的AI技术生态平台,聚焦Agent与大模型开发,提供豆包系列模型(图像/视频/视觉)、智能分析与会话工具,并配套评测集、动手实验室及行业案例库。社区通过技术沙龙、挑战赛等活动促进开发者成长,新用户可领50万Tokens权益,助力构建智能应用。
更多推荐
所有评论(0)