How to find movement onset after periods of inactivity

6 views (last 30 days)
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)

Accepted Answer

Image Analyst
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);
Steven Lee Ceto
Steven Lee Ceto on 29 Nov 2021
Okay, I think with all the tips you've provided I will be able to get something workable. I'll close the question, thanks!

Sign in to comment.

More Answers (1)

Image Analyst
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.
Steven Lee Ceto
Steven Lee Ceto on 24 Nov 2021
I would say around 200 samples (2 seconds at 100 samples/second) for the still period and 50 samples for the high signal. Yes, I do have the Image Processing Toolbox.

Sign in to comment.

Community Treasure Hunt

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

Start Hunting!