Matlab 如何及时重新校准两条曲线?

Matlab 如何及时重新校准两条曲线?,matlab,plot,time,overlay,Matlab,Plot,Time,Overlay,我目前正在处理二头肌卷曲运动在不同条件下获得的肌电信号。在我的代码结束时,我替换了每个条件的标准化信号,并将其作为时间的函数。我的问题是,在这个叠加过程中,由于参与者没有在同一时间开始运动,所以每次收缩都会从一个曲线到另一个曲线,我想“重新校准”(我不知道我不确定这是不是正确的拍摄词)曲线,以便每次收缩在同一时间开始和结束(蓝色曲线的末端有更多的收缩) 这就是我的代码现在的样子 %% Process EMG dynamique clc, clear all, close all %% Halt

我目前正在处理二头肌卷曲运动在不同条件下获得的肌电信号。在我的代码结束时,我替换了每个条件的标准化信号,并将其作为时间的函数。我的问题是,在这个叠加过程中,由于参与者没有在同一时间开始运动,所以每次收缩都会从一个曲线到另一个曲线,我想“重新校准”(我不知道我不确定这是不是正确的拍摄词)曲线,以便每次收缩在同一时间开始和结束(蓝色曲线的末端有更多的收缩)

这就是我的代码现在的样子

%% Process EMG dynamique
clc, clear all, close all

%% Haltère 10 Kg
%% Filtrage, centrage et rectication du signal
data_EMG = load([''10kg_haltere-Philippe.txt'']);        % Load file EMG
fe_EMG = 1000;      % sampling frequency Acceleration Hz
timeEMG_10 = (0:1/fe_EMG:(length(data_EMG)-1)*(1/fe_EMG))';       % Time vector

for m = 1 : 2
    [B,A] = butter(8/2,[15*1.247 400*1.247]/(fe_EMG/2),'bandpass');     % filter butterworth band pass 20 à 400 Hz d'ordre 4
    data_EMG_filt = filtfilt(B,A,data_EMG(:,m));     % filtring pass band 


    data_EMG_filt_1 = data_EMG_filt - ones(length(data_EMG_filt),1)*mean(data_EMG_filt);        %Centering of the EMG signal around the individual mean of each muscle
    data_EMG_filt_rectified = abs(data_EMG_filt_1);      % Rectification of the EMG signal = Full wave rectification



    %% courbe RMS/EMG
    rms_window = 1300;        
    for i = (rms_window/2)+1 : length(data_EMG)-(rms_window/2)
        rms_data_EMG(i) = rms(data_EMG_filt_rectified([i-(rms_window/2):i+(rms_window/2)]));    

    end


    [B,A] = butter(4/2,[5*1.247]/(fe_EMG/2),'low');     % filter butterworth band pass 20 à 400 Hz d'ordre 4
    data_EMG_filt_rectified_filtbutter = filtfilt(B,A,data_EMG_filt_rectified);     % filtring pass band 
    EMG_max = max(data_EMG_filt_rectified_filtbutter);
    data_EMG_filt_rectified_filtbutter_norm_10 = (data_EMG_filt_rectified_filtbutter.*100)./EMG_max;

    % Stockage
    RMS(:,m) = rms_data_EMG;
    EMG_filt(:,m) = data_EMG_filt_rectified;
    EMG_filtbutter(:,m) = data_EMG_filt_rectified_filtbutter;


    EMG_filtbutter_norm(:,m) = data_EMG_filt_rectified_filtbutter_norm_10;


end


%% Haltère 5 kg
%% Filtrage, centrage et rectication du signal
data_EMG = load(['5kg_haltere-Philippe.txt']);        % Load file EMG
fe_EMG = 1000;      % sampling frequency Acceleration Hz
timeEMG_5 = (0:1/fe_EMG:(length(data_EMG)-1)*(1/fe_EMG))';       % Time vector

for m = 1 : 2
    [B,A] = butter(4/2,[15*1.247 400*1.247]/(fe_EMG/2),'bandpass');     % filter butterworth band pass 20 à 400 Hz d'ordre 4
    data_EMG_filt = filtfilt(B,A,data_EMG(:,m));     % filtring pass band 


    data_EMG_filt_1 = data_EMG_filt - ones(length(data_EMG_filt),1)*mean(data_EMG_filt);        %Centering of the EMG signal around the individual mean of each muscle
    data_EMG_filt_rectified = abs(data_EMG_filt_1);      % Rectification of the EMG signal = Full wave rectification



    %% courbe RMS/EMG
    rms_window = 1300;        
    for i = (rms_window/2)+1 : length(data_EMG)-(rms_window/2)
        rms_data_EMG(i) = rms(data_EMG_filt_rectified([i-(rms_window/2):i+(rms_window/2)]));     

    end



    % Application d'un deuxième filtre (pour analyser les bouffé EMG) à la place de lp filter
    [B,A] = butter(8/2,[5*1.247]/(fe_EMG/2),'low');     
    data_EMG_filt_rectified_filtbutter = filtfilt(B,A,data_EMG_filt_rectified);    
    EMG_max = max(data_EMG_filt_rectified_filtbutter);
    data_EMG_filt_rectified_filtbutter_norm_5 = (data_EMG_filt_rectified_filtbutter.*100)./EMG_max;

    % Stockage
    RMS(:,m) = rms_data_EMG;
    EMG_filt(:,m) = data_EMG_filt_rectified;
    EMG_filtbutter(:,m) = data_EMG_filt_rectified_filtbutter;


    EMG_filtbutter_norm_5(:,m) = data_EMG_filt_rectified_filtbutter_norm_5;


end


figure
plot(timeEMG_10,EMG_filtbutter_norm(:,1))
hold on
plot(timeEMG_5,data_EMG_filt_rectified_filtbutter_norm_5)
hold off

我为类似的东西编写了自己的函数。我相信可能有更好的方法来实现这一点,但它在大多数情况下都是有效的。基本思想是一次将其中一行移动1点(限制在+/-范围内)并检查2之间的RMSE。记录最低RMSE出现的位置,以及您应移动的距离

时间对齐功能:

function [time2] = dataSync(data1, data2, time2, maxShift)
minError   = inf;
shiftPoint = NaN; 
for ii = -maxShift:maxShift    
    if ii <= 0 %Shift data 2 to the left
        RMSE = sqrt(mean((data1(1:end+ii) - data2(1-ii:end)).^2));
    else %Shift data 2 to the right (...or data 1 left)
        RMSE = sqrt(mean((data1(1+ii:end) - data2(1:end-ii)).^2));
    end
    if RMSE < minError
        minError = RMSE;
        shiftPoint = ii;
    end
end
if shiftPoint ~= 0
    time2 = time2 + time2(abs(shiftPoint))*sign(shiftPoint);
end
给出了一个对齐的绘图 过去是: 现在是:


请注意,峰值数不尽相同,但这可能是您能做到的最好的结果。此外,假设两个数据数组具有相同的元素数、相同的原始时间向量等,这可能并不总是正确的。

您可以在其中一个时间向量上添加一个常数,使它们对齐。因此,如果第一条曲线你的绘图从10秒开始,但第二个绘图从5.5秒开始。然后在第二个绘图中添加4.5秒。
绘图(timeEMG\u 5+4.5,data\u EMG\u filt\u rectived\u filter\u norm\u 5)
仅供参考,我尝试了你的代码,但“subject1.txt”不在你的dropbox@AeroEngy对不起,我忘了“假设这两个数据数组具有相同的元素数、相同的原始时间向量等,这可能并不总是正确的。”“是的,在我的情况下,始终是这样:-)这很好。我只是想让您知道,如果您试图在不正确的情况下使用它。有时我会出现以下错误:”
下标索引必须是实正整数或数据同步中的逻辑错误(第16行)time2=time2+time2(移位点)*符号(移位点)。(即使我改变了班次)“你知道为什么吗?当我用其他数据传输这个解决方案时(有相同的文件,但这些是另一个主题的文件),我得到了与以前相同的错误:-/@Mac。对不起,我想我看到了一个错误。基本上,如果'shiftPoint'是负数或零,就会出现错误。需要ans abs()如果
,则为零。
figure
plot(timeEMG_10,EMG_filtbutter_norm(:,1))
hold on
%% Try to line up the times.
[timeSync] = dataSync(EMG_filtbutter_norm(:,1), data_EMG_filt_rectified_filtbutter_norm_5, timeEMG_5, 5000);
% plot(timeEMG_5,data_EMG_filt_rectified_filtbutter_norm_5)
% hold off
plot(timeSync,data_EMG_filt_rectified_filtbutter_norm_5,'g')
hold off