是否有可能,以及如何做,扩展滤波器,将滤波器阻带中的信号转换为没有信息内容或至少与该频率范围内的输入信号零相关的噪声,只有通带中信号的任意小衰减?
为了可视化这一点,这是一个低通滤波器幅度频率响应,其等波纹阻带波瓣在 -72.5 dB 处达到峰值:
当过滤两个正弦调制频率扫描的总和(尝试解决问题的良好测试信号)时,生成的频谱图为:
我目前能想到的最好方法是在输入信号中添加一些噪声。在阻带波瓣的峰值处以比正弦曲线高 2.5 dB 的功率天真地添加三角噪声仍然显示频谱图中的正弦曲线:
在阻带 + 18.5 dB 处将噪声提高到峰值正弦波功率几乎完全隐藏了阻带上的正弦波:
但是噪音很大。我没有将噪声仅过滤到阻带,因为它需要额外的计算工作,并且因为在某些应用程序中信号会被抽取,并且无论如何噪声都会最终进入通带。
我也一直在考虑随机切换滤波器组的输出。切换将使阻带零点四处移动,同时在通带中引起最小的频率响应波动。但这种方法似乎是一条死胡同。如果输入是阻带内的复正弦曲线,那么为了消除输入和扰频器输出之间的相关性,滤波器组滤波器的频率响应之和需要在该频率处为零。如果按照我们的要求,对于所有阻带频率,这同时是可能的,那么还可以对滤波器组滤波器的脉冲响应求和,以获得具有均匀零阻带频率响应的滤波器。众所周知,这是不可能的。
也许不存在理想的方法。
绘图的 Python 代码:
import numpy as np
from scipy import signal
import matplotlib.pyplot as plt
c0 = signal.remez(8, [0, 0.25], [1], maxiter=100)
c = np.zeros(c0.size*2-1)
c[0::2] = c0
c[c0.size-1] = 1
c = c*0.5
freq, response = signal.freqz(c)
plt.plot(range(-c0.size+1, c0.size, 1), c, 'x')
plt.grid(True)
plt.show()
plt.plot(freq/(2*np.pi), 20*np.log10(np.abs(response)))
plt.grid(True)
plt.show()
print("Stop band ripple (dB):")
print(20*np.log10(np.abs(response[-1])))
delay_c = np.concatenate([np.zeros((c.size // 2)), [1], np.zeros((c.size // 2))])
freq, response = signal.freqz(delay_c - c)
plt.plot(range(-c0.size+1, c0.size, 1), delay_c - c, 'x')
plt.grid(True)
plt.show()
plt.plot(freq/(2*np.pi), 20*np.log10(np.abs(response)))
plt.grid(True)
plt.show()
N = 65536
f = 2
x = np.sin((lambda x: 0.5*np.pi*x - 0.5*np.sin(np.pi*x/N*f)*N/f)(np.arange(N)))
f = 5
x += np.sin((lambda x: 0.5*np.pi*x - 0.5*np.sin(np.pi*x/N*f)*N/f)(np.arange(N)))
def get_spectrogram(x):
return signal.spectrogram(x, window=('gaussian', 64), scaling='spectrum', nperseg=1024, noverlap=1024-64, nfft=1024, detrend=False)
def plot_spectrogram(x):
f, t, Sxx = get_spectrogram(x)
plt.figure(figsize=(10,5))
plt.pcolormesh(t, f, 10*np.log10(Sxx/np.max(Sxx) + 10e-100), shading='gouraud', cmap='pink', vmin=-112, vmax=0)
plt.show()
f, t, Sxx = get_spectrogram(x);
plot_spectrogram(x)
y = np.convolve(x, c)
plot_spectrogram(y);
epsilon = 10**(-70/20)*np.sqrt(3) #sqrt(3) = sqrt(1/2)/sqrt(1/6) = sine rms / triangular noise rms
r = (np.random.uniform(size=y.size)-np.random.uniform(size=y.size))*epsilon
z = y + r
plot_spectrogram(z);
epsilon = 10**(-54/20)*np.sqrt(3)
z = y + (np.random.uniform(size=y.size)-np.random.uniform(size=y.size))*epsilon
plot_spectrogram(z);