extractors.pyGait¶
Module: extractors.pyGait
¶
This program implements some of the feature extraction equations from:
“iGAIT: An interactive accelerometer based gait analysis system” Mingjing Yang, Huiru Zheng, Haiying Wang, Sally McClean, Dave Newell. 2012. Computer methods and programs in biomedicine 108:715-723. DOI:10.1016/j.cmpb.2012.04.004 http://www.ncbi.nlm.nih.gov/pubmed/22575802
iGait was written as a Matlab file and compiled as a Windows application. It assumes a fixed accelerometer position, and derived heel strike timings from an assumed anterior-posterior orientation along the y-axis.
- iGAIT inputs ::
- sample rate
- threshold (anterior-posterior acceleration, to detect heel contact)
- distance
- iGAIT features ::
- spatio-temporal features, from estimates of heel strikes:
- cadence = number of steps divided by walking time
- distance-based measures (mean step length, velocity)
- regularity and symmetry (each direction):
- step/stride regularity
- symmetry
root mean square (each direction)
- spectral features (each direction):
- integral of the power spectral density (IPSD)
- main frequency: frequency with the maximum value of PSD
- frequencies when PSD is cumulated (CPSD)
- pyGait functions compute all of iGAIT’s features except spectral features::
- gait_features() for all heel strike-based estimates:
- cadence
- mean step length and velocity (if distance supplied)
- regularity and symmetry (each direction)
- root_mean_square():
- root mean square (each direction)
- Authors:
- Arno Klein, 2015 (arno@sagebase.org) http://binarybottle.com
- Elias Chaibub-Neto, 2015 (neto@sagebase.org)
Copyright 2015, Sage Bionetworks (http://sagebase.org), Apache v2.0 License
Functions¶
-
mhealthx.extractors.pyGait.
gait
(strikes, data, duration, distance=None)¶ Extract gait features from estimated heel strikes and accelerometer data.
This function extracts all of iGAIT’s features that depend on the estimate of heel strikes:
- cadence = number of steps divided by walk time - step/stride regularity - step/stride symmetry - mean step/stride length and velocity (if distance supplied)
- strikes : numpy array
- heel strike timings
- data : list or numpy array
- accelerometer data along forward axis
- duration : float
- duration of accelerometer reading (s)
- distance : float
- distance traversed
- number_of_steps : integer
- estimated number of steps based on heel strikes
- velocity : float
- velocity (if distance)
- avg_step_length : float
- average step length (if distance)
- avg_stride_length : float
- average stride length (if distance)
- cadence : float
- number of steps divided by duration
- step_durations : numpy array
- step durations
- avg_step_duration : float
- average step duration
- sd_step_durations : float
- standard deviation of step durations
- strides : list of two lists of floats
- stride timings for each side
- avg_number_of_strides : float
- estimated number of strides based on alternating heel strikes
- stride_durations : list of two lists of floats
- estimated stride durations
- avg_stride_duration : float
- average stride duration
- sd_step_durations : float
- standard deviation of stride durations
- step_regularity : float
- measure of step regularity along axis
- stride_regularity : float
- measure of stride regularity along axis
- symmetry : float
- measure of gait symmetry along axis
>>> from mhealthx.xio import read_accel_json, compute_sample_rate >>> input_file = '/Users/arno/DriveWork/mhealthx/mpower_sample_data/deviceMotion_walking_outbound.json.items-a2ab9333-6d63-4676-977a-08591a5d837f5221783798792869048.tmp' >>> device_motion = True >>> start = 150 >>> t, axyz, gxyz, uxyz, rxyz, sample_rate, duration = read_accel_json(input_file, start, device_motion) >>> ax, ay, az = axyz >>> from mhealthx.extractors.pyGait import heel_strikes >>> threshold = 0.2 >>> order = 4 >>> cutoff = 5 >>> data = ay >>> plot_test = False >>> strikes, strike_indices = heel_strikes(data, sample_rate, threshold, order, cutoff, plot_test) >>> from mhealthx.extractors.pyGait import gait >>> distance = 90 >>> a = gait(strikes, data, duration, distance)
-
mhealthx.extractors.pyGait.
gait_regularity_symmetry
(data, step_period, stride_period)¶ Compute step and stride regularity and symmetry from accelerometer data.
The iGAIT software assumes that the y-axis is anterior-posterior, and restricts some feature extraction to this orientation. In this program, we compute every measure for an arbitrary axis.
From Yang, et al., 2012:
“The peak value a1 = NFC(t1), which is found at the t1 lag time to be a step period, indicates the step regularity in a direction. The peak value a2 = NFC(t2), which was found at the t2 lag time to be a stride period, indicates the stride regularity in a direction. The variance of the stride regularity and step regularity D = |a2 - a1, can be used as an indicator to measure gait asymmetry. A smaller value of D indicates a more symmetric gait. A larger value of D indicates a more asymmetric gait. In total, iGAIT extracts seven regularity and symmetry features from the acceleration data, namely
- Step regularity: vertical (VT), anterior-posterior (AP) directions - Stride regularity: VT, AP, medial-lateral (ML) directions - Symmetry: VT, AP directions
- data : list or numpy array
- accelerometer data for one (preferably forward) axis
- step_period : integer
- step period
- stride_period : integer
- stride period
- step_regularity : float
- step regularity measure along axis
- stride_regularity : float
- stride regularity measure along axis
- symmetry : float
- symmetry measure along axis
>>> from mhealthx.xio import read_accel_json >>> from mhealthx.extractors.pyGait import gait_regularity_symmetry >>> input_file = '/Users/arno/DriveWork/mhealthx/mpower_sample_data/deviceMotion_walking_outbound.json.items-a2ab9333-6d63-4676-977a-08591a5d837f5221783798792869048.tmp' >>> device_motion = True >>> start = 150 >>> t, axyz, gxyz, uxyz, rxyz, sample_rate, duration = read_accel_json(input_file, start, device_motion) >>> ax, ay, az = axyz >>> data = ay >>> step_period = 2 >>> stride_period = 1 >>> step_regularity, stride_regularity, symmetry = gait_regularity_symmetry(data, step_period, stride_period)
-
mhealthx.extractors.pyGait.
heel_strikes
(data, sample_rate, threshold=0.2, order=4, cutoff=5, plot_test=False, t=None)¶ Estimate heel strike times between sign changes in accelerometer data.
The iGAIT software assumes that the y-axis is anterior-posterior, and restricts some feature extraction to this orientation. In this program, we compute heel strikes for an arbitrary axis.
Re: heel strikes (from Yang, et al., 2012): “The heel contacts are detected by peaks preceding the sign change of AP acceleration [3]. In order to automatically detect a heel contact event, firstly, the AP acceleration is low pass filtered by the 4th order zero lag Butterworth filter whose cut frequency is set to 5 Hz. After that, transitional positions where AP acceleration changes from positive to negative can be identified. Finally the peaks of AP acceleration preceding the transitional positions, and greater than the product of a threshold and the maximum value of the AP acceleration are denoted as heel contact events... This threshold is defined as the ratio to the maximum value of the AP acceleration, for example 0.5 indicates the threshold is set at 50% of the maximum AP acceleration. Its default value is set to 0.4 as determined experimentally in this paper, where this value allowed correct detection of all gait events in control subjects. However, when a more irregular pattern is analysed, the threshold should be less than 0.4. The user can test different threshold values and find the best one according to the gait event detection results.”
- data : list or numpy array
- accelerometer data along one axis (preferably forward direction)
- sample_rate : float
- sample rate of accelerometer reading (Hz)
- threshold : float
- ratio to the maximum value of the anterior-posterior acceleration
- order : integer
- order of the Butterworth filter
- cutoff : integer
- cutoff frequency of the Butterworth filter (Hz)
- plot_test : Boolean
- plot heel strikes?
- t : list or numpy array
- accelerometer time points
- strikes : numpy array of floats
- heel strike timings
- strike_indices : list of integers
- heel strike timing indices
>>> from mhealthx.xio import read_accel_json >>> from mhealthx.signals import compute_sample_rate >>> input_file = '/Users/arno/DriveWork/mhealthx/mpower_sample_data/deviceMotion_walking_outbound.json.items-a2ab9333-6d63-4676-977a-08591a5d837f5221783798792869048.tmp' >>> device_motion = True >>> start = 150 >>> t, axyz, gxyz, uxyz, rxyz, sample_rate, duration = read_accel_json(input_file, start, device_motion) >>> ax, ay, az = axyz >>> from mhealthx.extractors.pyGait import heel_strikes >>> threshold = 0.4 >>> order = 4 >>> cutoff = max([1, sample_rate/10]) >>> plot_test = True >>> data = np.abs(ax) + np.abs(ay) + np.abs(az) >>> strikes, strike_indices = heel_strikes(data, sample_rate, threshold, order, cutoff, plot_test, t)
-
mhealthx.extractors.pyGait.
project_axes
(vectors, unit_vectors)¶ Project vectors on unit vectors.
vectors : list of lists of x, y, z coordinates or numpy array equivalent unit_vectors : list of lists of x, y, z coordinates (or numpy arrays)
unit vectors to project vectors onto- projection_vectors : list of lists of x, y, z coordinates
- vectors projected onto unit vectors
>>> from mhealthx.xio import read_accel_json >>> from mhealthx.signals import compute_sample_rate >>> input_file = '/Users/arno/DriveWork/mhealthx/mpower_sample_data/deviceMotion_walking_outbound.json.items-a2ab9333-6d63-4676-977a-08591a5d837f5221783798792869048.tmp' >>> device_motion = True >>> start = 150 >>> t, axyz, gxyz, uxyz, rxyz, sample_rate, duration = read_accel_json(input_file, start, device_motion) >>> vectors = zip(axyz[0], axyz[1], axyz[2]) >>> vectors = [vectors[0], vectors[1], vectors[2]] >>> from mhealthx.extractors.pyGait import project_axes >>> unit_vectors = [1, 1, 1] >>> projection_vectors = project_axes(vectors, unit_vectors)
-
mhealthx.extractors.pyGait.
project_walk_direction_attitude
(ax, ay, az, uw, ux, uy, uz)¶ Project accelerometer data on local walk direction by attitude rotation.
- ax : list or numpy array
- x-axis accelerometer data
- ay : list or numpy array
- y-axis accelerometer data
- az : list or numpy array
- z-axis accelerometer data
- uw : list or numpy array
- w of attitude quaternion
- ux : list or numpy array
- x of attitude quaternion
- uy : list or numpy array
- y of attitude quaternion
- uz : list or numpy array
- z of attitude quaternion
- px : numpy array
- accelerometer data along x axis projected on unit vector
- py : numpy array
- accelerometer data along y axis projected on unit vector
- pz : numpy array
- accelerometer data along z axis projected on unit vector
>>> from mhealthx.xio import read_accel_json >>> from mhealthx.signals import compute_sample_rate >>> input_file = '/Users/arno/DriveWork/mhealthx/mpower_sample_data/deviceMotion_walking_outbound.json.items-a2ab9333-6d63-4676-977a-08591a5d837f5221783798792869048.tmp' >>> device_motion = True >>> start = 0 >>> t, axyz, gxyz, wxyz, rxyz, sample_rate, duration = read_accel_json(input_file, start, device_motion) >>> ax, ay, az = axyz >>> uw, ux, uy, uz = wxyz >>> from mhealthx.extractors.pyGait import project_walk_direction_attitude >>> px, py, pz = project_walk_direction_attitude(ax, ay, az, uw, ux, uy, uz)
-
mhealthx.extractors.pyGait.
project_walk_direction_preheel
(ax, ay, az, t, sample_rate, stride_fraction, threshold, order, cutoff)¶ Project accelerometer data on local walk (not cardinal) direction.
- NOTE::
- This calls walk_direction_preheel(), which computes a single walk direction. It does NOT estimate walking direction for every time point, like walk_direction_attitude().
- ax : numpy array
- accelerometer data along x axis
- ay : numpy array
- accelerometer data along y axis
- az : numpy array
- accelerometer data along z axis
- t : list or numpy array
- accelerometer time points
- sample_rate : float
- sample rate of accelerometer reading (Hz)
- stride_fraction : float
- fraction of stride assumed to be deceleration phase of primary leg
- threshold : float
- ratio to the maximum summed acceleration to extract peaks
- order : integer
- order of the Butterworth filter
- cutoff : integer
- cutoff frequency of the Butterworth filter (Hz)
- px : numpy array
- accelerometer data along x axis projected on unit vector
- py : numpy array
- accelerometer data along y axis projected on unit vector
- pz : numpy array
- accelerometer data along z axis projected on unit vector
>>> from mhealthx.xio import read_accel_json >>> from mhealthx.extractors.pyGait import project_walk_direction_preheel >>> input_file = '/Users/arno/DriveWork/mhealthx/mpower_sample_data/deviceMotion_walking_outbound.json.items-a2ab9333-6d63-4676-977a-08591a5d837f5221783798792869048.tmp' >>> device_motion = True >>> start = 150 >>> t, axyz, gxyz, uxyz, rxyz, sample_rate, duration = read_accel_json(input_file, start, device_motion) >>> ax, ay, az = axyz >>> stride_fraction = 1.0/8.0 >>> threshold = 0.5 >>> order = 4 >>> cutoff = max([1, sample_rate/10]) >>> px, py, pz = project_walk_direction_preheel(ax, ay, az, t, sample_rate, stride_fraction, threshold, order, cutoff)
-
mhealthx.extractors.pyGait.
walk_direction_attitude
(ax, ay, az, uw, ux, uy, uz, plot_test=False)¶ Estimate local walk (not cardinal) directions by rotation with attitudes.
Translated by Arno Klein from Elias Chaibub-Neto’s R code.
- ax : list or numpy array
- x-axis accelerometer data
- ay : list or numpy array
- y-axis accelerometer data
- az : list or numpy array
- z-axis accelerometer data
- uw : list or numpy array
- w of attitude quaternion
- ux : list or numpy array
- x of attitude quaternion
- uy : list or numpy array
- y of attitude quaternion
- uz : list or numpy array
- z of attitude quaternion
- plot_test : Boolean
- plot rotated vectors?
- directions : list of lists of three floats
- unit vector of local walk (not cardinal) direction at each time point
>>> from mhealthx.xio import read_accel_json >>> from mhealthx.signals import compute_sample_rate >>> input_file = '/Users/arno/DriveWork/mhealthx/mpower_sample_data/deviceMotion_walking_outbound.json.items-a2ab9333-6d63-4676-977a-08591a5d837f5221783798792869048.tmp' >>> device_motion = True >>> start = 0 >>> t, axyz, gxyz, wxyz, rxyz, sample_rate, duration = read_accel_json(input_file, device_motion, start) >>> ax, ay, az = axyz >>> uw, ux, uy, uz = wxyz >>> from mhealthx.extractors.pyGait import walk_direction_attitude >>> plot_test = True >>> directions = walk_direction_attitude(ax, ay, az, uw, ux, uy, uz, plot_test)
-
mhealthx.extractors.pyGait.
walk_direction_preheel
(ax, ay, az, t, sample_rate, stride_fraction=0.125, threshold=0.5, order=4, cutoff=5, plot_test=False)¶ Estimate local walk (not cardinal) direction with pre-heel strike phase.
Inspired by Nirupam Roy’s B.E. thesis: “WalkCompass: Finding Walking Direction Leveraging Smartphone’s Inertial Sensors,” this program derives the local walk direction vector from the end of the primary leg’s stride, when it is decelerating in its swing. While the WalkCompass relies on clear heel strike signals across the accelerometer axes, this program just uses the most prominent strikes, and estimates period from the real part of the FFT of the data.
- NOTE::
- This algorithm computes a single walk direction, and could compute multiple walk directions prior to detected heel strikes, but does NOT estimate walking direction for every time point, like walk_direction_attitude().
- ax : list or numpy array
- x-axis accelerometer data
- ay : list or numpy array
- y-axis accelerometer data
- az : list or numpy array
- z-axis accelerometer data
- t : list or numpy array
- accelerometer time points
- sample_rate : float
- sample rate of accelerometer reading (Hz)
- stride_fraction : float
- fraction of stride assumed to be deceleration phase of primary leg
- threshold : float
- ratio to the maximum value of the summed acceleration across axes
- plot_test : Boolean
- plot most prominent heel strikes?
- direction : numpy array of three floats
- unit vector of local walk (not cardinal) direction
>>> from mhealthx.xio import read_accel_json >>> from mhealthx.signals import compute_sample_rate >>> input_file = '/Users/arno/DriveWork/mhealthx/mpower_sample_data/deviceMotion_walking_outbound.json.items-a2ab9333-6d63-4676-977a-08591a5d837f5221783798792869048.tmp' >>> device_motion = True >>> start = 150 >>> t, axyz, gxyz, uxyz, rxyz, sample_rate, duration = read_accel_json(input_file, start, device_motion) >>> ax, ay, az = axyz >>> from mhealthx.extractors.pyGait import walk_direction_preheel >>> threshold = 0.5 >>> stride_fraction = 1.0/8.0 >>> order = 4 >>> cutoff = max([1, sample_rate/10]) >>> plot_test = True >>> direction = walk_direction_preheel(ax, ay, az, t, sample_rate, stride_fraction, threshold, order, cutoff, plot_test)