likes
comments
collection
share

语音识别时域分析之信号的采样与重构

作者站长头像
站长
· 阅读数 30

信号的采样和重构是数字信号处理中重要的基础概念之一。采样是将连续时间信号转换为离散时间信号的过程,而重构则是将离散时间信号还原为连续时间信号的过程。在信号处理中,通常会采用周期采样和非周期采样两种方式进行信号采样。

周期采样

周期采样(也称为等间隔采样)是一种将连续时间信号转换为离散时间信号的方法,它的思想是在固定的时间间隔内对信号进行采样,即在等间隔的时间点上采样。这些时间点称为采样时刻,采样时刻的间隔称为采样周期。

假设连续时间信号为 x(t)x(t)x(t),采样周期为 TsT_sTs,则采样时刻为 t=nTst=nT_st=nTs,其中 nnn 是整数。那么采样后的离散时间信号为:

语音识别时域分析之信号的采样与重构

其中 x[n]x[n]x[n] 表示采样信号在第 nnn 个采样时刻的取值。

需要注意的是,周期采样有一个重要的限制条件,即采样周期 TsT_sTs 必须满足采样定理。采样定理指出,对于一个最高频率为 fmaxf_{max}fmax 的信号进行采样,采样周期 TsT_sTs 必须小于等于信号周期的一半,即 Ts≤12fmaxT_s \leq \frac{1}{2f_{max}}Ts2fmax1。否则,会出现采样失真现象,即由于采样率不足而无法还原原始信号。

下面是一个使用 Python 实现的周期采样的示例代码:

import numpy as np
import matplotlib.pyplot as plt

# 原始信号
t = np.linspace(-1, 1, 1000)
x = np.sin(2 * np.pi * 5 * t)

# 周期采样
Ts = 0.1  # 采样周期
n = np.arange(-10, 10)  # 采样点序列
xn = np.sin(2 * np.pi * 5 * n * Ts)  # 采样信号

# 绘图
plt.plot(t, x, label='Original signal')
plt.stem(n*Ts, xn, label='Sampled signal')
plt.legend()
plt.show()

在这个示例中,我们生成了一个正弦信号 x(t)=sin⁡(2πft)x(t)=\sin(2\pi f t)x(t)=sin(2πft),并使用周期采样对其进行采样。图中的蓝色曲线为原始信号,橙色的圆点表示采样时刻的离散时间点,红色的竖线表示采样值。

非周期采样

非周期采样也称为不等间隔采样,是指采样时间间隔不固定的采样方式。设采样时刻为 t1,t2,...,tnt_1,t_2,...,t_nt1,t2,...,tn,则得到的采样信号为:

语音识别时域分析之信号的采样与重构

其中,NNN 表示采样点数。可以看出,采样信号 xs(t)x_s(t)xs(t) 是由原始信号 x(t)x(t)x(t) 与一串在离散时刻 t1,t2,...,tnt_1,t_2,...,t_nt1,t2,...,tn 处取值的单位脉冲序列相乘得到的。

非周期采样通常使用时间间隔 Δt\Delta tΔt 来表示采样率,即 fs=1/Δtf_s = 1/\Delta tfs=1/Δt,其中 fsf_sfs 是采样率。对于连续时间信号 x(t)x(t)x(t),我们可以使用采样定理,即 Nyquist-Shannon 采样定理,来确保采样后的信号不失真。

Nyquist-Shannon 采样定理指出,如果信号 x(t)x(t)x(t) 的频率范围在 [0,fs/2][0, f_s/2][0,fs/2] 之内,那么在采样率为 fsf_sfs 时,我们可以完全恢复信号。因此,我们可以使用以下公式对信号进行采样:

语音识别时域分析之信号的采样与重构

其中 nnn 是采样点的整数序列。

然后,我们可以使用插值方法来重构原始信号。最简单的方法是使用零阶保持插值,也称为阶梯插值,它假定在两个采样点之间的信号值保持不变。这意味着,在 [nΔt,(n+1)Δt][n\Delta t, (n+1)\Delta t][nΔt,(n+1)Δt] 时间间隔内,信号值是常数 x[n]x[n]x[n]

重构后的信号为:

语音识别时域分析之信号的采样与重构

其中,rect(t)\mathrm{rect}(t)rect(t) 是矩形函数,定义为:

语音识别时域分析之信号的采样与重构

下面是 Python 代码示例,我们可以看到采样后的信号与原始信号非常接近:

import numpy as np
import matplotlib.pyplot as plt

# 原始信号
t = np.linspace(-1, 1, 1000)
x = np.sin(2 * np.pi * 5 * t)

# 非周期采样
fs = 50  # 采样率
ts = 1 / fs  # 采样间隔
n = np.arange(0, len(t))
xn = x[n*int(ts/t[1])]  # 采样信号

# 零阶保持插值
tr = np.linspace(-1, 1, 1000)
xr = np.zeros_like(tr)
for i in range(len(n)):
    xr += xn[i] * np.sinc((tr - n[i] * ts) / ts)

# 绘图
plt.plot(t, x, label='Original signal')
plt.stem(n*ts, xn, label='Sampled signal')
plt.plot(tr, xr, label='Reconstructed signal')
plt.legend()
plt.show()

重构

重构是将离散时间信号还原为连续时间信号的过程。设采样信号为 xs(t)x_s(t)xs(t),采样周期为 TsT_sTs,则重构信号为:

语音识别时域分析之信号的采样与重构

其中,sinc(x)sinc(x)sinc(x) 表示 sin⁡(x)x\frac{\sin(x)}{x}xsin(x) 函数。可以看出,重构信号 xr(t)x_r(t)xr(t) 是由采样信号 xs(t)x_s(t)xs(t) 在每个采样时刻处乘上一个 sincsincsinc 函数的值并求和得到的。

下面是 Python 代码实现:

import numpy as np
import matplotlib.pyplot as plt

# 原始信号
t = np.linspace(-1, 1, 1000)
x = np.sin(2 * np.pi * 5 * t)

# 周期采样
Ts = 0.1  # 采样周期
n = np.arange(-10, 10)  # 采样点序列
xn = np.sin(2 * np.pi * 5 * n * Ts)  # 采样信号

# 重构
tr = np.linspace(-1, 1, 1000)
xr = np.zeros_like(tr)
for i in range(len(n)):
    xr += xn[i] * np.sinc((tr - n[i] * Ts) / Ts)

# 绘图
plt.plot(t, x, label='Original signal')
plt.stem(n*Ts, xn, label='Sampled signal')
plt.plot(tr, xr, label='Reconstructed signal')
plt.legend()
plt.show()

在这个示例中,我们先生成了一个正弦信号 x(t)=sin⁡(2πft)x(t)=\sin(2\pi f t)x(t)=sin(2πft),然后使用周期采样对其进行采样,并最终使用 sincsincsinc 函数重构了原始信号。重构信号与原始信号非常接近,这证明了采样和重构的有效性。

信号的重构通常使用一种名为插值的方法,该方法将采样信号与一种基函数相乘,并将它们相加以获得连续信号。在这里,我们将使用基函数 sinc(x)sinc(x)sinc(x),它是一个非常常见的插值函数。

假设我们有一个离散时间序列 x[n]x[n]x[n],它是由原始信号进行周期采样得到的。在周期采样中,我们将原始信号 x(t)x(t)x(t) 采样为:

语音识别时域分析之信号的采样与重构

其中 TsT_sTs 是采样周期,nnn 是整数。

现在,我们希望通过重构方法得到连续的信号 xr(t)x_r(t)xr(t),并使用 sinc(x)sinc(x)sinc(x) 函数进行插值。那么,插值信号可以表示为:

其中,sinc(x)sinc(x)sinc(x) 函数定义为:

语音识别时域分析之信号的采样与重构

上面的式子意味着对于任何时刻 ttt,我们可以通过将 sinc(x)sinc(x)sinc(x) 函数与采样点 x[n]x[n]x[n] 相乘,然后对所有采样点求和,从而得到该时刻的连续信号 xr(t)x_r(t)xr(t)。这种重构技术被称为零阶保持插值(zero-order hold interpolation)。

下面是 Python 代码实现:

import numpy as np
import matplotlib.pyplot as plt

# 原始信号
t = np.linspace(-1, 1, 1000)
x = np.sin(2 * np.pi * 5 * t)

# 周期采样
Ts = 0.1  # 采样周期
n = np.arange(-10, 10)  # 采样点序列
xn = np.sin(2 * np.pi * 5 * n * Ts)  # 采样信号

# 重构
tr = np.linspace(-1, 1, 1000)
xr = np.zeros_like(tr)
for i in range(len(n)):
    xr += xn[i] * np.sinc((tr - n[i] * Ts) / Ts)

# 绘图
plt.plot(t, x, label='Original signal')
plt.stem(n*Ts, xn, label='Sampled signal')
plt.plot(tr, xr, label='Reconstructed signal')
plt.legend()
plt.show()

在这个示例中,我们先生成了一个正弦信号 x(t)=sin⁡(2πft)x(t)=\sin(2\pi f t)x(t)=sin(2πft),然后使用周期采样对其进行采样,并最终使用 sincsincsinc 函数重构了原始信号。重构信号与原始信号非常接近,这证明了采样和重构的有效性。

转载自:https://juejin.cn/post/7224043114360750135
评论
请登录