How to normalise segregated surface emg signals into the same number of data points?

14 views (last 30 days)
Hi everyone,
I have a cell array containing multiple gait cycles of an SEMG signal. Each cycle represents the push phase and recovery phase of a wheelchair. I want to get the average of the SEMG signal of all the cycles however, each cycle contains a different amount of data points. How do I normalise the cycles to contain a certain amount of data points without disrupting the signals? I also have a cell array containg the times of propulsion.
If anyone could point me in the right direction that would be great!
Thanks,
  4 Comments
Renee Wurfel
Renee Wurfel on 26 Aug 2024
Hi Jacob,
I have attached the file im reading from as well as the code that I have written that segregates the time and semg signals into cycles.
Thanks!

Sign in to comment.

Accepted Answer

Jacob Mathew
Jacob Mathew on 26 Aug 2024
Hey Renee,
I understand that you want to normalise the cycles to contain a certain number of datapoints without disrupting the signal. One way to achieve this is to use interpolation.
We will use the “interp1” function to achieve interpolation. The link to the function’s documentation is below:
A possible approach is to take the average length of the cycles and interpolate every cycle to have that length. This normalization can be achieved using the following code:
% Calculate the length of each cycle
cycle_lengths = cellfun(@length, BB_Cycles);
% Compute the average length of the cycles
% This will be the length we will normalise all cycles to
average_length = round(mean(cycle_lengths));
% Initialize cell arrays to store the normalized cycles
BB_Cycles_Normalized = cell(1,length(BB_Cycles));
Time_Cycles_Normalized = cell(1,length(BB_Cycles));
% Loop through each cycle to normalize
for i = 1:length(BB_Cycles)
% Get the current cycle and its time
current_cycle = BB_Cycles{i};
current_time = Time_Cycles{i};
% Create a new time vector for the normalized cycle
normalized_time = linspace(current_time(1), current_time(end), average_length);
% Interpolate the data to the new time vector
normalized_cycle = interp1(current_time, current_cycle, normalized_time, 'linear');
% Store the normalized cycle and its time
BB_Cycles_Normalized{i} = normalized_cycle;
Time_Cycles_Normalized{i} = normalized_time;
end
This will ensure that each cycle will have consistent number of points allowing comparison across cycles.

More Answers (1)

Umar
Umar on 26 Aug 2024

Hi @Renee Wurfel ,

To achieve the normalization of SEMG cycles while preserving the integrity of the signals, you can utilize interpolation techniques. This method will allow you to resample each cycle to a predetermined number of data points without distorting the signal characteristics. Here’s how you can modify your existing code to incorporate these steps:

% Assuming BB_Cycles contains your segmented SEMG cycles
num_cycles = length(BB_Cycles);
target_length = 1000; % Set your desired target length for normalization
normalized_cycles = zeros(num_cycles, target_length); % Preallocate normalized   cycles
% Interpolation for each cycle
for i = 1:num_cycles
  original_cycle = BB_Cycles{i};
  original_length = length(original_cycle);
    % Create a time vector for the original cycle
    original_time = linspace(0, 1, original_length); % Normalize time between 0   
    and 1
    % Create a new time vector for the target length
    new_time = linspace(0, 1, target_length);
    % Interpolate using linear method (you can use 'spline' for smoother results)
    normalized_cycles(i, :) = interp1(original_time, original_cycle, new_time, 
   'linear');
  end
% Calculate average SEMG signal across all normalized cycles
average_SEMG = mean(normalized_cycles, 1);
% Plotting the average SEMG signal
figure;
plot(linspace(0, 1, target_length), average_SEMG);
title('Average SEMG Signal Across Cycles');
xlabel('Normalized Time');
ylabel('Amplitude');
grid on;
% You may also want to visualize individual normalized cycles
figure;
hold on;
for i = 1:num_cycles
  plot(linspace(0, 1, target_length), normalized_cycles(i, :));
end
title('Normalized SEMG Cycles');
xlabel('Normalized Time');
ylabel('Amplitude');
legend(arrayfun(@(x) sprintf('Cycle %d', x), 1:num_cycles, 'UniformOutput',   
false));
hold off;

In addition to this code, the choice of interpolation method (linear vs. spline) can affect the smoothness of your normalized signals. Spline interpolation tends to provide smoother results but may introduce artifacts if not handled carefully. So, make sure that the normalization process does not introduce significant distortion in your SEMG signals. I will advise to visualize both individual cycles and their averages post-normalization. After obtaining the average signal, consider performing statistical analyses to evaluate variability among different cycles or conditions.

  2 Comments
Renee Wurfel
Renee Wurfel on 29 Aug 2024
Thank you very much Umar! I may need assitance with evaluating the variabilty among different cycles, but that is a great idea!
Umar
Umar on 29 Aug 2024
Hi @Renee Wurfel,
I appreciate your positive feedback regarding the idea. I would be more than happy to assist you with evaluating the variability among different cycles.

Sign in to comment.

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!