How can I cut the number of frames down?

2 views (last 30 days)
I have input data from force plates, to count the number of Tappings from a sport test. The measurement must last 15 sec. for an exact and valid result. This is equevanlent to 11250 frames with a frame rate of 750 Hz. Therefor I have to cut the data. I want a solution to do it automatically by define a start and end point with some sort of event, not manually by cutting the graph with uniwait and ginput.
%% Read data
[filename,pathname] = uigetfile('*.mat','Bitte Sprungdaten Mat-Datei auswählen','C:\Users\ifdadmin\Desktop\Local QTM Project\Data\20201007FR02\Running,Squat,CMJ,DJ,Extra\CMJ 2.qtm');
load([pathname, filename]);
% Kraftdaten aus Rohdaten ziehen
Data = struct2cell(load([pathname,filename]));
% Force data
F1 = (Data{1,1}.Force(1).Force);
F2 = (Data{1,1}.Force(2).Force);
f = Data{1,1}.Force.Frequency;
Frames = Data{1,1}.Force.NrOfSamples;
% isolate vertical force
Fges = F1 + F2;
Fvert = Fges(3,:);
Fvert_links = F1(3,:);
Fvert_rechts = F2(3,:);
%% Tapping Test
figure
plot(Fvert_links);
findpeaks(Fvert_links, "MinPeakHeight",600, "MinPeakDistance",50);
figure
plot(Fvert_rechts);
findpeaks(Fvert_rechts, "MinPeakHeight",600, "MinPeakDistance",50);
% Number of Taps per Side
Tap_links = numel(findpeaks(Fvert_links, "MinPeakHeight",600, "MinPeakDistance",50));
Tap_rechts = numel(findpeaks(Fvert_rechts, "MinPeakHeight",600, "MinPeakDistance",50));
% Number of Taps
Taps = Tap_links + Tap_rechts;
This is my code so far and the record I use is atteched.
  6 Comments
Image Analyst
Image Analyst on 8 Jun 2022
What is a "frame"? Is it an element? Can you just do
index1 = find(signal > 600, 1, 'first');
index2 = index1 + 11249; % Index 2 is exactly 15 seconds later.
(Make sure you scroll down to see @Mathieu NOE's answer).
Hannah Knoke
Hannah Knoke on 10 Jun 2022
Yes a frame is something like an element.
Thank you for your help, I will try this.

Sign in to comment.

Accepted Answer

Mathieu NOE
Mathieu NOE on 8 Jun 2022
hello Hannah
I tried to improve my first (very simple suggestion)
here some (hopefully) improvements :
  • detection of "valid" peaks based not only on findpeaks (and already used parameters) , but added another step :
  • method = all peaks generated by findpeaks are then analyzed in term of time increments (delta), by buffer of 5 samples (with overlap = 1)
  • only a full valid (low standard deviation) buffer can trigger a positive ouput , this way we record the first sample index of the valid buffer
  • once this first valid peak is defined, we show all peaks from this first value up to the end , 11250 samples down the road.
updated code :
%% Read data
[filename,pathname] = uigetfile('*.mat','Bitte Sprungdaten Mat-Datei auswählen','C:\Users\ifdadmin\Desktop\Local QTM Project\Data\20201007FR02\Running,Squat,CMJ,DJ,Extra\CMJ 2.qtm');
load([pathname, filename]);
% Kraftdaten aus Rohdaten ziehen
Data = struct2cell(load([pathname,filename]));
% Force data
F1 = (Data{1,1}.Force(1).Force);
F2 = (Data{1,1}.Force(2).Force);
f = Data{1,1}.Force.Frequency;
Frames = Data{1,1}.Force.NrOfSamples;
% isolate vertical force
Fges = F1 + F2;
Fvert = Fges(3,:);
Fvert_links = F1(3,:);
Fvert_rechts = F2(3,:);
%% Tapping Test
MinPeakHt = 600; % MinPeakHeight
MinPeakDist = 50; % MinPeakDistance
[PKS_links,LOCS_links]=findpeaks(Fvert_links, "MinPeakHeight",MinPeakHt, "MinPeakDistance",MinPeakDist);
[PKS_rechts,LOCS_rechts]=findpeaks(Fvert_rechts, "MinPeakHeight",MinPeakHt, "MinPeakDistance",MinPeakDist);
samples_display = 11250; % max samples window size to display (from first valid peak - see below the buffer analysis)
x = 1:length(Fvert_links); % create x axis data
figure
% remove (eventual) first spurious peaks by looking at buffered data and keeping
% only values that show a low standard deviation on time increments (delta)
valid_index_links = buffer_analysis(LOCS_links);
start_index_links = valid_index_links(1);
LOCS_links = LOCS_links(start_index_links:end);
ind_links = LOCS_links(1)-100:min(LOCS_links(1)+samples_display,length(Fvert_links)); % start to display data 100 samples before first peak
LOCS_links(LOCS_links>max(ind_links)) = []; % remove peaks plot after 11250 samples window
plot(x(ind_links),Fvert_links(ind_links));
hold on
plot(x(LOCS_links),Fvert_links(LOCS_links),'dr');
hold off
figure
% remove (eventual) first spurious peaks by looking at buffered data and keeping
% only values that show a low standard deviation on time increments (delta)
valid_index_rechts = buffer_analysis(LOCS_rechts);
start_index_rechts = valid_index_rechts(1);
LOCS_rechts = LOCS_rechts(start_index_rechts:end);
ind_rechts = LOCS_rechts(1)-100:min(LOCS_rechts(1)+samples_display,length(Fvert_rechts)); % start to display data 100 samples before first peak
LOCS_rechts(LOCS_rechts>max(ind_rechts)) = []; % remove peaks plot after 11250 samples window
plot(x(ind_rechts),Fvert_rechts(ind_rechts));
hold on
plot(x(LOCS_rechts),Fvert_rechts(LOCS_rechts),'dr');
hold off
% Number of Taps per Side
Tap_links = numel(LOCS_links);
Tap_rechts = numel(LOCS_rechts);
% Number of Taps
Taps = Tap_links + Tap_rechts;
function out = buffer_analysis(data)
% running (buffered) analysis with one sample overlap :
buffer = 5; % nb of samples in one buffer (buffer size)
stdD_threshold = 50; % time increments (delta) in buffer : valid buffers must have standard deviation below threshold
overlap = buffer-1; % overlap expressed in samples
out = [];
%% main loop %%%%
m = length(data);
shift = buffer-overlap; % nb of samples between 2 contiguous buffers
for ci=1:(m-buffer)
start_index = 1+(ci-1)*shift;
stop_index = start_index+ buffer-1;
buffer_data = data(start_index:stop_index); %
D = diff(buffer_data);
if std(D)<stdD_threshold
out = [out;start_index];
end
end
end
  6 Comments

Sign in to comment.

More Answers (0)

Community Treasure Hunt

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

Start Hunting!