You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用curve_fit拟合悬链线出现异常大参数的问题求助

悬链线拟合参数异常问题

我拍摄了一条链条的照片,采样了每个链环的像素位置,想要拟合悬链线模型 a*cosh((x-x0)/a)+c 的最优参数(a、c、x0为待求参数)。采样点绘制到原图上与链条完全重合,但拟合得到的参数却比预期大数千倍。我尝试减少采样点数量、调整初始参数,但问题仍未解决。

问题原因

核心问题是图像坐标系的y轴方向与数学模型相反:

  • 图像中y值越大表示位置越靠下(原点在左上角)
  • 标准悬链线模型 c + a*cosh((x-x0)/a) 的y值越大表示位置越靠上,且在x=x0处取得最小值(链条的最低点)

你的采样数据中,链条最低点对应图像的最高y值(约2624),这与模型的趋势完全相反,导致拟合算法收敛到错误的参数值。

解决方法

方法1:反转y轴数据

将采样的y值反转,使其符合模型的y轴方向:

y_max = y.max()
y_inverted = y_max - y

然后用y_inverted代替原y值进行拟合。

方法2:修改悬链线模型

调整模型以适配图像的y轴方向,让模型在x=x0处取得最大值(对应链条最低点):

def cat(x, a, c, x0):
    return c - a * np.cosh((x - x0) / a)

修正后的完整代码

以下是包含y轴反转的修正代码,同时修复了未加载图像的问题:

from matplotlib import pyplot as plt
from scipy.optimize import curve_fit
import numpy as np

fname = "C:/Users/marti/OneDrive/Desktop/Pier/Catenaria.txt"
# 加载图像(替换为你的实际图像路径)
img = plt.imread("your_image_path_here.jpg")

plt.xlabel("x [pixels]")
plt.ylabel("y [pixels]")
plt.imshow(img)

x, y = np.loadtxt(fname, unpack=True)
# 反转y轴数据
y_max = y.max()
y_inverted = y_max - y

sigma_y = 3.
plt.errorbar(x, y, sigma_y, fmt=".")

def cat(x, a, c, x0):
    return c + a * np.cosh((x - x0) / a)

# 基于反转后的数据设置合理初始参数
popt, pcov = curve_fit(cat, x, y_inverted, p0=(1000., 0., 2052.))
a_hat, c_hat, x0_hat = popt
sigma_a, sigma_c, sigma_x0 = np.sqrt(pcov.diagonal())
print(f"a: {a_hat:.2f} ± {sigma_a:.2f}, c: {c_hat:.2f} ± {sigma_c:.2f}, x0: {x0_hat:.2f} ± {sigma_x0:.2f}")

# 将拟合结果转换回原图像坐标系
y_fit = y_max - cat(x, a_hat, c_hat, x0_hat)
plt.plot(x, y_fit, color='red', label='拟合悬链线')
plt.legend()

plt.show()

额外说明

  • 初始参数的选择仍需合理:反转后的y值最小值为0(链条最低点),因此c的初始值可设为0,a的初始值可根据链条跨度估算(跨度约为3291像素,a值通常为跨度的1/4~1/2)
  • 代码中修复了img未加载的问题,需替换为你的实际图像路径

内容的提问来源于stack exchange,提问作者PIERGIORGIO GRECO

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.06 18:34:56