Tutorial EMG: Difference between revisions

From Software Product Documentation
Jump to navigation Jump to search
No edit summary
 
No edit summary
Line 6: Line 6:
This tutorial is a work in progress.....
This tutorial is a work in progress.....


Files used in this tutorial can be found here: [[http://www.c-motion.com/download/examples/EMG_Tutorial.zip  EMG Tutorial]]
Files used in this tutorial can be found here: [[https://www.c-motion.com/download/examples/EMG_Tutorial.zip  EMG Tutorial]]
=Introduction=
=Introduction=
'''EMG''' stands for '''electromyography''', which is the study of electrical signals from active muscles that are receiving input from the central nervous system. More information on EMG can be found in most good biomechanics and motor control textbooks, and on [http://en.wikipedia.org/wiki/Electromyography Wikipedia]. Additional information on EMG processing requirements for the [http://www.isek-online.org/standards.html International Society of Electrophysiology and Kinesiology]. You will also find other useful information on EMG signal processing posted by [[http://noraxon.com/downloads/educational.php3 Noraxon]]
'''EMG''' stands for '''electromyography''', which is the study of electrical signals from active muscles that are receiving input from the central nervous system. More information on EMG can be found in most good biomechanics and motor control textbooks, and on [http://en.wikipedia.org/wiki/Electromyography Wikipedia]. Additional information on EMG processing requirements for the [http://www.isek-online.org/standards.html International Society of Electrophysiology and Kinesiology]. You will also find other useful information on EMG signal processing posted by [[http://noraxon.com/downloads/educational.php3 Noraxon]]

Revision as of 15:36, 22 August 2022

Language:  English  • français • italiano • português • español 

This tutorial is a work in progress.....

Files used in this tutorial can be found here: [EMG Tutorial]

Introduction

EMG stands for electromyography, which is the study of electrical signals from active muscles that are receiving input from the central nervous system. More information on EMG can be found in most good biomechanics and motor control textbooks, and on Wikipedia. Additional information on EMG processing requirements for the International Society of Electrophysiology and Kinesiology. You will also find other useful information on EMG signal processing posted by [Noraxon]

Visual 3D Implementation

Visual3D expects the EMG signals to be stored in the C3D file as ANALOG data, not unlike force platform data. One point of importance is that EMG typically has very high frequency content, which means that it must be sampled at high data sampling rates.

As of Visual3D Version 5.0 EMG signals are stored as integer multiples of the Motion Capture sampling rate (e.g. consistent with the common use of the C3D file format). One of the nuisances caused by this requirement is that force platform data must be sampled at a very high rate in order to match the EMG sampling rate.

All signal processing commands in the pipeline can be used with EMG data.

EMG Processing using Visual 3D Pipeline commands

The tutorial will go through a step by step process using Visual 3D pipeline commands to process the example EMG data.

Open Files and Tag

This section will walk you through pipeline commands that will open files and automatically assign tags to motion files for Movement and MVIC trials.

!--------------------------------------------------------------------------------------
! Open files and automatically assign tag to motion files for Movement and MVIC trials
! --------------------------------------------------------------------------------------
 
! Fresh Workspace
File_New
;

!Open files
File_Open
! /FILE_NAME=
;

!Assign Tags to MVC_A file
Assign_Tags_To_File
/MOTION_FILE_NAMES=*MVC_A.C3D
! /QUERY=
/TAGS=MVC_A
;

!Assign Tags to MVC_B file
Assign_Tags_To_File
/MOTION_FILE_NAMES=*MVC_B.C3D
! /QUERY=
/TAGS=MVC_B
;

!Assign Tags to MVC_C file
Assign_Tags_To_File
/MOTION_FILE_NAMES=*MVC_C.C3D
! /QUERY=
/TAGS=MVC_C
';

!Assign Tags to walking files
Assign_Tags_To_File
/MOTION_FILE_NAMES=*trial*.C3D
!/QUERY=
/TAGS=MOVEMENT
;

Create Pipeline Parameter "EMG Signals"

Use the command Set_Pipeline_Parameter, to set up a pipeline parameter to contain the EMG signal names.

Set_Pipeline_Parameter
/PARAMETER_NAME=EMG_SIGNALS
/PARAMETER_VALUE=EMG_A+EMG_B+EMG_C
;

Apply a Band Pass Filter

Apply a band pass filter to the EMG data with the commands Highpass_Filter and Lowpass_Filter. Surface EMG signals have a frequency content between 20 and 500 Hz.

Note: that the highpass filter often has a cutoff frequency anywhere between 20 and 50 Hz. The purpose of this high pass filter is to remove movement artifact (low frequency content).

!-------------------------------------------------------------
! Apply a band pass filter - highpass and lowpass filter
!------------------------------------------------------------- 

! Select active file ALL_FILES
Select_Active_File 
/FILE_NAME=ALL_FILES 
! /QUERY= 
;

! Apply highpass filter with 50 Hz cutoff
Highpass_Filter 
/Signal_Types=ANALOG 
/SIgnal_Names=::EMG_SIGNALS 
/Signal_Folder=ORIGINAL 
! /Result_Suffix= 
! /Result_Folder=PROCESSED 
! /Filter_Class=BUTTERWORTH 
/Frequency_Cutoff=50 
/Num_Reflected= 0 
/Total_Buffer_Size=100 
/Num_Bidirectional_Passes=1 
; 

! Apply lowpass filter with 500 Hz cutoff
Lowpass_Filter 
/Signal_Types=ANALOG 
/SIgnal_Names=::EMG_SIGNALS 
/Signal_Folder=PROCESSED 
! /Result_Suffix= 
! /Result_Folder=PROCESSED 
! /Filter_Class=BUTTERWORTH 
/Frequency_Cutoff=500 
/Num_Reflected= 0 
/Total_Buffer_Size=100 
/Num_Bidirectional_Passes=1 
;

Compute an Envelope

We will compute the linear envelope of the EMG signal by calculating the RMS value using the command Moving_RMS for short successive time periods (the time period is described as a moving window). In Visual3D the windows overlap. The output value at each frame is the RMS of the window centered on that frame (e.g. the RMS value for each window is plotted at the time corresponding to its center). The number of frames in the window must be an odd number. This is a moving average. So, if the window was 11 frames.

The first output frame is frame 6 computed from frames 1-11.
The second output frame is frame 7 computed from frames 2-12 Etc.

Note: A window of T seconds is approximately equivalent to a lowpass filter with a cutoff frequency = 1/(2T)

The command below will apply a moving RMS with a 100ms window

!-------------------------------------------
! Apply a moving RMS with a 100ms window
!-------------------------------------------
Moving_RMS 
/SIGNAL_TYPES=ANALOG 
/SIGNAL_NAMES=::EMG_SIGNALS 
/SIGNAL_FOLDER=PROCESSED 
! /RESULT_SUFFIX= 
/RESULT_FOLDER=RMS 
/NUM_WINDOW_FRAMES=1+0.1*PARAMETER::ANALOG::RATE 
;

Create Normalization Factor and Scale

There are two alternate methods described in this tutorial. The second method calculates the scale factor for EMG_A only from file MVC_A, scale factor for EMG_B only from file MVC_B, and so on. The first method calculates the normalization factor (or scale) for EMG_A from the maximum calculated scale factor for EMG_A regardless of MVC file.

Alternate Method 1

Normalize to greatest ½ second activity during 5 second trial. A window of twenty-five .02 second intervals of integrated EMG is moved one interval at a time across the 5 seconds of data to find the greatest EMG. The average integrated EMG during the ½ second is used to compute the normalization factor. The task is as follows:

  • Compute a normalization factor
  • Normalize to greatest ½ second during 5 second trial.
    This is accomplished by using an average filter (see the bottom of the page)
  • A window of twenty-five .02 second intervals of integrated EMG is moved one interval at a time across the 5 seconds of data to find the greatest EMG.
  • The average integrated EMG during the ½ second is used to compute the normalization factor.
!--------------------------------------------------------------------------------------------------
! There are often artifacts in the EMG signal related to filtering, so we want to ignore the first
! and last 50 frames of data (at POINT rate) when we create the normalization (scale) factors
!--------------------------------------------------------------------------------------------------

Event_Explicit
/EVENT_NAME=START
/FRAME=50
! /TIME=
;

Event_Explicit
/EVENT_NAME=END
/FRAME=250
! /TIME=
;

!---------------------------------------------------
! Set Pipeline parameters for START and END events
!---------------------------------------------------

Set_Pipeline_Parameter 
/PARAMETER_NAME=START_AT_EVENT 
/PARAMETER_VALUE=START 
;

Set_Pipeline_Parameter 
/PARAMETER_NAME=END_AT_EVENT  
/PARAMETER_VALUE=END 
;

!---------------------------------------------------
! Loop to calculate scale to normalize EMG signals
!---------------------------------------------------
For_Each 
/ITERATION_PARAMETER_NAME=INDEX 
/ITEMS=::EMG_SIGNALS 
;

! Create an event at the maximum value
Event_Global_Maximum 
/SIGNAL_TYPES=ANALOG 
/SIGNAL_NAMES=::INDEX 
/SIGNAL_FOLDER=RMS 
/EVENT_NAME=EMG_MAX 
/SELECT_X=TRUE 
! /SELECT_Y=FALSE 
! /SELECT_Z=FALSE 
/START_AT_EVENT=::START_AT_EVENT 
/END_AT_EVENT=::END_AT_EVENT 
;

! Create an event MEAN_START 15 frames prior to the max event
Event_Copy 
/EVENT_NAME=EMG_MAX 
! /EVENT_INSTANCE=0 
! /START_AT_EVENT= 
! /END_AT_EVENT= 
/NEW_EVENT_NAME=MEAN_START 
/FRAME_OFFSET=-15 
;

! Create an event MEAN_END 15 frames after the max event
Event_Copy 
/EVENT_NAME=EMG_MAX 
! /EVENT_INSTANCE=0 
! /START_AT_EVENT= 
! /END_AT_EVENT= 
/NEW_EVENT_NAME=MEAN_END 
/FRAME_OFFSET=15 
; 

! Calculate mean of EMG signal between MEAN_START and MEAN_END 
Metric_Mean 
/RESULT_METRIC_NAME=::INDEX&_SCALE 
! /APPLY_AS_SUFFIX_TO_SIGNAL_NAME=FALSE 
/RESULT_METRIC_FOLDER=EMG_SCALE 
/SIGNAL_TYPES=ANALOG 
/SIGNAL_NAMES=::INDEX 
/SIGNAL_FOLDER=RMS 
/SIGNAL_COMPONENTS=0 
/EVENT_SEQUENCE=MEAN_START+MEAN_END 
/EXCLUDE_EVENTS= 
/GENERATE_MEAN_AND_STDDEV=FALSE 
! /APPEND_TO_EXISTING_VALUES=FALSE 
;

! calculate the global maximum of the mean signal
Metric_Maximum 
/RESULT_METRIC_NAME=_MAX 
/APPLY_AS_SUFFIX_TO_SIGNAL_NAME=TRUE 
/RESULT_METRIC_FOLDER=PROCESSED 
/SIGNAL_TYPES=METRIC 
/SIGNAL_NAMES=::INDEX&_SCALE 
/SIGNAL_FOLDER=EMG_SCALE 
! /SIGNAL_COMPONENTS=ALL_COMPONENTS 
/EVENT_SEQUENCE= 
/EXCLUDE_EVENTS= 
! /GENERATE_MEAN_AND_STDDEV=TRUE 
! /APPEND_TO_EXISTING_VALUES=FALSE 
/CREATE_GLOBAL_MAXIMUM=FALSE 
;

! Clean up some temporary signals 
Event_Delete 
/EVENT_NAME=EMG_MAX+MEAN_START+MEAN_END 
! /EVENT_SEQUENCE= 
! /EXCLUDE_EVENTS= 
! /TIME= 
;

Remove_Signals 
/SIGNAL_TYPES=METRIC 
/SIGNAL_NAMES=::INDEX&_SCALE_MAX 
/SIGNAL_FOLDER=PROCESSED 
;

End_For_Each 
/ITERATION_PARAMETER_NAME=INDEX 
;

! --------------------------------------------------------------- 
! Divide by the EMG Normalization Scale Factor 
! --------------------------------------------------------------- 
For_Each 
/ITERATION_PARAMETER_NAME=INDEX 
/ITEMS=::EMG_SIGNALS 
;

Evaluate_Expression 
/EXPRESSION=ANALOG::RMS&:&:&::INDEX&/&GLOBAL::METRIC::PROCESSED&:&:&::INDEX&_SCALE_MAX_MEAN 
/RESULT_NAME=::INDEX 
/RESULT_TYPE=ANALOG 
/RESULT_FOLDER=RESULT 
;

End_For_Each 
/ITERATION_PARAMETER_NAME=INDEX 
;

Alternate Method 2

This normalization scale method calculates the scale factor for EMG_A only from file MVC_A, scale factor for EMG_B only from file MVC_B, and so on.

!--------------------------------------------------------------------------------------------------
! There are often artifacts in the EMG signal related to filtering, so we want to ignore the first
! and last 50 frames of data (at POINT rate) when we create the normalization (scale) factors
!--------------------------------------------------------------------------------------------------

Event_Explicit
/EVENT_NAME=START
/FRAME=50
! /TIME=
;

Event_Explicit
/EVENT_NAME=END
/FRAME=250
! /TIME=
;

!---------------------------------------------------
! Set Pipeline parameters for START and END events
!---------------------------------------------------

Set_Pipeline_Parameter 
/PARAMETER_NAME=START_AT_EVENT 
/PARAMETER_VALUE=START 
;

Set_Pipeline_Parameter 
/PARAMETER_NAME=END_AT_EVENT  
/PARAMETER_VALUE=END 
;

!---------------------------------------------------
! Loop to calculate scale to normalize EMG signals
!---------------------------------------------------
For_Each 
/ITERATION_PARAMETER_NAME=INDEX 
/ITEMS=_A+_B+_C 
;

! Select active file MVC file
Select_Active_File 
/FILE_NAME=MVC&::INDEX 
! /QUERY= 
;

! Create an event at the maximum value
Event_Global_Maximum 
/SIGNAL_TYPES=ANALOG 
/SIGNAL_NAMES=EMG&::INDEX 
/SIGNAL_FOLDER=RMS 
/EVENT_NAME=EMG&::INDEX&_MAX 
/SELECT_X=TRUE 
! /SELECT_Y=FALSE 
! /SELECT_Z=FALSE 
/START_AT_EVENT=::START_AT_EVENT 
/END_AT_EVENT=::END_AT_EVENT 
;

! Create an event MEAN_START 15 frames prior to the max event
Event_Copy 
/EVENT_NAME=EMG&::INDEX&_MAX 
! /EVENT_INSTANCE=0 
! /START_AT_EVENT= 
! /END_AT_EVENT= 
/NEW_EVENT_NAME=MEAN_START 
/FRAME_OFFSET=-15 
;

! Create an event MEAN_END 15 frames prior to the max event
Event_Copy 
/EVENT_NAME=EMG&::INDEX&_MAX 
! /EVENT_INSTANCE=0 
! /START_AT_EVENT= 
! /END_AT_EVENT= 
/NEW_EVENT_NAME=MEAN_END 
/FRAME_OFFSET=15 
;

! Calculate global mean of EMG signal between MEAN_START and MEAN_END
Metric_Mean 
/RESULT_METRIC_NAME=EMG&::INDEX&_SCALE 
! /APPLY_AS_SUFFIX_TO_SIGNAL_NAME=FALSE 
/RESULT_METRIC_FOLDER=EMG_NORM 
/SIGNAL_TYPES=ANALOG 
/SIGNAL_NAMES=EMG&::INDEX 
/SIGNAL_FOLDER=RMS 
/SIGNAL_COMPONENTS=0 
/EVENT_SEQUENCE=MEAN_START+MEAN_END 
/EXCLUDE_EVENTS= 
/GENERATE_MEAN_AND_STDDEV=TRUE 
! /APPEND_TO_EXISTING_VALUES=FALSE 
;

End_For_Each 
/ITERATION_PARAMETER_NAME=INDEX 
;

! Select active file MOVEMENT files
Select_Active_File 
/FILE_NAME=MOVEMENT
! /QUERY= 
;

! --------------------------------------------------------------- 
! Divide by the EMG Normalization Scale Factor 
! --------------------------------------------------------------- 
For_Each 
/ITERATION_PARAMETER_NAME=INDEX 
/ITEMS=_A+_B+_C 
;

Evaluate_Expression 
/EXPRESSION=ANALOG::RMS::EMG&::INDEX&/&GLOBAL::METRIC::EMG_NORM::EMG&::INDEX&_SCALE_MEAN
/RESULT_NAME=EMG&::INDEX
/RESULT_TYPE=ANALOG 
/RESULT_FOLDER=RESULT2 
;

End_For_Each 
/ITERATION_PARAMETER_NAME=INDEX 
;
Retrieved from ""