Volatility data segmentation algorithm based on

We have a variety of common segmentation algorithm, such as energy method, the envelope method and the like, but difficult to implement these algorithms in real-time segmentation, and today I have to share an original segmentation algorithm was used in previous projects, which It is optimized for two days, the most in a compiled version of MATLAB, to share with you.

The algorithm principle brief introduction:

Here are some muscle tone signal (have a good split), the acceleration sensor is acquired in the hand, each time the operation is completed, a data fluctuation is generated, if we need to analyze the signal characteristic of such a period, it is necessary to these signals are split out.

 

 

 Our analysis, when the main task to extract the signal frame corresponding to the start point of data index, and here I wrote a partition function:

function [ST, EN] = SignalDivision(A)

%%宏定义
AF1 = 2;    %放大因子,计算ADD
AF2 = 16;    %放大因子,延申长度
AF3 = 3.5;    %放大因子,判断Frame
MAE = 0.95; %移动平均系数

%%中间变量
L = max(size(A));
AS = MeanAverSlope_3(A);
Sigma = std(A);
ADD = AF1 * (Sigma / AS);
JF = false;
FF = false;
Counter = 1;
Index = 1;
MA = 0;

st = zeros(1, L);
en = zeros(1, L);
ST = zeros(1, L);
EN = zeros(1, L);

DATA_P = zeros(1, L - 1);
DATA_A = zeros(1, L - 2);
DATA_P(1) = A(1);
for i = 2 : L - 1
    DATA_P(i) = DATA_P(i-1) * MAE + A(i) * (1 - MAE); %移动平均
    DATA_A(i-1) = abs(A(i) - DATA_P(i));
    if DATA_A(i-1) > Sigma && ~JF
        JF = true;
        st(Counter) = i - ADD * AF2;
        if ~FF
            ST(Index) = st(Counter);
            FF = true;
        end
    elseif abs(DATA_A(i-1) < Sigma) && JF
        JF = false;
        en(Counter) = i + ADD * AF2;
        sep = en(Counter) - st(Counter);
        Counter = Counter + 1;
    end
    if JF
        if DATA_A(i-1) > MA
            MA = DATA_A(i-1);
        end
    elseif FF
        if i - en(Counter - 1) >sep
            EN(Index) = en(Counter - 1);
            FF = false;
            if MA > Sigma * AF3
                Index = Index + 1;
            end
            MA = 0;
        end
    end
end

ST(ST==0)=[];
EN(EN==0)=[];
function [AS] = MeanAverSlope_3(A)

L = max(size(A));
ALS = zeros(L-1, 1);
for i = 2:L
    ALS(i-1) = abs((A(i) - A(i-1)));
end

AS = mean(ALS);

这个函数主要工作机制是:

1,计算整个波段的数据波动性,用一个“平均斜率”的参数表征,即MeanAverSlope_3 函数的功能,然后再利用公式计算数据的标准差(C/C++的朋友可以自己写一个计算标准差的函数),ADD是断点延伸长度,因为我们判定产生动作的位置比较靠近数据峰值,因此起点需要往前扩展一定距离,终点往后扩展,而ADD即为扩展的长度。

2,利用移动平均的思想消除低频噪音,这些无效的信号往往是由于手的缓慢移动等因素而产生的。我们可以对比消除前后的数据图形:

消除前:

 

 消除后:

 

 对比过后,是不是就感觉这样一处理分割起来就简单多了

3,判断数据的跳动性,当数据跳动值大于Sigma时,判定数据有跳动,记录当前对应点的索引值,当一段时间之内还有其他值也大于Sigma时,刷新这个时间,如果没有,则判定该跳动结束,并记录结束位置的索引。然而该跳动是否由手的动作而产生还是环境噪音产生,我们还需要对其进行二次判定,当这段截取的信号中最大跳动值大于阈值 AF3*Sigma 时,才判定该动作有效,否则判定是环境因素产生的噪音。

4,整理数据帧的起始索引,存放于两个向量中,并删除其他数据值为0的点(一开始预分配了内存)

至此,我们的数据分割就完成了,接下来就是怎么用的问题了,由于我们对于数据是一个一个导入处理的(在一个大的for循环中),而不是一段一段或者整段处理,因此该算法具有实时性,非常适合在嵌入式设备中应用。

我们看一下对肌音信号的分割效果:

 

 

 

 

 

 

 

 

 

 最后,我要感谢吴荣耀同学,在研究这个算法的时候他帮助了我很多。

觉得有帮助的话记得点赞转发哦!

 

Guess you like

Origin www.cnblogs.com/showtime20190824/p/11760793.html