OpenCV-Python:如何基于三个坐标点绘制抛物线曲线
OpenCV三点绘制抛物线实现方案
你当前代码输出三角形的原因有两个:
- cv2.polylines的作用是直接连接给定的离散坐标点形成折线,不会自动做曲线拟合
- 你将polylines的第三个参数
isClosed设为了True,会自动将最后一个点和第一个点连接形成闭合图形
实现抛物线需要先基于三个点生成足够多的曲线采样点,再用polylines连接采样点,下面提供两种常用实现方案:
方案1:二次贝塞尔曲线实现(适合控制点控制弧度场景)
如果你的中间点[clicked_x, clicked_y]是用来控制曲线弧度的控制点,不需要落在最终曲线上,用二次贝塞尔曲线实现最简单,二次贝塞尔曲线恰好对应抛物线形态。
实现代码如下:
import numpy as np import cv2 # 你的三个原始点 p0 = (line_start_x, line_start_y) p1 = (clicked_x, clicked_y) p2 = (line_end_x, line_end_y) # 生成t参数序列,步长越小曲线越平滑 t = np.linspace(0, 1, 1000) # 二次贝塞尔曲线公式 x = (1 - t)**2 * p0[0] + 2 * (1 - t) * t * p1[0] + t**2 * p2[0] y = (1 - t)**2 * p0[1] + 2 * (1 - t) * t * p1[1] + t**2 * p2[1] # 转为int32格式的点数组 pts = np.column_stack((x, y)).astype(np.int32) # 绘制折线,isClosed设为False不闭合 image = cv2.polylines(image, [pts], False, (0, 255, 0), 2) cv2.imshow(window_name, image)
方案2:三点拟合抛物线(适合要求三点均落在曲线上的场景)
如果要求你给出的三个点都必须在最终抛物线上,可以先做二次多项式拟合,再生成曲线上的点:
import numpy as np import cv2 # 三个点坐标 x_coords = [line_start_x, clicked_x, line_end_x] y_coords = [line_start_y, clicked_y, line_end_y] # 二次多项式拟合 y = a*x² + b*x + c,得到系数a,b,c z = np.polyfit(x_coords, y_coords, 2) p = np.poly1d(z) # 生成x的采样点,覆盖三个点的x范围 x_sample = np.linspace(min(x_coords), max(x_coords), 1000) y_sample = p(x_sample) # 转为点数组 pts = np.column_stack((x_sample, y_sample)).astype(np.int32) image = cv2.polylines(image, [pts], False, (0, 255, 0), 2) cv2.imshow(window_name, image)
提示:如果三个点的x坐标存在重复,可将x、y互换后做拟合,再把生成的点坐标换回来即可避免报错。采样点数可以根据平滑度需求调整,一般500以上就足够平滑。
内容的提问来源于stack exchange,提问作者Yonatan
相关产品推荐
相关产品推荐

