• Автор записи:
  • Рубрика записи:Scipy
  • Время чтения:8 минут чтения
  • Комментарии к записи:0 комментариев

В Scipy есть библиотека scipy.signal для изменения, анализа и обработки сигнала, например видеосигнала, аудиосигнала и т. д.

Каждая категория содержит множество функций, поэтому здесь мы рассмотрим часто используемые методы некоторых категорий.

Содержание

Метод 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])

Метод butter()

  • Создайте фильтр верхних частот Баттерворта с частотой 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()

Метод Convolve()

Метод 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()

Корреляция сигнала Scipy

Метод 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

Метод Ifilter

  • Спроектируйте фильтр Баттерворта нижних частот порядка 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()

Фильтр сигнала Scipy

Метод 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 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)

Модуль Scipy scipy.signal

Метод 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()

Спектрограмма сигнала Scipy

Добавить комментарий