.. DO NOT EDIT. .. THIS FILE WAS AUTOMATICALLY GENERATED BY SPHINX-GALLERY. .. TO MAKE CHANGES, EDIT THE SOURCE PYTHON FILE: .. "auto_examples/stride_segmentation/barth_dtw_stride_segmentation_roi.py" .. LINE NUMBERS ARE GIVEN BELOW. .. only:: html .. note:: :class: sphx-glr-download-link-note Click :ref:`here ` to download the full example code .. rst-class:: sphx-glr-example-title .. _sphx_glr_auto_examples_stride_segmentation_barth_dtw_stride_segmentation_roi.py: .. _roi_stride_segmentation: Stride segmentation with Regions of Interest ============================================ In long datasets it might be desirable to predefine regions of interest in which strides should be segmented. This can massively speed up the computation or focus the analysis on a specific part of the data. Most of the time such regions of interest would be defined using some sort of gait detection algorithms (e.g. :mod:`~gaitmap.gait_detection.UllrichGaitSequenceDetection`). In this example we will create an example output of such an algorithms and will use it to limit the search region for the `BarthDtw` stride segmentation algorithms. However, all other stride segmentation algorithms should this functionality as well. Note, that for smaller datasets, the algorithms might actually be slower when using multiple regions of interest, compared to analysing the entire dataset. This is, because the method relies on a slow Python loop to process the individual regions of interest. .. GENERATED FROM PYTHON SOURCE LINES 20-26 .. code-block:: default import matplotlib.pyplot as plt import numpy numpy.random.seed(0) .. GENERATED FROM PYTHON SOURCE LINES 27-35 Getting some example data -------------------------- For this we take some example data that contains the regular walking movement during a 2x20m walk test of a healthy subject. The IMU signals are already rotated so that they align with the gaitmap SF coordinate system. The data contains information from two sensors - one from the right and one from the left foot. We will further convert the data into the body frame, as this is required by the `BarthDTW` method to perform the stride segmentation. .. GENERATED FROM PYTHON SOURCE LINES 35-45 .. code-block:: default from gaitmap.example_data import get_healthy_example_imu_data from gaitmap.utils.coordinate_conversion import convert_to_fbf data = get_healthy_example_imu_data() sampling_rate_hz = 204.8 bf_data = convert_to_fbf(data, left_like="left_", right_like="right_") data.sort_index(axis=1).head(1) .. raw:: html
sensor left_sensor right_sensor
axis acc_x acc_y acc_z gyr_x gyr_y gyr_z acc_x acc_y acc_z gyr_x gyr_y gyr_z
0.0 0.880811 2.762208 9.40865 -0.112402 -0.032157 -0.062261 0.311553 -2.398646 9.513275 -0.323037 0.084604 -0.025288


.. GENERATED FROM PYTHON SOURCE LINES 46-51 Defining regions of interest ---------------------------- We will define two regions of interest (one at the beginning and one at the end of the dataset). We expect the algorithm to only find strides in these regions. .. GENERATED FROM PYTHON SOURCE LINES 51-57 .. code-block:: default import pandas as pd roi = pd.DataFrame([[0, 2000], [5000, 7500]], columns=["start", "end"]) roi.index.name = "roi_id" roi .. raw:: html
start end
roi_id
0 0 2000
1 5000 7500


.. GENERATED FROM PYTHON SOURCE LINES 58-61 Setting up the Stride Segmentation ---------------------------------- We will use BarthDTW with the default settings. .. GENERATED FROM PYTHON SOURCE LINES 61-65 .. code-block:: default from gaitmap.stride_segmentation import BarthDtw dtw = BarthDtw() .. GENERATED FROM PYTHON SOURCE LINES 66-69 Setting up the ROI wrapper -------------------------- To apply our method to multiple regions of interest wie use the `RoiStrideSegmentation` wrapper. .. GENERATED FROM PYTHON SOURCE LINES 69-73 .. code-block:: default from gaitmap.stride_segmentation import RoiStrideSegmentation roi_seg = RoiStrideSegmentation(segmentation_algorithm=dtw) .. GENERATED FROM PYTHON SOURCE LINES 74-77 Applying the segmentation ------------------------- Instead of our original dtw object we now use the wrapper with the same inputs to segment. .. GENERATED FROM PYTHON SOURCE LINES 77-79 .. code-block:: default roi_seg = roi_seg.segment(data=bf_data, sampling_rate_hz=sampling_rate_hz, regions_of_interest=roi) .. GENERATED FROM PYTHON SOURCE LINES 80-84 Inspecting the results ---------------------- The wrapper will automatically combine all stride lists from all ROIs into one. The additional "roi_id" column indicates in which ROI a stride was identified in. .. GENERATED FROM PYTHON SOURCE LINES 84-89 .. code-block:: default stride_list_left = roi_seg.stride_list_["left_sensor"] print(f"{len(stride_list_left)} strides were detected.") stride_list_left .. rst-class:: sphx-glr-script-out .. code-block:: none 16 strides were detected. .. raw:: html
roi_id start end
s_id
0 0 364 584
1 0 584 802
2 0 802 1023
3 0 1023 1242
4 0 1242 1458
5 0 1458 1672
6 0 1672 1887
7 1 5043 5267
8 1 5267 5489
9 1 5489 5713
10 1 5713 5936
11 1 5936 6167
12 1 6167 6395
13 1 6395 6628
14 1 6628 6858
15 1 6858 7091


.. GENERATED FROM PYTHON SOURCE LINES 90-97 All other outputs of our stride segmentation method are not accumulated, as they differ from method to method. However, we can inspect the individual instances stored in the `instances_per_roi_` attribute to get this information. In the following we will plot the cost matrices that are created for ROI. We will see that we now have multiple cost matrices and cost functions per sensor. This is simply because the DTW was applied separately to the two regions. To plot the outputs together, we need to loop all dtw instances. .. GENERATED FROM PYTHON SOURCE LINES 97-127 .. code-block:: default import numpy as np # Create combined outputs sensor = "left_sensor" cost_funcs = {roi: dtw.cost_function_[sensor] for roi, dtw in roi_seg.instances_per_roi_.items()} cost_mat = {roi: dtw.acc_cost_mat_[sensor] for roi, dtw in roi_seg.instances_per_roi_.items()} full_cost_matrix = np.full((len(roi_seg.segmentation_algorithm.template.get_data()), len(roi_seg.data)), np.nan) fig, axs = plt.subplots(nrows=3, sharex=True, figsize=(10, 5)) roi_seg.data[sensor]["gyr_ml"].reset_index(drop=True).plot(ax=axs[0]) axs[0].set_ylabel("gyro [deg/s]") for roi, (start, end) in roi_seg.regions_of_interest[["start", "end"]].iterrows(): axs[1].plot(np.arange(start, end), cost_funcs[roi], c="C0") full_cost_matrix[:, start:end] = cost_mat[roi] axs[1].set_ylabel("dtw cost [a.u.]") axs[1].axhline(roi_seg.segmentation_algorithm.max_cost, color="k", linestyle="--") axs[2].imshow(full_cost_matrix, aspect="auto") axs[2].set_ylabel("template position [#]") for roi_id, dtw_instance in roi_seg.instances_per_roi_.items(): roi_start = roi_seg.regions_of_interest.loc[roi_id]["start"] for p in dtw_instance.paths_[sensor]: axs[2].plot(p.T[1] + roi_start, p.T[0]) for start, end in dtw_instance.matches_start_end_original_[sensor]: axs[1].axvspan(start + roi_start, end + roi_start, alpha=0.3, color="g") for _, s in roi_seg.stride_list_[sensor][["start", "end"]].iterrows(): axs[0].axvspan(*s, alpha=0.3, color="g") axs[0].set_xlabel("time [#]") fig.tight_layout() fig.show() .. image-sg:: /auto_examples/stride_segmentation/images/sphx_glr_barth_dtw_stride_segmentation_roi_001.png :alt: barth dtw stride segmentation roi :srcset: /auto_examples/stride_segmentation/images/sphx_glr_barth_dtw_stride_segmentation_roi_001.png :class: sphx-glr-single-img .. rst-class:: sphx-glr-timing **Total running time of the script:** ( 0 minutes 2.298 seconds) **Estimated memory usage:** 59 MB .. _sphx_glr_download_auto_examples_stride_segmentation_barth_dtw_stride_segmentation_roi.py: .. only:: html .. container:: sphx-glr-footer sphx-glr-footer-example .. container:: sphx-glr-download sphx-glr-download-python :download:`Download Python source code: barth_dtw_stride_segmentation_roi.py ` .. container:: sphx-glr-download sphx-glr-download-jupyter :download:`Download Jupyter notebook: barth_dtw_stride_segmentation_roi.ipynb ` .. only:: html .. rst-class:: sphx-glr-signature `Gallery generated by Sphinx-Gallery `_