полосовой фильтр ValueError: Критические частоты цифрового фильтра должны быть 0 ‹ Wn ‹ 1

Я пытаюсь использовать полосовой фильтр для сигналов ЭКГ, это код:

from scipy.signal import butter

def bandpass_filter(self, data, lowcut, highcut, signal_freq, filter_order):
        nyquist_freq = 0.5 * signal_freq
        low = lowcut / nyquist_freq
        high = highcut / nyquist_freq
        b, a = butter(filter_order, [low, high], btype='band', analog=False)
        y = lfilter(b,a, data)
        return y

def detect_peaks(self):
    self.filtered_ecg_measurements = self.bandpass_filter(ecg_measurements,
                                         lowcut=self.filter_lowcut,
                                         highcut=self.filter_highcut,
                                         signal_freq=self.signal_frequency,
                                         filter_order=self.filter_order)
    self.signal_frequency = 250  
    self.filter_lowcut = 0.0
    self.filter_highcut = 15.0
    self.filter_order = 1

Эта ошибка появляется каждый раз, когда я пытаюсь запустить эту функцию:

Traceback (most recent call last):
  File "D:/Project/code/untitled/test.py", line 297, in <module>
    log_data=True, plot_data=True, show_plot=False)
  File "D:/Project/code/untitled/test.py", line 98, in __init__
    self.detect_peaks()
  File "D:/Project/code/untitled/test.py", line 135, in detect_peaks
    filter_order=self.filter_order)
  File "D:/Project/code/untitled/test.py", line 256, in bandpass_filter
    b, a = butter(filter_order, [low, high], btype='band', analog=False)
  File "C:\Users\AppData\Roaming\Python\Python36\site-packages\scipy\signal\filter_design.py", line 2394, in butter
    output=output, ftype='butter')
  File "C:\Users\AppData\Roaming\Python\Python36\site-packages\scipy\signal\filter_design.py", line 1959, in iirfilter
    raise ValueError("Digital filter critical frequencies "
ValueError: Digital filter critical frequencies must be 0 < Wn < 1

текст ошибки такой:

Критические частоты цифрового фильтра должны быть 0 ‹ Wn ‹ 1


person f.zahraa    schedule 03.05.2018    source источник
comment
по крайней мере один из них неверный self.filter_lowcut, self.filter_highcut, self.signal_frequency   -  person Gang    schedule 03.05.2018
comment
это значения: self.filter_lowcut = 0,0 self.filter_highcut = 15,0 self.filter_order = 1 self.signal_frequency = 250   -  person f.zahraa    schedule 03.05.2018
comment
lowcut не может быть нулем.   -  person Darkoob12    schedule 30.01.2019


Ответы (2)


Это может быть из-за ввода параметра fs. Он должен быть больше любого из 2 * Wn. Как и в исходном коде scipy/signal/filter_design.py:

if fs is not None:
    if analog:
        raise ValueError("fs cannot be specified for an analog filter")
    Wn = 2*Wn/fs

И позже:

if not analog:
    if numpy.any(Wn <= 0) or numpy.any(Wn >= 1):
        raise ValueError("Digital filter critical frequencies must be 0 < Wn < 1")
person Jiayin Shi    schedule 20.04.2020

scipy.signal.butter(N, Wn, btype='low', аналог=False, output='ba')

Wn : array_like

Скалярная последовательность или последовательность длины 2, задающая критические частоты. Для фильтра Баттерворта это точка, в которой усиление падает до 1/sqrt(2) усиления полосы пропускания («точка -3 дБ»). Для цифровых фильтров Wn нормируется от 0 до 1, где 1 — частота Найквиста, пи радиан/выборка. (Таким образом, Wn выражается в полупериодах/выборке.) Для аналоговых фильтров Wn представляет собой угловую частоту (например, рад/с).

Ваше исключение здесь, где низкий/высокий не [0,1]

b, a = butter(filter_order, [low, high], btype='band', analog=False)

для filter_type == 1, Wn является числом с плавающей запятой, отличным от nparray.

https://github.com/scipy/scipy/blob/v0.19.1/scipy/signal/filter_design.py#L2226-L2297

>>> N, Wn = signal.buttord([20, 50], [14, 60], 3, 40, True)
>>> b, a = signal.butter(N, Wn, 'band', True)
person Gang    schedule 03.05.2018