Эффект Jello при отображении отфильтрованного цифрового сигнала
Я хочу отображать записанный сигнал в реальном времени с некоторой базовой фильтрацией (остановка полосы, полосовой проход).
- сигнал хранится в массиве numpy ( numpy.array )
- граф matplotlib отображает массив numpy ( matplotlib.animation.FuncAnimation )
- для каждого кадра FuncAnimation некоторые фильтры применяются к сигналу ( scipy.signal.butter , scipy.signal.filtfilt )
Когда я делаю это так, я получаю какой-то эффект джело (извините за плохое качество gif)
Даже если это не совсем то, что происходит, давайте притвориться, что я реализовал этот алгоритм в псевдокоде:
signal = np.array(some_data) plot = FuncAnimation(init_function, update_function) for each frame: - shift signal on the left # make space and discard oldest samples - add new samples on the right - filtered_signal = filter(signal) # using signal.butter and signal.filtfilt - update_plot(filtered_signal) # FuncAnimation update function
Я ищу методы, чтобы избавиться от этого нежелательного эффекта. Есть идеи?
ИЗМЕНИТЬ 1
Без анимации это то, что добавляется для 20 последовательных отфильтрованных сигналов.
- Первый график –
signal
(необработанный сигнал) - Второй сюжет содержит 20 последних
filtered_signal
- Третий сюжет содержит 20 последних
filtered_signal
сдвинутых для лучшей визуализации
EDIT 2
-
signal
представляет собой буфер фиксированного размера, содержащий N = 1000 выборок -
filtered_signal
создается с нуля для каждого кадра - частота дискретизации равна fs = 250 Гц
- Применяются 2 фильтра: полоса пропускания 50 Гц и полоса пропускания [0,5 Гц, 120 Гц]
EDIT 3 Вот полный рабочий пример:
- Первый график – это необработанный сигнал
- Второй график – отфильтрованный сигнал (полоса пропускания [0,5 Гц, 120 Гц])
Исходный код:
import matplotlib.pyplot as plt import numpy as np from scipy import signal import matplotlib.animation as animation import time N = 1000 fs = 250 last_update = time.time() sample_id = 0 def all_samples(length=10000): # generate a dummy signal st = 1.0 / fs t = np.arange(length) * st sig1 = 1*np.sin(2*np.pi * 2*t) + 2 sig2 = 0.25*np.sin(2*np.pi * 3*t) + 4 sig3 = 2*np.sin(2*np.pi * 4*t) + 5 return sig1 + sig2 + sig3 def band_pass(low_cut, high_cut, order=2): # compute butterworth b, a coefficients band = np.array([low_cut, high_cut]) Wn = band / (float(fs/2.0)) b, a = signal.butter(order, Wn, 'bandpass') return b, a def filter(raw_signal): # apply filter b, a = band_pass(0.5, 120) return signal.filtfilt(b, a, raw_signal) def init(): # init function for FuncAnimation blit=True global axe_raw, line_raw global axe_filt, line_filt line_filt.set_visible(False) line_raw.set_visible(False) axe_raw.set_xlim(0, 1000) axe_raw.set_ylim(5, 15) axe_filt.set_xlim(0, 1000) axe_filt.set_ylim(-5, 5) return line_raw, line_filt, def update(n): global raw_signal, axe_raw, line_raw global axe_filt, line_filt global last_update, fs, sample_id if n == 1: line_raw.set_visible(True) line_filt.set_visible(True) # add new samples now = time.time() sample_count = int((now - last_update) * fs) raw_signal = np.roll(raw_signal, -sample_count) raw_signal[-sample_count:] = all_samples[sample_id:sample_id + sample_count] last_update = now sample_id += sample_count # update plot (raw + filtered) line_raw.set_ydata(raw_signal) line_filt.set_ydata(filter(raw_signal)) return line_raw, line_filt all_samples = all_samples() raw_signal = np.zeros(N) # matplotlib animation figure = plt.figure() axe_raw = figure.add_subplot(211) axe_filt = figure.add_subplot(212) line_raw, = axe_raw.plot(raw_signal) line_filt, = axe_filt.plot(np.zeros(N)) anim = animation.FuncAnimation(figure, update, init_func=init, interval=5, blit=True) plt.show()
- Быстрый способ выбора n элементов (из распределения Пуассона) для каждого элемента в массиве x
- Логическая игра: максимизация (или минимизация) шансов для двух агентов встретиться
- Найти глобальный минимум, используя scipy.optimize.minimize
- как я могу запрограммировать большое количество циклов
- алгоритм для рандомизации матрицы с ограничением единственности
- Python Image tutorial работает, другие изображения ведут себя по-разному (показывая изображения с Pylab)
- Перестановка на месте numpy
- как научиться программированию компьютерного зрения и базовым концепциям обработки изображений в реальном времени
- Улучшение сортировки слияния
- Элемент большинства Python
- Алгоритм для создания списка моделей скобок в Python
- Статистика заказа Красное Черное двоичное дерево в Python
- Эффективный способ объединения двух списков со списком или значением None
- Ограничение случайных случайностей Python