通过在MATLAB中获取上下包络来输入信号

时间:2016-07-11 07:37:11

标签: matlab interpolation envelope

我有一个反映某些值的信号。我想要封装来自上方和下方的信号,如下图所示: example

如果信号仅增大或减小,使用运行的最大值脚本效果很好:

function [out] = rMax(X)
    Y=X;
    maximum=X(1);
    for k=1:length(X)
        if X(k)<=maximum
        Y(k)=maximum;
        else
            maximum=X(k);
        end
    end
    out=Y;
end

然而,当信号交替出现时,我不能再使用那种方法了。有没有办法在MATLAB或Mathematica中实现这个目标?

2 个答案:

答案 0 :(得分:3)

您可以将movmaxmovmin与适当的窗口大小n1&gt;结合使用n2取决于您的需求。 这两个功能在R2016a中引入。请查看我的答案的底部,以便在R2016a之前使用自行替换它们。

要获取上限,您可以使用:

xMax = movmax(x,[n1,n1]);
xMax = movmin(xMax,[n2,n2]);

对于下限,只需切换movminmovmax

xMin = movmin(x,[n1,n1]);
xMin = movmax(xMin,[n2,n2]);

结果可能如下所示:

result

如果选择n2=n1,当数据x中存在峰值时,界限非常紧张。如果您只是通过使n2小于n1来选择更大的差异,则会在峰值处获得更长的直线。副作用是当信号从1跳到-1或反之亦然时,边界开始是远距离的。如果选择n1太高,则会提取100左右的信号的一小部分。

以下是生成上图的完整代码,其中一些示例数据与您问题中的绘图相匹配。只需使用值n1n2来查看它们的效果。

n1 = 20;        % for first window
n2 = 18;        % for second window

% generate sample data
t = 20:0.1:220;
x = -ones(size(t));
x(t>60&t<100) = 1;
x(t>105&t<135) = 1;
x(t>145&t<155) = 1;
x = x + 0.4*randn(size(x));

% get upper bounds
xMax = movmax(x,[n1,n1]);
xMax = movmin(xMax,[n2,n2]);

% get lower bounds
xMin = movmin(x,[n1,n1]);
xMin = movmax(xMin,[n2,n2]);

% draw figure for illustration
figure; hold on;
plot(t,x);
xlim([20,220]);
ylim([-3,3]);
plot(t,xMax,'r','LineWidth',1.1);
plot(t,xMin,'Color',[0,0.5,0],'LineWidth',1.1);

在R2016a之前

要在R2016a之前的MATLAB版本中拥有movminmovmax基本功能,我们可以实现自己的功能。因此,我们需要应用可以非常容易地实现的移动最小值(或分别移动最大值)。为了保持与R2016a中的函数的兼容性,我们将实现第二个参数是标量并且它是两个元素的向量的情况。这涵盖了与here类似的以下语法,其中x需要是一个向量。

y = movingmax(x,k)
y = movingmax(x,[kb kf])

以下是替换movingmax的{​​{1}}代码:

movmax

以下是替换function y = movingmax(x,n) if length(n) > 1 a=n(1); b=n(2); else b=floor((n-1)/2); a=b+mod(n-1,2); end s = size(x); xp = [ones(a,1)*x(1);x(:);ones(b,1)*x(end)]; y = zeros(size(x)); for k = 1:length(x) y(k) = max(xp(k:k+a+b)); end y = reshape(y,s); 的{​​{1}}代码:

movingmin

答案 1 :(得分:0)

我为运行的最大值/最小值函数添加了第二个条件

function [out] =rMin(X)

Y=X;

minimum=X(1);

for k=2:length(X)

    if X(k)>=minimum
        Y(k)=minimum;
    else
        minimum=X(k);
    end

    if X(k)>=(Y(k-1)+3)
        minimum=X(k);
        Y(k)=minimum; 
    end
end 

out=Y;

end

然后我得到了这个但是在信号的某些部分仍然失败了 enter image description here