Closed 408550969 closed 4 months ago
是的,可以调大N来增强精度,如果不在意计算时间的话。 如果训练是PPG作为标签,这个N和训练无关。
当我fs设置为30,连续采样180帧数据时,根据函数: def _calculate_fft_hr(ppg_signal, fs=60, low_pass=0.75, high_pass=2.5): """Calculate heart rate based on PPG using Fast Fourier transform (FFT).""" ppg_signal = np.expand_dims(ppg_signal, 0) N = _next_power_of_2(ppg_signal.shape[1]) f_ppg, pxx_ppg = scipy.signal.periodogram(ppg_signal, fs=fs, nfft=N, detrend=False) fmask_ppg = np.argwhere((f_ppg >= low_pass) & (f_ppg <= high_pass)) mask_ppg = np.take(f_ppg, fmask_ppg) mask_pxx = np.take(pxx_ppg, fmask_ppg) fft_hr = np.take(mask_ppg, np.argmax(mask_pxx, 0))[0] 60 return fft_hr 心率的分辨率为7,现在我想提高心率的分辨率,我的做法是当fs为30时,直接让N等于2048,这样根据公式30/204860,心率的分辨率小于1,实际测下来也是这样。我想问一下我这样做正确吗? 还有一个问题,在训练模型时,_calculate_fft_hr中的ppg_signal默认也是180大小,那么根据这个函数,得到的心率分辨率是7,如果我在训练的时候也把N改成2048,这样对模型的训练有帮助吗?
Hi @408550969 the HR beat frequency resolution with fs = 30Hz, and 180 frames (samples) is 30 / 180 hz, giving a frequency resolution of 0.1667Hz per frequency bin. I would avoid upsampling to improve frequency resolution. This is a fallacy and can be deterministically predicted given the interpolation method you use. This WILL NOT introduce additional real/useful frequency content to your signal. Also note, that longer observation windows (etc.) 2048 samples (~70 seconds), will provide a single measure of HR for that minute long span (albeit with higher frequency resolution). This is the average HR for that observation period, and begins to lose its utility when averaged over too long a time period.
这是rPPG-Toolbox作者的回复,对于实际应用来说,一般不会让用户盯着相机1分钟来得到过去一分钟的心率,而过低的N会导致心率的波动范围很大。现在的心率检测设备都是手指放进去几秒就能得到结果(例如HKG-07C+),这些设备的做法是否也是类似调大N?
算法这块我们在ToolBox仓库讨论吧,我也是ToolBox的作者,我先暂时关闭这个issue
好的,谢谢
当我fs设置为30,连续采样180帧数据时,根据函数: def _calculate_fft_hr(ppg_signal, fs=60, low_pass=0.75, high_pass=2.5): """Calculate heart rate based on PPG using Fast Fourier transform (FFT).""" ppg_signal = np.expand_dims(ppg_signal, 0) N = _next_power_of_2(ppg_signal.shape[1]) f_ppg, pxx_ppg = scipy.signal.periodogram(ppg_signal, fs=fs, nfft=N, detrend=False) fmask_ppg = np.argwhere((f_ppg >= low_pass) & (f_ppg <= high_pass)) mask_ppg = np.take(f_ppg, fmask_ppg) mask_pxx = np.take(pxx_ppg, fmask_ppg) fft_hr = np.take(mask_ppg, np.argmax(mask_pxx, 0))[0] 60 return fft_hr 心率的分辨率为7,现在我想提高心率的分辨率,我的做法是当fs为30时,直接让N等于2048,这样根据公式30/204860,心率的分辨率小于1,实际测下来也是这样。我想问一下我这样做正确吗? 还有一个问题,在训练模型时,_calculate_fft_hr中的ppg_signal默认也是180大小,那么根据这个函数,得到的心率分辨率是7,如果我在训练的时候也把N改成2048,这样对模型的训练有帮助吗?