第2章 声波信号采集:水听器原理、采样率选择、信号预处理

各位同学,欢迎来到第二章。上一章我们聊了海豚声波的物理特性,今天咱们来点实在的——怎么把水里的声音“抓”到电脑里来。

说白了,声波信号采集就是三个核心问题:用什么抓?抓多快?抓完怎么处理?我一个个讲。

2.1 水听器原理:水下耳朵的秘密

水听器,英文叫hydrophone,就是水下麦克风。但你别以为它跟空气麦克风一样,差别大了去了。

空气麦克风靠振膜振动,水听器呢?靠的是压电效应。嗯,这里要注意——压电材料受到声波压力时,会产生电荷。压力越大,电荷越多。这就是水听器的基本原理。

我在项目中遇到过一件事:有次在浅海做实验,水听器绑在浮标上,结果浪太大,水听器被拽得晃来晃去。数据里全是低频噪声,根本没法用。后来我才意识到,水听器对加速度也敏感,晃动会产生伪信号。所以固定水听器,一定要稳。

核心参数:

  • 灵敏度:单位是dB re 1V/μPa。数值越负,越不灵敏。比如-170 dB比-190 dB灵敏。
  • 频率响应:海豚声波范围是1 kHz到150 kHz,所以水听器至少要覆盖这个范围。
  • 指向性:全向还是定向?全向的适合监听,定向的适合定位。

你想想看,如果水听器频响只到20 kHz,那海豚的高频哨叫声就全丢了。这不是白忙活吗?

2.2 采样率选择:Nyquist定理不是闹着玩的

采样率怎么选?教科书会告诉你:采样率必须大于信号最高频率的两倍。这叫Nyquist采样定理。

但实际工程中,我建议至少取最高频率的3到5倍。为什么?

举个例子。海豚的click信号,频率能到150 kHz。按Nyquist,300 kHz就够了。但我个人习惯用500 kHz甚至1 MHz。原因有二:

  1. 抗混叠滤波器不是理想砖墙,需要留过渡带。
  2. 高采样率能保留更多波形细节,后续分析更准。

实战建议:

我曾经在实验室里对比过300 kHz和500 kHz采样的海豚click数据。300 kHz的波形看起来还行,但做时频分析时,高频成分明显被削了。换成500 kHz,细节全出来了。所以,采样率宁高勿低。

当然,采样率高了,数据量也大。1 MHz采样,16 bit精度,一小时就是7.2 GB。存储和传输都是问题。所以要根据实际场景权衡。

信号类型 最高频率 推荐采样率 数据率(16 bit)
海豚click 150 kHz 500 kHz - 1 MHz 1 - 2 MB/s
海豚whistle 20 kHz 100 - 200 kHz 200 - 400 KB/s
环境噪声 10 kHz 50 kHz 100 KB/s

2.3 信号预处理:去噪与归一化

原始信号直接拿来用?别闹。水里噪声多着呢——船引擎、波浪、虾兵蟹将的咔嚓声。预处理是必须的。

2.3.1 去噪

去噪方法很多,我挑三个最常用的:

  • 带通滤波:最简单。海豚声波集中在1-150 kHz,那就滤掉这个范围以外的。用Butterworth滤波器,阶数4-6就够了。
  • 中值滤波:对付脉冲噪声(比如虾的爆裂声)特别有效。窗口长度选信号周期的1-2倍。
  • 小波去噪:效果最好,但计算量大。适合离线分析。

注意:

滤波会改变信号相位。如果你要做到达时间差估计,一定要用零相位滤波(比如scipy.signal.filtfilt)。我曾经因为用了普通滤波,导致定位误差大了好几米,排查了半天才发现是相位问题。

2.3.2 归一化

归一化就是把信号幅度调整到统一范围。为什么要做?

因为不同水听器灵敏度不同,同一水听器在不同深度接收到的信号幅度也不同。不归一化,后续比较就没意义。

我常用的归一化方法:

  1. 最大值归一化:除以信号绝对值的最大值。简单粗暴。
  2. 标准差归一化:减去均值,除以标准差。适合统计特征分析。
  3. 能量归一化:除以信号总能量的平方根。适合比较不同信号的波形形状。
import numpy as np
import scipy.signal as signal

def preprocess_hydrophone(data, fs, lowcut=1000, highcut=150000):
    """
    水听器信号预处理
    data: 原始信号
    fs: 采样率 (Hz)
    """
    # 1. 带通滤波
    nyq = 0.5 * fs
    low = lowcut / nyq
    high = highcut / nyq
    b, a = signal.butter(4, [low, high], btype='band')
    filtered = signal.filtfilt(b, a, data)  # 零相位滤波
    
    # 2. 去直流
    filtered = filtered - np.mean(filtered)
    
    # 3. 归一化(最大值归一化)
    normalized = filtered / np.max(np.abs(filtered))
    
    return normalized

这段代码我用了很多年,基本没出过问题。你拿去改改参数就能用。

2.4 知识体系总览

下面这张图,把本章的核心逻辑串起来了。从水听器到采样,再到预处理,每一步都有坑,每一步也都有解法。

声波信号采集知识体系 水听器原理 采样率选择 信号预处理 压电效应 · 灵敏度 · 频响 Nyquist · 抗混叠 · 数据量 去噪 · 归一化 · 去直流 最终目标:高质量、可复现的声波数据

这张图你看懂了吗?从左到右,从物理原理到数字信号,每一步都环环相扣。水听器选错了,后面再好的算法也救不回来。采样率设低了,高频信息就永远丢了。预处理做不好,分析结果全是噪声。

我的经验:

做海豚声波采集,最忌讳的就是“先采了再说”。我见过太多人,拿个水听器就往水里扔,回来一看数据全是低频干扰。所以,动手之前,先把这三个问题想清楚:用什么水听器?采样率设多少?预处理流程怎么走?想清楚了再开机。

好了,这一章就到这里。下一章我们讲时频分析,到时候你会看到,预处理做得好,时频图有多漂亮。


公众号:蓝海资料掘金营,微信deep3321