keenon / AddBiomechanics

A tool to automatically process and share biomechanics data
https://addbiomechanics.org/
Other
24 stars 5 forks source link

lowpass filter problem #262

Open hitefork opened 2 months ago

hitefork commented 2 months ago

I used data from the SMPL model, with a frame rate of 30Hz.When I attempted to convert the data, I encountered the following issues:

Running lowpass filter
Traceback (most recent call last):
  File "/app/src/../../engine/src/engine.py", line 105, in <module>
    main()
  File "/app/src/../../engine/src/engine.py", line 75, in main
    subject.lowpass_filter()
  File "/engine/src/subject.py", line 567, in lowpass_filter
    success = trial_segment.lowpass_filter(self.kinematics_skeleton, self.lowpass_hz)
  File "/engine/src/trial.py", line 392, in lowpass_filter
    b, a = butter(2, lowpass_hz, 'low', fs=1 / self.parent.timestep)
  File "/usr/local/lib/python3.8/dist-packages/scipy/signal/_filter_design.py", line 3094, in butter
    return iirfilter(N, Wn, btype=btype, analog=analog,
  File "/usr/local/lib/python3.8/dist-packages/scipy/signal/_filter_design.py", line 2554, in iirfilter
    raise ValueError("Digital filter critical frequencies must "
ValueError: Digital filter critical frequencies must be 0 < Wn < fs/2 (fs=30.014534883720934 -> fs/2=15.007267441860467)
davidpagnon commented 1 month ago

Same problem that I also brought up there.

From the error message, it seems like the issue is that the cut-off frequency (lowpass_hz ) is defined as 30, while the SMPL sequence frequency is also 30 Hz. According to the Nyquist-Shannon theorem, the sequence frequency should be at least twice the cut-off frequency, hence the error.

Now I am not sure of it since if so, I don't know how it has ever worked. @MarilynKeller, can you still process trc files from SMPL data with AddBiomechanics?

MarilynKeller commented 1 month ago

Hi, I think when using AddBiomechanics I only used SMPL sequences that were 60 FPS or beyond, so I did not run into this problem.

If your SMPL sequence is 30 FPS and AddBiomechanics needs at least 60 FPS, you could interpolate your SMPL sequence. The idea is to interpolate the pose and translation parameter to transform your sequence of F frames to F*2 frames (fps_in=30, fps_out=60).

You can proceed as done here:

# Reshape the pose vector to be (F, J, 3) (J: nb of joints, F: nb of frames)
ps = np.reshape(poses, [poses.shape[0], -1, 3]) 
# Resample rotations using cubic interpolation in SO(3)
ps_new = resample_rotations(ps, fps_in, fps_out)
# Reshape poses back to (F, J*3)
poses = np.reshape(ps_new, [-1, poses.shape[1]])
# Resample translation 
trans = resample_positions(trans, fps_in, fps_out)

If you use the repo SMPL2Addbiomechanics, this should be done to interpolate the smple_data before running the SMPL pass (here) to generate the marker sequences. The generated marker sequence will then have 2*F frames, so double FPS.

davidpagnon commented 1 month ago

Interesting! The interpolation functions are already written so it should be rather straightforward. Now it also means that it will double the size of my dataset. I'll have to think about it, thanks for the tip!

hitefork commented 1 month ago

Thanks!Now I know how to process my data (^-^*)/ !