You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

寻求去除50Hz工频噪声的自适应滤波器方案及优化方法

Hey there! I totally get the frustration of dealing with stubborn 50Hz line noise—even after tweaking Q-values, it just hangs around. Let’s break down some solid solutions, starting with the adaptive filter example you asked for, plus a few other tricks that might do the trick.

Adaptive Filter Example (LMS Algorithm)

Adaptive filters like the Least Mean Squares (LMS) are perfect here because they automatically track variations in the 50Hz noise (like small frequency drifts) without needing perfect prior knowledge. The key is having a reference noise source—this can be a pure 50Hz sine wave you generate, or even a sensor reading directly from the power line (way more accurate if you can get it).

Here’s a straightforward Python implementation:

import numpy as np
import matplotlib.pyplot as plt

def lms_adaptive_filter(input_signal, reference_noise, mu=0.01, order=10):
    # Initialize filter weights
    w = np.zeros(order)
    filtered_signal = np.zeros_like(input_signal)
    
    for n in range(order, len(input_signal)):
        # Grab the last 'order' samples of the reference noise (reverse for convolution)
        x = reference_noise[n-order:n][::-1]
        # Estimate the noise component in the input signal
        noise_estimate = np.dot(w, x)
        # Subtract the estimated noise to get a cleaner signal
        filtered_signal[n] = input_signal[n] - noise_estimate
        # Update filter weights using the error signal
        error = filtered_signal[n]
        w = w + mu * error * x
    
    return filtered_signal

# Example setup
fs = 500  # Sampling frequency (Hz)
t = np.linspace(0, 1, fs)

# Create a noisy signal: 10Hz useful signal + 50Hz noise + small random noise
clean_signal = np.sin(2 * np.pi * 10 * t)
line_noise = 0.5 * np.sin(2 * np.pi * 50 * t)
noisy_signal = clean_signal + line_noise + 0.05 * np.random.randn(len(t))

# Reference noise (use a power line sensor reading here if possible!)
reference_noise = np.sin(2 * np.pi * 50 * t)

# Apply the LMS filter
filtered_signal = lms_adaptive_filter(noisy_signal, reference_noise, mu=0.005, order=15)

# Plot results to compare
plt.figure(figsize=(12, 6))
plt.subplot(3, 1, 1)
plt.plot(t, noisy_signal)
plt.title("Noisy Signal (10Hz + 50Hz Line Noise)")
plt.subplot(3, 1, 2)
plt.plot(t, filtered_signal)
plt.title("Filtered Signal with LMS Adaptive Filter")
plt.subplot(3, 1, 3)
plt.plot(t, clean_signal - filtered_signal)
plt.title("Residual Error")
plt.tight_layout()
plt.show()
  • Tips for tuning: Keep mu (step size) small to avoid filter instability, and increase order if the noise has more complex harmonics (just note that higher order means more computation).
Other Methods to Crush 50Hz Noise

If you can’t get a reliable reference noise source, these alternatives might work better:

  • Multi-Harmonic Notch Filter
    50Hz line noise often comes with harmonics (100Hz, 150Hz, etc.)—a single notch filter won’t catch all of them. Try chaining multiple notch filters to target the base frequency and its harmonics:
from scipy import signal

fs = 500
target_freqs = [50, 100, 150]  # Base + 2nd/3rd harmonics
Q = 25  # Balances notch narrowness and stability
filtered_signal = noisy_signal.copy()

for freq in target_freqs:
    b, a = signal.iirnotch(freq, Q, fs)
    # Use filtfilt to avoid phase distortion
    filtered_signal = signal.filtfilt(b, a, filtered_signal)
  • Wavelet Transform Denoising
    Great for non-stationary signals (where your useful signal changes over time). Wavelets break the signal into frequency scales—you can zero out the scale corresponding to 50Hz to eliminate noise:
import pywt

# Choose a wavelet and decomposition level
wavelet = "db4"
level = 5

# Decompose the noisy signal
coeffs = pywt.wavedec(noisy_signal, wavelet, level=level)
# For fs=500Hz, level 3 covers ~31-62Hz (perfect for 50Hz)
coeffs[3] = np.zeros_like(coeffs[3])  # Zero out the 50Hz scale

# Reconstruct the clean signal
filtered_signal = pywt.waverec(coeffs, wavelet)
  • Synchronous Detection (Lock-In Amplifier)
    If your useful signal is periodic and you know its frequency, this method suppresses all non-synchronous noise (including 50Hz) by correlating the signal with a reference matching your useful signal:
# Reference signal matching your useful signal frequency (e.g., 10Hz)
ref_signal = np.sin(2 * np.pi * 10 * t)
# Demodulate the noisy signal
demodulated = noisy_signal * ref_signal
# Low-pass filter to extract the DC component (carries useful signal info)
b, a = signal.butter(2, 1, "low", fs=fs)
filtered_dc = signal.filtfilt(b, a, demodulated)
# Reconstruct the clean useful signal
clean_reconstructed = 2 * filtered_dc * ref_signal

Start with the LMS filter if you can get a good reference—it’s unbeatable for tracking noise drift. If not, the multi-harmonic notch filter or wavelet denoising are solid go-tos. Tweak parameters like filter order, Q-values, or wavelet scales to squeeze out that last bit of noise!

内容的提问来源于stack exchange,提问作者Ivo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.19 08:06:15