В Scipy есть библиотека scipy.signal для изменения, анализа и обработки сигнала, например видеосигнала, аудиосигнала и т. д.
Каждая категория содержит множество функций, поэтому здесь мы рассмотрим часто используемые методы некоторых категорий.
- Метод Butter()
- Метод find_peaks()
- Метод convolve()
- Метод correlate()
- Метод ifilter()
- Метод impulse()
- Модуль Scipy scipy.signal
- Метод spectrogram()
Метод Butter()
В Scipy есть метод Butter(), позволяющий применить к сигналу фильтр Баттерворта. Другими словами, мы можем создать конструкцию цифрового или аналогового фильтра Баттерворта N-го порядка, выравнивающего частоту.
Синтаксис:
scipy.signal.butter(N, Wn, btype='low', analog=False, output='ba', fs=None)
Где параметры:
- N (int): используется для указания порядка фильтра.
- Wn (array_data): используется для указания критических частот фильтров верхних и нижних частот.
- btype: используется для указания типа используемых фильтров, таких как полосовой фильтр, фильтр верхних частот, фильтр нижних частот и полосовой фильтр.
- analog (логический): если это правда, то используется аналоговый фильтр, в противном случае, в случае ложности, используется цифровой фильтр.
- output: используется для указания типа вывода, например zpk(плоэ-ноль), sos(разделы второго порядка) и ba(обратная совместимость).
Давайте рассмотрим пример, выполнив следующие шаги:
- Импортируйте необходимые библиотеки, используя приведенный ниже код Python.
from scipy.signal import butter import numpy as np import matplotlib.pyplot as plt %matplotlib inline
- Создайте продолжительность сигнала, используя приведенный ниже код.
t_duration = np.linspace(0,0.5,2000,False)
- Сгенерируйте сигнал частотой 20 и 40 Гц, используя приведенный ниже код.
sign = np.sin(2*np.pi*20*t_duration) + np.sin(2*np.pi*40*t_duration)
- Постройте созданный сигнал, используя приведенный ниже код.
fig,(ax1) = plt.subplots(1, 1, sharex=True) ax1.plot(t_duration, sign) ax1.set_title('20 and 40 Hz Sinusoid') ax1.axis([0, 0.5, -2, 2.5])
- Создайте фильтр верхних частот Баттерворта с частотой 25 Гц и примените его к созданному выше сигналу, используя приведенный ниже код.
from scipy import signal sos = butter(15, 20, 'hp', fs=2000, output='sos') filtd = signal.sosfilt(sos, sign)
- Постройте сигнал после применения фильтра, используя приведенный ниже код.
fig,(ax2) = plt.subplots(1, 1, sharex=True) ax2.plot(t_duration, filtd) ax2.set_title('After applying 20 Hz high-pass filter') ax2.axis([0, 0.5, -2, 2.5]) ax2.set_xlabel('Time(seconds)') plt.tight_layout() plt.show()
Метод find_peaks()
В Scipy есть метод find_peaks() внутри модуля scipy.signal, который возвращает все пики на основе заданных свойств пиков.
Синтаксис:
scipy.signal.find_peaks(x, height=1, prominence=4, distance=2, width=2, threshold=1, rel_height=0.5, wlen=1, )
Где параметры:
- x (последовательность): используется для приема сигнала, имеющего пики.
- height () (последовательность, ndarray, число): используется для определения высоты пика.
- prominence(последовательность, ndarray, число): используется для определения пикового порога.
- distance(число): используется для определения минимального горизонтального расстояния между соседними пиками.
- width (последовательность, ndarray, число): используется для обеспечения максимальной известности.
- threshold (последовательность, ndarray, число): используется для определения ширины пика.
- wlen(int): используется для расчета пиковой значимости.
- rel_height(int): используется для расчета высоты пика.
Давайте рассмотрим пример, выполнив следующие шаги:
- Импортируйте необходимую библиотеку, используя приведенный ниже код Python.
from scipy.signal import find_peaks from scipy.misc import electrocardiogram import matplotlib.pyplot as plt %matplotlib inline
Создайте электрокардиограмму, используя приведенный ниже код.
value = electrocardiogram()[1000:5000]
Теперь пики, используя приведенный ниже код.
peak, _ = find_peaks(value, height=0) plt.plot(value) plt.plot(peak, value[peak], "*") plt.plot(np.zeros_like(value), "--", color="green") plt.show()
Метод convolve()
В Scipy есть метод convolve() в модуле scipy.signal, который возвращает третий сигнал путем объединения двух сигналов.
Синтаксис:
scipy.signal.convolve(in1, in2, mode='full', method='auto')
Где параметры:
- in1 (array_data): используется для ввода первого сигнала в виде массива.
- in2 (array_data): используется для ввода второго сигнала в виде массива, размерность которого должна быть такой же, как у первого входного массива.
- mode: используется для указания строки, определяющей размер вывода. Режим может быть одинаковым, полным и действительным.
- method: используется для указания метода, который вычисляет свертку. Метод может быть автоматическим, прямым и FFT.
Давайте разберемся на примере, выполнив следующие шаги:
- Импортируйте необходимую библиотеку, используя приведенный ниже код Python.
from scipy.signal import convolve import scipy.signal import numpy as np import matplotlib.pyplot as plt %matplotlib inline
- Создайте два разных сигнала, используя приведенный ниже код.
signal_1 = np.repeat([1., 2., 1.], 50) signal_2 = np.repeat([2., 4., 5.], 50)
- Теперь добавьте оба сигнала, чтобы создать третий сигнал, используя приведенный ниже код.
conv = signal.convolve(signal_1, signal_2, mode='same') / sum(signal_2)
- Давайте построим вышеуказанные сигналы, используя приведенный ниже код.
fig,(ax_actual, ax_sig_1, ax_conv) = plt.subplots(3, 1, sharex=True) ax_actual.plot(signal_1) ax_actual.set_title('Actual pulse') ax_actual.margins(0, 0.1) ax_sig_1.plot(signal_2) ax_sig_1.set_title(' It is the Filter impulse response') ax_sig_1.margins(0, 0.1) ax_conv.plot(conv) ax_conv.set_title('Convolved signal') ax_conv.margins(0, 0.1) fig.tight_layout() fig.show()
Метод correlate()
В Scipy есть метод correlate() внутри модуля scipy.signal, который аналогичен методу scipy.signal.convolve(). Он также генерирует третий сигнал путем сложения двух сигналов, и сгенерированный сигнал известен как кросс-корреляция.
Синтаксис:
scipy.signal.correlate(in1, in2, mode='full', method='auto')
Где параметры:
- in1 (array_data): используется для ввода первого сигнала в виде массива.
- in2 (array_data): используется для ввода второго сигнала в виде массива, размерность которого должна быть такой же, как у первого входного массива.
- mode: используется для указания строки, определяющей размер вывода. Режим может быть одинаковым, полным и действительным.
- method: используется для указания метода, который вычисляет свертку. Метод может быть автоматическим, прямым и FFT.
Давайте разберемся на примере, выполнив следующие шаги:
- Импортируйте необходимую библиотеку, используя приведенный ниже код Python.
from scipy.signal import correlate from scipy import signal import numpy as np import matplotlib.pyplot as plt %matplotlib inline
- Создайте два разных сигнала, используя приведенный ниже код.
signal_1 = np.repeat([1., 2., 1.], 50) signal_2 = np.repeat([2., 4., 5.], 50)
- Теперь добавьте оба сигнала, чтобы создать третий сигнал, используя приведенный ниже код.
conv = signal.correlate(signal_1, signal_2, mode='same') / sum(signal_2)
- Давайте построим вышеуказанные сигналы, используя приведенный ниже код.
fig,(ax_actual, ax_sig_1, ax_conv) = plt.subplots(3, 1, sharex=True) ax_actual.plot(signal_1) ax_actual.set_title('Actual pulse') ax_actual.margins(0, 0.1) ax_sig_1.plot(signal_2) ax_sig_1.set_title(' It is the Filter impulse response') ax_sig_1.margins(0, 0.1) ax_conv.plot(conv) ax_conv.set_title('Correlated signal') ax_conv.margins(0, 0.1) fig.tight_layout() fig.show()
Метод ifilter()
В Scipy есть метод ifilter() внутри модуля scipy.signal, который очищает данные сигнала в одном измерении с использованием фильтра Finite Impulse Respose(FIR) или Infinite Impulse Response.
Синтаксис:
scipy.signal.lfilter(b, a, x, axis=- 1, zi=None)
Где параметры:
- b (array_data): это одномерная последовательность векторов, содержащая коэффициенты числителя.
- a (array_data): это одномерная последовательность векторов, содержащая коэффициенты знаменателя.
- x (array_data): в качестве входных данных используется ndarray.
- axis (int): это имя оси данного массива, к которой применяется линейный фильтр.
- zi (array_data): используется для указания начального условия для поддержания фильтра.
Вышеупомянутый метод возвращает два значения y и zi.
Давайте посмотрим на примере, используя следующие шаги:
- Импортируйте необходимые библиотеки, используя приведенный ниже код Python.
from scipy.signal import lfilter,butter,filtfilt import matplotlib.pyplot as plt import numpy as np
- Создайте шумный сигнал, который мы собираемся фильтровать, используя приведенный ниже код.
rng = np.random.default_rng() array_data = np.linspace(-2, 2, 302) sin_data =(np.sin(2*np.pi*0.65*array_data*(1-array_data) + 1.1) + 0.2*np.sin(2*np.pi*2.1*array_data + 1) + 0.20*np.cos(2*np.pi*2.58*array_data)) noisy_data = sin_data + rng.standard_normal(len(array_data)) * 0.07
- Спроектируйте фильтр Баттерворта нижних частот порядка 4, используя приведенный ниже код.
num_coff, deno_coff = butter(4, 0.06)
- Давайте реализуем фильтр на зашумленных данных.
zi = lfilter_zi(num_coff, deno_coff) z, _ = lfilter(num_coff, deno_coff, noisy_data, zi=zi*noisy_data[0])
- Реализуйте фильтр еще раз.
z2, _ =lfilter(num_coff, deno_coff, z, zi=zi*z[0])
- Теперь реализуем фильтр filtfilt.
y = filtfilt(num_coff, deno_coff, noisy_data)
- Постройте все сигналы, используя приведенный ниже код.
plt.figure plt.plot(array_data, noisy_data, 'b', alpha=0.75) plt.plot(array_data, z, 'r--', array_data, z2, 'r', array_data, y, 'k') plt.legend(('This is noisy one', 'lfilter, once', 'lfilter, twice', 'This is filtfilt one'), loc='best') plt.grid(True) plt.show()
Метод impulse()
В Scipy есть метод impulse() внутри модуля scipy scipy.signal, который является ретортой системы непрерывного времени в ответ на внешние изменения.
Синтаксис приведен ниже.
scipy.signal.impulse(system, X0=None, T=None, N=None)
Где параметры:
- system (кортеж array_data): используется для определения систем.
- X0 (array_data): это вектор массива начального состояния.
- T (array_data): это моменты времени.
- N (int): Чтобы вычислить количество моментов времени, используйте этот параметр.
Метод возвращает два значения T и you.
Давайте посмотрим на примере, выполнив следующие шаги:
- Импортируйте необходимые библиотеки, используя приведенный ниже код Python.
import matplotlib.pyplot as plt from scipy.signal import impulse
- Создайте систему, используя приведенный ниже код.
sys =([2.1], [2.1, 3.1, 2.1]) time_pts, impulse_res = signal.impulse(sys)
- Теперь постройте сгенерированный импульс, используя приведенный ниже код.
plt.plot(time_pts,impulse_res)
Модуль Scipy scipy.signal
Модуль Scipy scipy.signal содержит метод Square(), который генерирует сигнал в виде прямоугольной волны.
Синтаксис:
scipy.signal.square(t, duty=0.5)
Где параметры:
- t (array_data): это данные массива в качестве входных данных.
- duty (array_data): используется для определения рабочего цикла, по умолчанию он равен 0,5.
Метод возвращает y типа ndarray, который содержит прямоугольную волну.
Давайте сгенерируем прямоугольный сигнал, выполнив следующие шаги:
- Импортируйте необходимые библиотеки, используя приведенный ниже код Python.
import matplotlib.pyplot as plt import numpy as np from scipy.signal import square
- Создайте массив данных и данных прямоугольной формы, используя приведенный ниже код.
array_data = np.linspace(0, 2, 1000, endpoint=False) square_wave = square(2 * np.pi * 2 * array_data)
- Теперь постройте созданный прямоугольный сигнал, используя приведенный ниже код.
plt.plot(array_data,square_wave) plt.ylim(-1.5, 1.5)
Метод spectrogram()
В Scipy есть метод spectrogram() в модуле scipy.signal, который показывает силу сигнала с течением времени на разных частотах определенной формы сигнала.
Синтаксис:
scipy.signal.spectrogram(x, fs=1.0, window=('tukey', 1), nperseg=None, noverlap=None, nfft=None, detrend='constant', return_onesided=False, axis=- 1, mode='psd')
Где параметры:
- x (array_data): это временной ряд.
- fs (float): используется для обеспечения частоты выборки временных рядов.
- window (array_data, tuple, string): используется для указания типа окна, которое мы хотим реализовать.
- nperseg (int): Чтобы указать длину каждого сегмента.
- nooverlap (int): используется для указания количества точек для наложения между сегментами.
- nfft (int): это размер БПФ.
- detrend (False, string, function): используется для указания способа удаления тренда из каждого сегмента.
- return_oneside (boolean): чтобы получить сторону спектра данных. Если true, то возвращается одностороннее, в противном случае, в случае false, возвращается двустороннее.
- axis (int): используется для указания оси, по которой рассчитывать спектрограмму.
- mode (строка): чтобы указать, как мы хотим получить ожидаемое значение, например угол, величину, фазу, комплекс и PSD.
Метод возвращает три значения f (частоты в виде массива), t (время сегмента в виде массива) и sxx (спектрограмма).
Давайте разберемся на примере, выполнив следующие шаги:
- Импортируйте необходимые библиотеки, используя приведенный ниже код Python.
from scipy.signal import spectrogram import matplotlib.pyplot as plt import numpy as np from scipy.fft import fftshift
- Определение значений необходимых параметров для генерации сигнала с использованием приведенного ниже кода.
rng = np.random.default_rng() sample_fre = 9e3 n = 1e3 amp = 3 * np.sqrt(3) noisep = 0.02 * sample_fre / 3 time_data = np.arange(n) / float(sample_fre) mode = 600*np.cos(3*np.pi*0.4*time_data) car_rier = amp * np.sin(3*np.pi*4e4*time_data + mode) gen_noise = rng.normal(scale=np.sqrt(noisep), size=time_data.shape) gen_noise *= np.exp(-time_data/5) signal_data = car_rier + gen_noise
Теперь рассчитайте и покажите спектрограмму, используя приведенный ниже код.
sample_freq, segment_time, spectrogram = spectrogram(signal_data, sample_fre) plt.pcolormesh(segment_time, sample_freq, spectrogram, shading='gouraud') plt.ylabel('It is frequency in Hertz') plt.xlabel('It is time in second') plt.show()