逼近方法

3
我附上了一张图片:alt text
(来源:piccy.info) 在这张图片中,有一个在给定点上定义的函数图表。例如,在x=1..N的点上。
另一个图表是以半透明曲线绘制的, 我想从原始图表中得到它, 也就是说,我想将原始函数近似为平滑函数。
有没有什么方法可以做到这一点?
我听说过最小二乘法,它可以用于通过直线或抛物线函数逼近函数。但我不需要用抛物线函数逼近。 我可能需要用三角函数来逼近它。 那么有没有相应的方法呢? 还有一个想法,如果我们能推导出三角函数的最小二乘法,那么是否可以将其用于此问题?
还有一个问题! 如果我使用离散傅里叶变换,并将函数视为波的总和,那么噪声可能具有特殊的特征,通过这些特征我们可以定义它,然后可以将相应的频率设为零,然后执行反傅里叶变换。 如果您认为这是可能的,那么您可以提出什么建议来确定噪声的频率?

我不知道使用正弦、余弦还是多项式更好。是的,我知道样条曲线,但我只用它们来处理抛物线函数。我还没有尝试用三角函数进行逼近。 - maximus
实际上,我想对图像进行二值化处理。 不使用任何二值化方法,如Otsu、Bernsen等——这些方法使用灰度图像数据和一些阈值进行二值化。 - maximus
还有一点要说 - 我想要一个快速的方法。时间很重要。 - maximus
不,我的意思不是输出曲线必须具有0和1的值。 我希望得到一个平滑的曲线作为输出。在获得这个平滑曲线之后,我可以识别其局部最小值和最大值,并计算图像行中每个像素的局部阈值值,它必须是该像素周围一些局部最小值和最大值的平均值。 - maximus
为了构建阈值线,我需要在该点周围取几个局部最大值和最小值,并计算平均值。这将成为每个像素的阈值值。 - maximus
显示剩余4条评论
5个回答

9
很不幸,这里提供的许多解决方案都不能解决问题,或者它们是完全错误的。有许多方法可以解决特定条件和要求的问题,您必须了解!
a) 近似理论:如果您有一个非常清晰定义的函数(由定义或数据给出)且您想尽可能精确地跟踪它,则使用Chebyshev或Legendre多项式的多项式或有理逼近,这意味着您通过多项式或傅里叶级数逼近函数。
b) 插值:如果您有一个函数,其中给出了一些点(但不是整个曲线!)并且您需要一个函数来穿过这些点,则可以使用几种方法:
Newton-Gregory、带分裂差异的牛顿、拉格朗日、埃尔米特、样条。
c) 曲线拟合:您有一个具有给定点的函数,并且您想绘制一个具有给定函数的曲线,该函数尽可能接近曲线。对于这种情况,有线性和非线性算法。
您的绘图意味着:
- 它与数学函数远不相同。 - 它不是由数据或函数明确定义的。 - 您需要拟合曲线,而不是一些点。

你想要和需要的是什么

d) 平滑处理: 如果给定一个有噪声或快速变化元素的曲线或数据点,你只想看到随时间变化缓慢的变化。

你可以像Jacob建议的那样使用LOESS进行处理(但我发现这有些过度,特别是因为选择合理的跨度需要一些经验)。对于你的问题,我建议简单地使用Jim C.建议的移动平均法。

http://en.wikipedia.org/wiki/Running_average

抱歉,cdonner和Orendorff,你们的建议虽然出于好心,但完全错误,因为你们在使用正确的工具来解决错误的问题。
这些人使用了六次多项式来拟合气候数据,并且让自己非常尴尬。

http://scienceblogs.com/deltoid/2009/01/the_australians_war_on_science_32.php

http://network.nationalpost.com/np/blogs/fullcomment/archive/2008/10/20/lorne-gunter-thirty-years-of-warmer-temperatures-go-poof.aspx


优秀的、准确的回应! - Alex Budovski
我会逐步尝试每一件事情!现在我想尝试计算图像线每个像素的阈值。该阈值将由左极值和右极值的平均值计算而来。如果图像线不是平滑曲线,则此方法不好。但是,我使用平滑滤波器对图像线进行了平滑处理,现在该线似乎成为了平滑曲线,但是如果我们在使用平滑滤波器后仍无法得到平滑曲线怎么办?在这种情况下,只有提供一个良好的图像线平滑算法才能使该算法有效,我的意思是获得一个良好的平滑线。 - maximus
如果我们获取源图像每个像素的亮度值,我们得到Y(x)=aR(x)+bG(x)+c*B(x),其中a、b和c可以不同设置。然后,我们对图像线使用平滑滤波并计算图像线的所有极值-我们只能取那些差异为|L(x') - L(x'')| > epsilon的极值,其中epsilon被设置为一些小值。因此,我们将忽略不重要(嘈杂)的波动变化。我从某个算法中得到了这个结论,该算法也用于构造阈值线,但我还没有检查它,也不知道这个算法是否总是能给出好结果。 - maximus
在我自己的防御中,问题说,“我可能需要用三角函数来逼近它。那么有没有做到这一点的方法?”但我认为你的答案是正确的:曲线拟合并不是Maximus真正需要的,尽管这是他最初要求的... - Jason Orendorff

3

在免费的R中使用loess。例如,loess函数可以近似一个嘈杂的正弦曲线。

sine
(来源:stowers-institute.org)

如您所见,您可以通过span来调整曲线的平滑程度。

以下是这里的一些示例R代码:

逐步程序

让我们取一个正弦曲线,添加一些“噪声”,然后看看loess的“span”参数如何影响平滑曲线的外观。

  1. 创建一个正弦曲线并添加一些噪声:

    period <- 120 x <- 1:120 y <- sin(2*pi*x/period) + runif(length(x),-1,1)

  2. 在这个嘈杂的正弦曲线上绘制点:

    plot(x,y, main="Sine Curve + 'Uniform' Noise") mtext("showing loess smoothing (local regression smoothing)")

  3. 使用默认的span值0.75应用loess平滑:

    y.loess <- loess(y ~ x, span=0.75, data.frame(x=x, y=y))

  4. 计算整个曲线上的loess平滑值:

    y.predict <- predict(y.loess, data.frame(x=x))

  5. 沿着已经绘制的点绘制平滑的loess曲线:

    lines(x,y.predict)


为了确定所需的结果是否已获得,必须满足什么条件?我指的是期望曲线。 如果图像某些地方颜色差异非常小,则与该图像部分对应的线将被视为噪音。我想知道这些方法在手机上如何工作。到目前为止,虽然已知算法,但我找不到解决方案。如果我们有理想的条形码,则一切正常,但如果它包含噪声,则整个过程都会浪费。 - maximus

2
这被称为曲线拟合。最好的方法是找到一个可以帮你完成此操作的数值库。这里有一个页面展示了如何使用scipy进行曲线拟合(点击此处)。该页面上的图片展示了代码的功能:

graph showing two noisy data sets and two best-fit sine curves
(来源:scipy.org

现在只需要4行代码,但作者并没有解释它。我会在这里简要解释一下。

首先,您必须决定您想要的答案形式。在这个例子中,作者想要一个形式为

"f(x) = p0 cos (2π/p1 x + p2) + p3 x" 是一个数学公式,其中p0、p1、p2和p3是常数。它可以用于描述一个曲线。通过使用scipy库中的求解器,可以找到这个曲线的四个常数。需要提供一个误差函数,以便scipy可以根据样本数据点来检查其猜测值与实际值的接近程度。
fitfunc = lambda p, x: p[0]*cos(2*pi/p[1]*x+p[2]) + p[3]*x # Target function
errfunc = lambda p: fitfunc(p, Tx) - tX # Distance to the target function

"errfunc"函数只需要一个参数:长度为4的数组。它将这些常量插入公式中,计算候选曲线上的一组值,然后减去采样数据点tX的数组。结果是一组误差值的数组;很可能scipy将对这些值的平方和进行求和。
然后,只需放入一些初始猜测值,scipy.optimize.leastsq就会计算,试图找到一组使误差最小化的参数p
p0 = [-15., 0.8, 0., -1.] # Initial guess for the parameters
p1, success = optimize.leastsq(errfunc, p0[:])

结果p1是一个包含四个常量的数组。success如果求解器实际找到了解,则为1、2、3或4。(如果errfunc足够疯狂,求解器可能会失败。)

2

你可以使用数字滤波器,如FIR滤波器。最简单的FIR滤波器只是一个运行平均值。如果需要更复杂的处理,请查看FFT。


我会考虑一下的!谢谢!这可能有些复杂,但是结果应该会很好,我认为。 - maximus

1

这看起来像是多项式逼近。您可以在Excel中玩弄多项式(在图表上添加趋势线,选择多项式,然后将阶数增加到所需的逼近级别)。应该不难找到相应的算法/代码。

Excel还可以显示它为逼近得出的方程式。


我尝试了6次多项式逼近,结果不太理想,也许我应该尝试增加阶数... - maximus

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接