I have data samples for an EMG signal of three arm reps. In the data I have 1 signal that is flat then fluctuates in voltage then becomes flat again shows three pulses for each rep. I want to separate the three reps from the signal (chop the signal into 3 parts). I can manually do this by plotting the signal then zooming in and finding the index before the variance in voltage fluctuates and after it flat lines again. I wanted to know if there is an automated way to do this. Some sort of greedy algorithm or a built in Matlab function. Any ideas?

One example:


So I would want:

1 [-40,-45,80,85]
2 [-100,-105,80,85]
3 [-200,-45,305,85]

Usually the flat line values vary from zero.

  • $\begingroup$ Do you have any model for what the three pulses look like? Is it different from how the rest of the signal behaves? $\endgroup$ – Peter K. May 31 '16 at 18:37
  • $\begingroup$ I only have the raw data. Each pulse corresponds to one arm rep. $\endgroup$ – wwjdm May 31 '16 at 18:46

This is a little hacky, but it uses the three models you have to find an "eigen"-pulse and then takes successive inner products of a normalized signal segment with this "eigen"-pulse to give a measure between -1.0 and 1.0.

The red line in the image is your data. The black line is this normalized measure. You'll have to sanity check it (no detections within 2 samples of a previous detection ?), but other than that selecting anything above 0.8 should let you detect the start of the pulses.

enter image description here

R Code Below


  arm <- c(12,-23,1,-2,-40,-45,80,85,14,-28,10,-22,-100,-105,80,85,14,-2, 16,-2,-200,-45,305,85,1,-2,1,-2)

  #1 [-40,-45,80,85]
  #2 [-100,-105,80,85]
  #3 [-200,-45,305,85]
  rep1 <- c(-40,-45,80,85)
  rep2 <- c(-100,-105,80,85)
  rep3 <- c(-200,-45,305,85)

  repMat <- rep1 %*% t(rep1) + rep2 %*% t(rep2) + rep3 %*% t(rep3);
  mean1 <- (rep1+rep2+rep2)/3

  eigs <- eigen(repMat)

  plot(rep1, ylim=c(-350, 350), col="red", lwd=6, type="l")
  lines(rep2, col="green", lwd=4)
  lines(rep3, col="blue", lwd=2)
  lines(eigs$vectors[,1]*sqrt(eigs$values[1]), col="purple", lwd=1)

  eigs$vectors[,1] %*% rep1

  similarity <- rep(0,length(arm))
  for (idx in seq(1,length(arm)-3))
    patch <- arm[idx + seq(0,3)]
    patch <- patch / sqrt(sum(patch ^ 2))
    similarity[idx] <- (eigs$vectors[,1] %*% patch)

  plot(similarity, type="l")
  lines(arm/max(arm), col="red")
| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.