基於數據波動性的分割算法


我們常見的分割算法有很多種,比如能量法,包絡線法之類的,但這些算法難以實現實時分割,今天我給大家分享一個原創的分割算法,是在以前項目中用過的,這兩天加以優化,最中整理了一個MATLAB版本的,給大家分享一下。

算法的原理簡單介紹一下:

這里給出了一段肌音信號(已經分割好了),是用加速度傳感器在手上采集的,每次完成一次動作,就會產生一個數據波動,如果我們需要分析這樣一段信號的特征,需要先將這些信號分割出來。

 

 

 我們在分析時,主要任務時提取出信號幀起始點對應的數據索引,這里我寫了一個分割函數:

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循環中),而不是一段一段或者整段處理,因此該算法具有實時性,非常適合在嵌入式設備中應用。

我們看一下對肌音信號的分割效果:

 

 

 

 

 

 

 

 

 

 最后,我要感謝吳榮耀同學,在研究這個算法的時候他幫助了我很多。

覺得有幫助的話記得點贊轉發哦!

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM