python 过滤曲线噪点(滤波)

import numpy as np
import matplotlib.pyplot as plt
from scipy import signal

# 生成示例信号
t = np.linspace(0, 1, 1000)
x = np.sin(2 * np.pi * 5 * t) + np.sin(2 * np.pi * 20 * t) + np.random.randn(len(t)) * 0.2

# 设计低通滤波器
order = 3  # 滤波器阶数
cutoff_freq = 0.9  # 截止频率(Hz)
b, a = signal.butter(order, cutoff_freq, fs=2, btype='low', analog=False, output='ba')

# 应用滤波器
filtered_x = signal.lfilter(b, a, x)

# 绘制原始信号和滤波后的信号
plt.figure(figsize=(8, 6))
plt.plot(t, x, label='原始信号')
plt.plot(t, filtered_x, label='滤波后的信号')
plt.xlabel('时间')
plt.ylabel('振幅')
plt.legend()
plt.show()

在这里插入图片描述

动画效果展示,实时进行平滑:

import numpy as np
import matplotlib.pyplot as plt
from matplotlib.animation import FuncAnimation
from scipy import signal

# 创建图形对象和子图
fig, ax = plt.subplots()

# 设置空白的线对象
line_raw, = ax.plot([], [], 'b-', label='原始数据')
line_filtered, = ax.plot([], [], 'r-', label='平滑数据')

# 设计低通滤波器
order = 4
b, a = signal.butter(3, 0.8, btype='low', analog=False, output='ba')

# 初始化数据和滤波结果
x = np.zeros(1000)
filtered_x = np.zeros_like(x)
time = np.arange(len(x))

# 更新函数,用于每一帧的绘制
def update(frame):
    global x, filtered_x, time

    # 生成新数据
    new_data = np.random.randn()  # 这里示例使用随机数作为新数据

    # 更新数据
    x = np.append(x[1:], new_data)
    time = np.append(time[1:], time[-1] + 1)

    # 应用滤波器
    filtered_x = signal.lfilter(b, a, x)

    # 更新绘图数据
    line_raw.set_data(time, x)
    line_filtered.set_data(time, filtered_x)

    # 设置轴的范围
    ax.set_xlim(time[0], time[-1])
    ax.set_ylim(min(x.min(), filtered_x.min()) - 1, max(x.max(), filtered_x.max()) + 1)

# 创建动画
ani = FuncAnimation(fig, update, frames=range(1000), interval=10)

# 设置图形界面
plt.xlabel('时间')
plt.ylabel('数值')
plt.legend()

# 显示动画
plt.show()

在这里插入图片描述

一欧元滤波

import numpy as np
import matplotlib.pyplot as plt
from matplotlib.animation import FuncAnimation
from scipy import signal


class ExtendOneEuroFilter:
    def __init__(self, x0, dx0=0.0, min_cutoff=1, beta=0.0, d_cutoff=1.0):
        """Initialize the one euro filter."""
        # The parameters.
        self.min_cutoff = float(min_cutoff)
        self.beta = float(beta)
        self.d_cutoff = float(d_cutoff)
        # Previous values.
        self.x_prev = float(x0)
        self.dx_prev = float(dx0)

    def __call__(self, x, t_e=1):
        """Compute the filtered signal."""

        # The filtered derivative of the signal.
        a_d = self.smoothing_factor(t_e, self.d_cutoff)
        dx = (x - self.x_prev) / t_e
        dx_hat = self.exponential_smoothing(a_d, dx, self.dx_prev)

        # The filtered signal.
        cutoff = self.min_cutoff + self.beta * abs(dx_hat)
        a = self.smoothing_factor(t_e, cutoff)
        x_hat = self.exponential_smoothing(a, x, self.x_prev)

        # Memorize the previous values.
        self.x_prev = x_hat
        self.dx_prev = dx_hat

        return x_hat

    def exponential_smoothing(self, a, x, x_prev):
        return a * x + (1 - a) * x_prev

    def smoothing_factor(self, t_e, cutoff):
        r = 2 * np.pi * cutoff * t_e
        return r / (r + 1)

    def update_prev(self,x_prev):
        self.x_prev = x_prev

    def get_prev(self):
        return self.x_prev

    def get_min_cutoff(self):
        return self.min_cutoff

    def update_min_cutoff(self, min_cutoff):
        self.min_cutoff = min_cutoff

# 创建图形对象和子图
fig, ax = plt.subplots()

# 设置空白的线对象
line_raw, = ax.plot([], [], 'b-', label='原始数据')
line_filtered, = ax.plot([], [], 'r-', label='平滑数据')

# 初始化数据和滤波结果
x = np.zeros(30)
# ss = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1] * 100
filtered_x = np.zeros_like(x)
t = np.arange(len(x))

# 创建ExtendOneEuroFilter对象
one_euro_filter = ExtendOneEuroFilter(x0=0, dx0=0)

# 初始化点序号注释
point_num_text = ax.text(0, 0, '', fontsize=12, ha='center', va='center')

# 更新函数,用于每一帧的绘制
def update(frame):
    global x, filtered_x, t, counter

    # 生成新数据
    if counter > 1000:
        new_data = 1.0  # 设置为固定值
    else:
        new_data = np.random.randn()
    # print(one_euro_filter.get_min_cutoff())
    if counter > 100:
        one_euro_filter.update_min_cutoff(0.5)
    if counter > 200:
        one_euro_filter.update_min_cutoff(0.25)
    if counter > 300:
        one_euro_filter.update_min_cutoff(0.1)
    if counter > 400:
        one_euro_filter.update_min_cutoff(0.08)
    if counter > 500:
        one_euro_filter.update_min_cutoff(0.05)
    if counter > 600:
        one_euro_filter.update_min_cutoff(0.03)
    if counter > 700:
        one_euro_filter.update_min_cutoff(0.02)
    # 更新数据
    x = np.append(x[1:], new_data)
    # x = np.append(x[1:], ss[counter])
    t = np.append(t[1:], t[-1] + 1)

    # 应用滤波器
    filtered_x = one_euro_filter(x, t_e=1)
    print(filtered_x[-1])
    # 更新绘图数据
    line_raw.set_data(t, x)
    line_filtered.set_data(t, filtered_x)

    # 设置轴的范围
    ax.set_xlim(t[0], t[-1])
    ax.set_ylim(min(x.min(), filtered_x.min()) - 1, max(x.max(), filtered_x.max()) + 1)

    # 更新点序号注释
    point_num_text.set_position((t[-1], x[-1]))
    point_num_text.set_text(str(counter))

    # 更新计数器
    counter += 1


# 创建动画
ani = FuncAnimation(fig, update, frames=range(1000), interval=10)

# 设置图形界面
plt.xlabel('时间')
plt.ylabel('数值')
plt.legend()

# 暂停状态的标志
paused = False

# 键盘事件处理函数
def on_key(event):
    global paused

    # 按下空格键暂停/恢复动画
    if event.key == ' ':
        paused = not paused
        if paused:
            ani.event_source.stop()
        else:
            ani.event_source.start()


# 绑定键盘事件处理函数
fig.canvas.mpl_connect('key_press_event', on_key)

# 初始化计数器
counter = 0

# 显示动画
plt.show()



  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Python图像识别

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值