在MATLAB中通过获取上下包络来封装信号

在MATLAB中通过获取上下包络来封装信号,matlab,interpolation,envelope,Matlab,Interpolation,Envelope,我有一个信号,它在一些值周围反弹。我想从上方和下方封装信号,如下图所示: 如果信号只增加或减少,使用正在运行的maxima脚本非常有效: 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 e

我有一个信号,它在一些值周围反弹。我想从上方和下方封装信号,如下图所示:

如果信号只增加或减少,使用正在运行的maxima脚本非常有效:

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
函数[out]=rMax(X)
Y=X;
最大值=X(1);
对于k=1:长度(X)
如果X(k)您可以根据需要使用适当的窗口大小
n1
n2
。R2016a中引入了这两个功能。请看我答案的底部,为R2016a之前的产品提供一个自编的替代品

要获取上限,可以使用:

xMax = movmax(x,[n1,n1]);
xMax = movmin(xMax,[n2,n2]);
对于下限,只需切换
movmin
movmax

xMin = movmin(x,[n1,n1]);
xMin = movmax(xMin,[n2,n2]);
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);
结果可能如下所示:

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


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

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);
以下是取代
movmax
movingmax
的代码:

xMin = movmin(x,[n1,n1]);
xMin = movmax(xMin,[n2,n2]);
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);
以下是取代
movmin
movingmin
的代码:

function y = movingmin(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) = min(xp(k:k+a+b));
end
y = reshape(y,s);

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

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
我明白了,但是在信号的某些部分仍然失败

对于此函数或任何其他函数,我强烈建议您不要使用名为
max
的变量,因为它会隐藏Matlab内置函数,并可能导致各种难以调试的问题,特别是在不知不觉中完成时。是的,我知道,谢谢您的答案看起来正符合我的要求。唯一不好的是movmax和movmin函数适用于matlab2016a,我目前只能访问2015版本。@JaredLo我刚刚更新了答案,加入了适用于R2016a之前版本的解决方案。请参阅底部的部分,它提供了两个功能的替换。结果完全相同。