How to find movement onset after periods of inactivity
9 views (last 30 days)
Show older comments
Steven Lee Ceto
on 23 Nov 2021
Commented: Steven Lee Ceto
on 29 Nov 2021
I have position vs time data for a subject walking on a treadmill that is moving at constant speed. Most of the time the subject is walking at the same speed as the treadmill, so the position is relatively constant and the speed (in terms of the position) is around zero. Sometimes, though, the subject stops walking and thus moves backward on the treadmill. Before the subject goes off the end of the treadmill, it starts walking again. I would like to extract all the times when this transition from not walking to walking again occurs. Below is a plot of velocity (pixels/second) over time (seconds) with all the peaks I'm talking about manually labeled:
I'm thinking I want to have a sort of moving window looking for periods where the average velocity is below a low threshold for a minimum length of time before then jumping up to an average velocity above a high threshold for a minimum length of time. I would want the times that correspond to the midpoint in the transition from low to high velocity. I'm just not sure how to implement something like that. I'm also working on making the data less noisy both in the position detection (refining the DeepLabCut network) and with filtering, but my main issue is finding these transition times.
edit: attached .m file with signal (100 samples/second)
0 Comments
Accepted Answer
Image Analyst
on 23 Nov 2021
Is this what you're looking for:
% Demo by Image Analyst
clc; % Clear the command window.
close all; % Close all figures (except those of imtool.)
clear; % Erase all existing variables. Or clearvars if you want.
workspace; % Make sure the workspace panel is showing.
format long g;
format compact;
fontSize = 22;
s = load('velexamp.mat')
v = s.velexamp;
subplot(2, 1, 1);
plot(v, 'b-');
title('Original Signal', 'FontSize', fontSize);
grid on;
% Smooth the signal with a median filter
vSmooth = medfilt1(v, 151);
subplot(2, 1, 2);
plot(vSmooth, 'b-');
grid on;
title('Median Filtered Signal', 'FontSize', fontSize);
% Set a threshold of 100
threshold = 100;
% Put red horizontal line there.
yline(threshold, 'Color', 'r', 'LineWidth', 2)
highSignal = vSmooth > threshold;
% Find starting points.
startingIndexes = strfind(highSignal', [0, 1])
% Put red vertical lines there.
for k = 1 : length(startingIndexes)
xline(startingIndexes(k), 'Color', 'r', 'LineWidth', 2);
end
5 Comments
Image Analyst
on 24 Nov 2021
For each starting time, you could examine the filtered time and see if the value is below some "no movement" threshold for the required number of elements.
More Answers (1)
Image Analyst
on 23 Nov 2021
Lots of ways you could approach this.
Maybe try mad() to get the mean or median absolute deviation and then threshold it and call strfind() to look for onsets.
You can use bwareaopen() on the threshold to throw out walking signals less than (shorter) a certain number of indexes.
It would be easier to help you if you would have attached your signal.
3 Comments
Image Analyst
on 23 Nov 2021
Edited: Image Analyst
on 23 Nov 2021
How many indexes (time span) before a moving/walking period do you consider it to be a still period, and how long does the signal have to be high for the signal to be considered a legitamate motion and not just a noise spike?
And let me know if you have the Image Processing Toolbox because there are some functions in there that will make this a lot easier.
See Also
Categories
Find more on Pulsed Waveforms in Help Center and File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!