高效算法仅适用于沿数据上边界拟合线性线

时间:2014-07-17 09:12:05

标签: algorithm matlab curve-fitting

我目前正试图在MATLAB中通过分散数据的扩展拟合线性线。现在这很容易使用polyfit函数,我可以很容易地获得我的y = mx + c等式。但是,我现在需要沿着数据的上边界拟合一条线,即前几个数据点。我知道这个描述是模糊的,所以我们假设我的散射数据将呈锥形,其顶点位于y轴上,并且在+ x和+ y方向上向外和向上展开。如果愿意的话,我需要在“锥体的上边缘”上安装最合适的线条。

我开发了一种算法,但速度非常慢。它涉及首先通过ALL数据拟合最佳拟合线,删除该最佳拟合线下方的所有数据点,并迭代直到仅剩下5%的初始数据点。然后,最终的最佳拟合线将位于锥体的顶部边缘附近。对于250个数据点,这需要大约5秒,而且我处理了超过一百万个数据点,这个算法效率太低。

我想我的问题是:是否有一种算法可以更有效地实现我的需求?或者有没有办法增强我的代码以消除不必要的复杂性?

这是我在MATLAB中的代码:

(例如)

a = [4, 5, 1, 8, 1.6, 3, 8, 9.2]; %To be used as x-axis points
b = [45, 53, 12, 76, 25, 67, 75, 98]; %To be used as y-axis points

while prod(size(a)) > (0.05*prod(size(a))) %Iterative line fitting occurs until there are less than 5% of the data points left

      lobf = polyfit(a,b,1); %Line of Best Fit for current data points

      alen = length(a);

      for aindex = alen:-1:1 %For loop to delete all points below line of best fit

            ValLoBF = lobf(1)*a(aindex) + lobf(2)

            if ValLoBF > b(aindex) %if LoBF is above current point...
                   a(aindex) = []; %delete x coordinate...
                   b(aindex) = []; %and delete its corresponding y coordinate
            end
      end

end

2 个答案:

答案 0 :(得分:1)

首先,您的示例代码似乎无限期地运行;)

对您的代码进行一些优化:

a = [4, 5, 1, 8, 1.6, 3, 8, 9.2]; %To be used as x-axis points
b = [45, 53, 12, 76, 25, 67, 75, 98]; %To be used as y-axis points

n_init_a = length(a);

while length(a) > 0.05*n_init_a %Iterative line fitting occurs until there are less     than 5% of the data points left

  lobf = polyfit(a,b,1); % Line of Best Fit for current data points

  % Delete data points below line using logical indexing
  % First create values of the polyfit points using element-wise vector multiplication
  temp = lobf(1)*a + lobf(2); % Containing all polyfit values
  % Using logical indexing to discard all points below
  a(b<temp)=[]; % First destroy a
  b(b<temp)=[]; % Then b, very important!

end

您还应该尝试通过在命令窗口中输入

来分析代码
profile viewer

并检查计算结果的时间最多。我怀疑它是polyfit但可能不会加速。

答案 1 :(得分:0)

您正在寻找的不是线条拟合。你试图找到点的凸包。 enter image description here

您应该查看函数convhull。一旦找到船体,就可以移除所有不靠近它的点,并独立地适应每个部分,以避免数据嘈杂。


或者,您可以将点渲染到某个像素网格上,然后执行某种形态操作,如imclose,并使用Hough变换完成。请查看此answer