当前位置: 首页 > web >正文

奈氏准则/奈奎斯特定理 如何直观理解2W这个超参数,为什么偏偏就是2呢?

奈氏准则/奈奎斯特定理 如何直观理解2W这个超参数

大家好,今天我们来聊一个在数字信号处理领域非常核心的概念——奈奎斯特准则(Nyquist Criterion)。它告诉我们,要完整地捕捉一个信号,我们至少需要多快的采样频率。别担心,我们不讲复杂的数学公式,而是通过一个有趣的故事来直观理解它。

跳绳比赛与老式相机

在这里插入图片描述

现在,呱呱小学举办了一场别开生面的跳绳比赛。参赛选手有几位“重量级”人物:

  • 邻居的儿子小粉:每 2 秒 跳一次绳(频率 0.5 Hz 0.5 \text{ Hz} 0.5 Hz)。
  • 校长的儿子小紫:每 4 秒 跳一次绳(频率 0.25 Hz 0.25 \text{ Hz} 0.25 Hz)。
  • 书记的儿子小明:每 1 秒 跳一次绳(频率 1 Hz 1 \text{ Hz} 1 Hz)。

现在,上头给你派了个艰巨的任务:用一台珍贵的 1987 年黑白胶片相机,在胶卷极其有限的情况下,记录下这场比赛的“视频”。你得盘算盘算,这相机快门得按多快,才能把这场比赛的精彩瞬间都拍下来,而且还得省胶卷!


抓住最快的,就能抓住全部

显然,在这场比赛中,书记的儿子小明是跳得最快的,他每秒跳一次,频率高达 1 Hz 1 \text{ Hz} 1 Hz。如果我能用相机完整记录下小明的跳绳过程,那么跳得慢的小粉和小紫自然也能被清晰记录下来。所以,我们的首要任务就是:如何用最少的胶卷,完整地记录下小明的跳绳过程?

为了方便理解,我们可以把小明跳绳的高度抽象成一个周期为 1 秒、非负的波形。他从地面(高度为 0)起跳,在大约 0.5 秒时达到最高点,然后在 1 秒时重新落地。
在这里插入图片描述

import numpy as np
import matplotlib.pyplot as plt# 设置中文显示
plt.rcParams['font.sans-serif'] = ['SimHei']  # 用来正常显示中文标签
plt.rcParams['axes.unicode_minus'] = False  # 用来正常显示负号# 生成1Hz“跳绳高度”数据(非负)
f_max = 1  # 频率 1 Hz
T = 1 / f_max  # 周期 1 秒
time = np.linspace(0, 4 * T, 400) # 4个周期# 高度模拟:从0开始,0.5秒达到最高点,1秒回到0
height = (1 - np.cos(2 * np.pi * f_max * time)) / 2plt.figure(figsize=(10, 5))
plt.plot(time, height, label='小明跳绳高度 (1 Hz)', color='blue')
plt.title('小明跳绳高度随时间变化示意图 (1 Hz)', fontsize=16)
plt.xlabel('时间 (秒)', fontsize=12)
plt.ylabel('相对高度', fontsize=12)
plt.grid(True, linestyle='--', alpha=0.7)
plt.axhline(0, color='black', linewidth=0.8)
plt.ylim([-0.1, 1.1]) # 确保显示高度从0开始
plt.legend()
plt.show()

第一次尝试:1 秒拍一张 ( 1 Hz 1 \text{ Hz} 1 Hz 采样率)

你心想,小明一秒跳一次,那我一秒拍一张照片总行了吧?这样胶卷也省。于是你设置相机快门,每 1 1 1 秒拍一张。
在这里插入图片描述

import numpy as np
import matplotlib.pyplot as plt# 设置中文显示
plt.rcParams['font.sans-serif'] = ['SimHei']  # 用来正常显示中文标签
plt.rcParams['axes.unicode_minus'] = False  # 用来正常显示负号# 生成1Hz“跳绳高度”数据(非负)
f_max = 1  # 频率 1 Hz
T = 1 / f_max  # 周期 1 秒
time = np.linspace(0, 4 * T, 400) # 4个周期# 高度模拟:从0开始,0.5秒达到最高点,1秒回到0
height = (1 - np.cos(2 * np.pi * f_max * time)) / 2# 采样频率 fs = 1 Hz,即每秒拍一张
fs1 = 1
sample_interval1 = 1 / fs1
sample_times1 = np.arange(0, 4 * T + 0.001, sample_interval1) # 采样点
sampled_heights1 = (1 - np.cos(2 * np.pi * f_max * sample_times1)) / 2plt.figure(figsize=(10, 5))
plt.plot(time, height, label='原始小明跳绳高度 (1 Hz)', color='blue', alpha=0.7)
plt.scatter(sample_times1, sampled_heights1, color='red', zorder=5, s=100, label='采样点 (每1秒拍一张)')
plt.title('采样频率 1 Hz 拍摄小明跳绳', fontsize=16)
plt.xlabel('时间 (秒)', fontsize=12)
plt.ylabel('相对高度', fontsize=12)
plt.grid(True, linestyle='--', alpha=0.7)
plt.axhline(0, color='black', linewidth=0.8)
plt.ylim([-0.1, 1.1])
plt.legend()
plt.show()plt.figure(figsize=(10, 5))
plt.plot(sample_times1, sampled_heights1, 'o-', color='red', label='重构的跳绳波形')
plt.title('从 1 Hz 采样点重构的跳绳波形', fontsize=16) 
plt.xlabel('时间 (秒)', fontsize=12)
plt.ylabel('相对高度', fontsize=12)
plt.grid(True, linestyle='--', alpha=0.7)
plt.axhline(0, color='black', linewidth=0.8)
plt.ylim([-0.1, 1.1])
plt.legend()
plt.show()

你兴奋地冲洗照片,结果傻眼了!在你的照片里,小明似乎一直在原地,高度始终为 0 0 0!根本看不出来他跳了多少次绳。这就是著名的 混叠(Aliasing) 现象。你的采样频率恰好等于信号频率,每次都只拍到小明在最低点(或最高点,取决于相位)的瞬间,完全丢失了中间的变化。
在这里插入图片描述

第二次尝试:1.5 秒拍一张 ( 0.66 Hz 0.66 \text{ Hz} 0.66 Hz 采样率)

这下你意识到不对劲了,于是你尝试把快门放慢一点,每 1.5 1.5 1.5 秒拍一张。
在这里插入图片描述

import numpy as np
import matplotlib.pyplot as plt# 设置中文显示
plt.rcParams['font.sans-serif'] = ['SimHei']  # 用来正常显示中文标签
plt.rcParams['axes.unicode_minus'] = False  # 用来正常显示负号# 生成1Hz"跳绳高度"数据(非负)
f_max = 1  # 频率 1 Hz
T = 1 / f_max  # 周期 1 秒
time = np.linspace(0, 4 * T, 400) # 4个周期# 高度模拟:从0开始,0.5秒达到最高点,1秒回到0
height = (1 - np.cos(2 * np.pi * f_max * time)) / 2# 采样频率 fs = 1/1.5 Hz ≈ 0.66 Hz,即每1.5秒拍一张
fs1 = 1/1.5  # 约0.66 Hz
sample_interval1 = 1 / fs1  # 1.5秒
sample_times1 = np.arange(0, 4 * T + 0.001, sample_interval1) # 采样点
sampled_heights1 = (1 - np.cos(2 * np.pi * f_max * sample_times1)) / 2# 生成实际观察到的1.5秒周期的波形
observed_time = np.linspace(0, 4 * T, 400)
observed_height = (1 - np.cos(2 * np.pi * (1/3) * observed_time)) / 2  # 3秒周期的波plt.figure(figsize=(10, 5))
plt.plot(time, height, label='原始小明跳绳高度 (1 Hz)', color='blue', alpha=0.7)
plt.scatter(sample_times1, sampled_heights1, color='red', zorder=5, s=100, label='采样点 (每1.5秒拍一张)')
plt.title('采样频率 0.66 Hz 拍摄小明跳绳', fontsize=16)
plt.xlabel('时间 (秒)', fontsize=12)
plt.ylabel('相对高度', fontsize=12)
plt.grid(True, linestyle='--', alpha=0.7)
plt.axhline(0, color='black', linewidth=0.8)
plt.ylim([-0.1, 1.1])
plt.legend()
plt.show()# 绘制实际观察到的1.5秒周期的波形
plt.figure(figsize=(10, 5))
plt.plot(observed_time, observed_height, color='red', label='实际观察到的波形 (1.5秒周期)')
plt.scatter(sample_times1, sampled_heights1, color='red', zorder=5, s=100, label='采样点')
plt.title('采样频率不足导致的频率混叠\n(实际观察到的是3秒周期的波形)', fontsize=16)
plt.xlabel('时间 (秒)', fontsize=12)
plt.ylabel('相对高度', fontsize=12)
plt.grid(True, linestyle='--', alpha=0.7)
plt.axhline(0, color='black', linewidth=0.8)
plt.ylim([-0.1, 1.1])
plt.legend()
plt.show()

你再次冲洗照片,这次更奇怪了!照片显示小明似乎在 1.5 1.5 1.5 秒时达到最高,然后 3 3 3 秒时达到最低,仿佛他跳绳的频率变成了 1 / 3 Hz 1/3 \text{ Hz} 1/3 Hz。这完全不是他真实跳绳的样子!这就是低频混叠,你把一个高频信号错误地看成了低频信号。
在这里插入图片描述


第三次尝试:0.5 秒拍一张 ( 2 Hz 2 \text{ Hz} 2 Hz 采样率)

经历两次失败,你开始思考:一个完整的波形(比如小明跳绳的一个周期),包含了从最低点(落地)到最高点,再回到最低点(再次落地)的过程。也就是说,它有一个 波峰(“山顶”) 和两个关键的 波谷(“山脚”,即落地瞬间)。要完整地捕捉这个波形,至少得抓住这些关键瞬间!

小明跳绳频率是 1 Hz 1 \text{ Hz} 1 Hz,一个周期是 1 1 1 秒。他从 0 0 0 秒落地,在 0.5 0.5 0.5 秒达到最高点,然后在 1 1 1 秒再次落地。这意味着,从一次落地到下一次落地,是 1 1 1 秒;而从落地到最高点,只需要半秒 ( 0.5 0.5 0.5 秒)。 为了完整记录他“跳起来”和“落下去”的全过程,我们需要在这半秒内至少捕捉到“落地”和“最高点”这两个关键状态。

你将快门速度设置为每 0.5 0.5 0.5 秒拍一张(即采样频率 2 Hz 2 \text{ Hz} 2 Hz)。
在这里插入图片描述

# 采样频率 fs = 2 Hz,即每0.5秒拍一张
import numpy as np
import matplotlib.pyplot as plt# 设置中文显示
plt.rcParams['font.sans-serif'] = ['SimHei']  # 用来正常显示中文标签
plt.rcParams['axes.unicode_minus'] = False  # 用来正常显示负号# 生成1Hz"跳绳高度"数据(非负)
f_max = 1  # 频率 1 Hz
T = 1 / f_max  # 周期 1 秒
time = np.linspace(0, 4 * T, 400) # 4个周期# 高度模拟:从0开始,0.5秒达到最高点,1秒回到0
height = (1 - np.cos(2 * np.pi * f_max * time)) / 2# 采样频率 fs = 2 Hz,即每0.5秒拍一张
fs1 = 2  # 2 Hz
sample_interval1 = 1 / fs1  # 0.5秒
sample_times1 = np.arange(0, 4 * T + 0.001, sample_interval1)  # 采样点
sampled_heights1 = (1 - np.cos(2 * np.pi * f_max * sample_times1)) / 2# 生成实际观察到的2 Hz采样下的波形(其实就是原始信号的采样点)
observed_time = np.linspace(0, 4 * T, 400)
observed_height = (1 - np.cos(2 * np.pi * f_max * observed_time)) / 2  # 1 Hz周期的波plt.figure(figsize=(10, 5))
plt.plot(time, height, label='原始小明跳绳高度 (1 Hz)', color='blue', alpha=0.7)
plt.scatter(sample_times1, sampled_heights1, color='red', zorder=5, s=100, label='采样点 (每0.5秒拍一张)')
plt.title('采样频率 2 Hz 拍摄小明跳绳', fontsize=16)
plt.xlabel('时间 (秒)', fontsize=12)
plt.ylabel('相对高度', fontsize=12)
plt.grid(True, linestyle='--', alpha=0.7)
plt.axhline(0, color='black', linewidth=0.8)
plt.ylim([-0.1, 1.1])
plt.legend()
plt.show()# 绘制实际观察到的波形(2 Hz采样下,能还原1 Hz信号)
plt.figure(figsize=(10, 5))
plt.plot(observed_time, observed_height, color='red', label='实际观察到的波形 (1 Hz周期)')
plt.scatter(sample_times1, sampled_heights1, color='red', zorder=5, s=100, label='采样点')
plt.title('采样频率满足奈氏准则\n(实际观察到的是1秒周期的原始波形)', fontsize=16)
plt.xlabel('时间 (秒)', fontsize=12)
plt.ylabel('相对高度', fontsize=12)
plt.grid(True, linestyle='--', alpha=0.7)
plt.axhline(0, color='black', linewidth=0.8)
plt.ylim([-0.1, 1.1])
plt.legend()
plt.show()

这次,你终于成功了!照片冲洗出来,虽然有些“粗糙”,但你已经能清晰地看出小明跳绳的节奏和幅度。你成功地记录下了他从落地到最高点,再到下一次落地的完整变化过程,并可以据此重构出他的真实跳绳轨迹。
在这里插入图片描述


第四次尝试:0.25 秒拍一张 ( 4 Hz 4 \text{ Hz} 4 Hz 采样率)

为了让“视频”看起来更流畅,你尝试把快门调得更快,每 0.25 0.25 0.25 秒拍一张(即采样频率 4 Hz 4 \text{ Hz} 4 Hz)。
在这里插入图片描述

# 采样频率 fs = 4 Hz,即每0.25秒拍一张
fs4 = 4
sample_interval4 = 1 / fs4
sample_times4 = np.arange(0, 4 * T + 0.001, sample_interval4)
sampled_heights4 = (1 - np.cos(2 * np.pi * f_max * sample_times4)) / 2plt.figure(figsize=(10, 5))
plt.plot(time, height, label='原始小明跳绳高度 (1 Hz)', color='blue', alpha=0.7)
plt.scatter(sample_times4, sampled_heights4, color='orange', zorder=5, s=100, label='采样点 (每0.25秒拍一张)')
plt.title('采样频率 $4 \text{ Hz}$ 拍摄小明跳绳', fontsize=16)
plt.xlabel('时间 (秒)', fontsize=12)
plt.ylabel('相对高度', fontsize=12)
plt.grid(True, linestyle='--', alpha=0.7)
plt.axhline(0, color='black', linewidth=0.8)
plt.ylim([-0.1, 1.1])
plt.legend()
plt.show()plt.figure(figsize=(10, 5))
plt.plot(sample_times4, sampled_heights4, 'o-', color='orange', label='重构的跳绳波形')
plt.title('从 $4 \text{ Hz}$ 采样点重构的跳绳波形', fontsize=16)
plt.xlabel('时间 (秒)', fontsize=12)
plt.ylabel('相对高度', fontsize=12)
plt.grid(True, linestyle='--', alpha=0.7)
plt.axhline(0, color='black', linewidth=0.8)
plt.ylim([-0.1, 1.1])
plt.legend()
plt.show()

这次,你记录的采样点更加密集,重构出的波形也更加平滑,更接近小明真实的跳绳轨迹了!
在这里插入图片描述

实际上,如果我们只是简单采样的话,更高频率的采样,肯定更清晰,但是在现在的技术下,只要你采样频率大于等于2W,就像我之前展示的一样,原始波形是可以被还原的,当然,因为我们是数字世界,我数字也只能还原数字,终归是还原不了模拟信号的。


奈氏准则的“2W”之谜

通过这个跳绳比赛的故事,我们就能直观地理解 奈奎斯特准则 的核心思想了。

小明跳绳的最高频率是 1 Hz 1 \text{ Hz} 1 Hz,这相当于我们信号的带宽 W W W(或最高频率 f m a x f_{max} fmax)。我们发现,要完整捕捉这个 1 Hz 1 \text{ Hz} 1 Hz 的信号,我们至少需要每 0.5 0.5 0.5 秒拍一张照片,也就是每秒拍 2 2 2 张照片。这个采样频率 2 Hz 2 \text{ Hz} 2 Hz,正好是小明跳绳频率 1 Hz 1 \text{ Hz} 1 Hz两倍

这就是奈奎斯特准则的核心:为了能够不失真地恢复一个频率上限为 W W W 的信号,采样频率 f s f_s fs 必须至少是这个频率上限的两倍,即 f s ≥ 2 W f_s \ge 2W fs2W

为什么是“2”呢?

核心原因就在于信号的周期性变化。一个频率为 W W W 的信号,它在一个周期内会经历从最低点到最高点,再回到最低点的完整过程。要完整地捕捉这种变化,我们至少需要采集到两个关键信息点:一个能代表**波峰(跳到最高点)的信息,另一个能代表波谷(落地瞬间)**的信息。

对于小明 1 Hz 1 \text{ Hz} 1 Hz 的跳绳动作来说,一个完整的周期是 1 1 1 秒。从落地到最高点,再到下一次落地,这期间需要捕捉的两个关键状态(落地和最高点)在时间上相隔半个周期( 0.5 0.5 0.5 秒)。因此,在 1 / W 1/W 1/W 秒(一个周期)的时间内,我们需要至少进行两次采样才能捕捉到这两个独立的信息点。这就意味着,每秒我们需要进行 2 W 2W 2W 次采样。

低于 2 W 2W 2W 的采样频率会导致 混叠,就像我们前面两次尝试一样,高频的跳绳动作被错误地“看成”了静止或者更慢的跳绳动作,原始信息就丢失了。只有当采样频率达到或超过 2 W 2W 2W 时,我们才能确保捕捉到足够的信息,从而完整地重构出原始信号。


希望通过这个跳绳比赛的故事,你对奈奎斯特准则中的“2W”有了更直观、更深刻的理解。在实际的数字通信、音频处理(比如 CD 音质的 44.1 kHz 44.1 \text{ kHz} 44.1 kHz 采样率对应人耳听力极限 20 kHz 20 \text{ kHz} 20 kHz)、图像处理等领域,奈奎斯特准则都是一个不可或缺的基石。祝你也玩得愉快!

http://www.xdnf.cn/news/12042.html

相关文章:

  • fastadmin+workman环境搭建
  • thymeleaf直接调用Spring Bean中定义的方法
  • 区块链技术在计算机信息网络综合布线实训室的应用实践
  • mybatis 参数绑定错误示范(1)
  • 配置GDAL使用工具
  • window 显示驱动开发-提供视频解码功能(二)
  • 工业自动化DeviceNET从站转Ethernet/IP主站网关赋能冶金行业工业机器人高效运行
  • 网络编程之网络基础
  • VS Code 打开ipynb(还不会)运行python
  • 微服务面试资料1
  • CppCon 2015 学习:Benchmarking C++ Code
  • 【vibe coding解决100个问题】开发CRM管理系统, Augment/windsurf/bolt.new哪家强?
  • AtCoder-abc407_e解析
  • 【Blender Texture】【游戏开发】高质感 Blender 4K 材质资源推荐合集 —— 提升场景真实感与美术表现力
  • Vue跨层级通信
  • 2025-0604学习记录17——文献阅读与分享(2)
  • Anaconda全平台安装指南
  • PostgreSQL-安装-win10、win11安装pgsql16.1和timescaledb2.13.0(绿色免安装版本)
  • 开源库 API 化平台 (ALLBEAPI) - 让优秀工具触手可及!
  • 实验设计如何拯救我的 CEI VSR 28G 设计
  • ubuntu下libguestfs-tools
  • 电力系统时间同步系统之二
  • 我的概要设计模板(以图书管理系统为例)
  • [Css]等腰梯形
  • 如何在IDE中通过Spark操作Hive
  • Ant Design动态增加表单项
  • 使用Prometheus+Grafana+Alertmanager+Webhook-dingtalk搭建监控平台
  • simulink这边重新第二次仿真时,直接UE5崩溃,然后simulink没有响应
  • AReaL-boba²:开源异步强化学习训练系统的革命性突破
  • 【C/C++】进一步介绍idl编码