【问题标题】:Smooth out a single sharp corner in a function in Matlab在Matlab中平滑函数中的单个尖角
【发布时间】:2017-09-28 22:49:18
【问题描述】:

所以我想在 Sharkfin 信号的下降点和上升点平滑它。如下图所示,Sharkfin 波形在 2 秒和 4 秒的时间都有急剧的下降和上升:

关于如何对该区域进行四舍五入以使其在该部分平滑以使其看起来像这样的任何想法:

【问题讨论】:

  • 因此您正在寻找一种算法来检测信号中的尖角并将其四舍五入。找到了吗?
  • 请注意,您对convex 的使用可能是错误的。平滑拐角不会使其更加凸出。
  • 不仅仅是一个算法,一步就足够了。我有一个想法,围绕急剧上升和下降的移动平均过滤器可能会起作用。但我正在从这里寻求一些帮助。或仅在曲线的一小部分上实现过滤器的一些帮助。
  • @m7913d 会改变
  • @rayryeng 您提供的解决方案无法处理仅在特定位置进行平滑处理的情况,这里似乎就是这种情况。

标签: matlab filtering smoothing


【解决方案1】:

这里有两件不同的事情 - 如何检测急剧过渡,以及如何过滤它。

让我们依次来看看。

急剧过渡的特点是曲率大 - 我们可以通过输入曲线的diff 轻松检测到这一点。使用第二个参数 = 2 需要两次 diff 并导致“类似于”二阶导数 - 但它偏移了一个。所以当我们找到diff(sharkfin,2)较大的点时,需要偏移1才能得到角点。

接下来,平滑本身。有很多技术——我展示了一个带有盒子函数的简单卷积。这样做两次会给出输入的平滑版本。通过选择原始的“远离不连续性”和过滤后的版本“接近不连续性”,我们得到了你所要求的。如果您愿意,您可以“混合”这些点 - 根据您与角点的接近程度,使用过滤和未过滤的加权版本。我没有明确显示,但应该很容易看出如何扩展我已经编写的代码:

% generate a "shark fin" function:
fin = exp(-linspace(0,4,60));
shark = [fin (1-fin+fin(end))];
shark = repmat(shark, [1 3]);
D2 = diff(shark, 2);
roundMe = find(abs(D2)>0.1*max(D2))+1; % offset by 1 because second derivative

figure; 
subplot(3,1,1)
plot(shark); title 'shark plot'
hold on;
plot(roundMe, shark(roundMe),'r*')
legend('input','corners found')

% take N points on either side of the sharp corners:
N = 3;

% boxplot filtered version of the curve
boxFilt = ones(1, 2*N+1)/(2*N+1);
smoothShark1 = convn(shark, boxFilt, 'same'); % box plot

% second filter - smoother
smoothShark2 = convn(smoothShark1, boxFilt, 'same');


% plot the filtered results:
subplot(3,1,2)
plot(shark)
hold on
plot(smoothShark1);
hold on
plot(smoothShark2);
xlim([114 126])
ylim([0.8,1.1])
legend('original','box','box x2')
title 'smoothed everywhere'

% Now apply filtering only to points near the discontinuity
smoothMe = zeros(size(shark));
smoothMe(roundMe)=1;
smoothMe = convn(smoothMe, boxFilt, 'same');
smoothMe(smoothMe>0)=1; % this finds N points on either side of the corner

subplot(3,1,3)
plot(shark)
finalPlot=shark;
hold on
smoothIndx = find(smoothMe);
finalPlot(smoothIndx)=smoothShark2(smoothIndx);
plot(finalPlot,'g')
plot(smoothIndx, finalPlot(smoothIndx), 'r*')
xlim([114 126])
ylim([0.8,1.1])
legend('original','smoothed','changed')
title 'smoothed only near discontinuity'

输出:

【讨论】:

  • 非常感谢您的回答。我相应地修改并使用了它。效果很好:)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-02-15
  • 2011-09-11
  • 1970-01-01
  • 1970-01-01
  • 2013-01-22
相关资源
最近更新 更多