
简介近场声全息技术利用声波干涉记录三维声场信息这套MATLAB代码包正为该方向提供了可运行的算法实现适合声学工程、无损检测等领域的研究者与工程师。压缩包共10个文件其中6个.m脚本负责数据读取、相位差计算与图像重建4个txt文件用于存储样例数据或注释说明整体仅12KB结构紧凑。目前已有270人学习下载代码覆盖近场声全息从采集、预处理到成像重建和后处理的主要流程配合实例数据可快速了解各环节编程要点。结合实际运行结果能够帮助读者掌握利用MATLAB开展声场模拟与近场成像分析的方法为噪声控制、声源识别等应用提供有力工具。1. 近场声全息程序包从GitHub上的rar到声场重建近场声全息NAH是一种利用近场声压测量来重建声源表面振动分布的技术标题里这个hologaphy_GitHub.rar听名字就知道是 GitHub 上一份整理过的声全息程序包主目录organized7ah里通常放着 MATLAB 或 Python 脚本用来做平面近场成像和声源识别。很多从业者拿到这种包第一反应是解压后直接点运行然后被路径、版本、参数搞得头大。这篇笔记不吹概念我就按从下载、解压到真正跑出声场云图的完整路径把近场成像最关键的原理、参数和典型坑讲清楚。无论你是做 NVH 测试的工程师还是刚碰声阵列的研究生照着这条路能把程序包用起来。2. 近场声全息原理为什么近场能恢复倏逝波2.1 声压测量与空间频谱一句话说清 NAH传统声成像手段比如波束形成只能看到传播波分辨率受限于半波长。近场声全息选择在声源非常近的位置测量这个距离通常远小于一个波长因此声压里包含了从声源表面衰减出来的倏逝波。倏逝波虽然带着声源表面的微观细节却在传播过程中指数衰减几十厘米外就测不到了。NAH 的重建过程可以拆成三步。第一步把测量面 x-y 平面上的复声压p_h做二维空间 FFT得到波数域频谱P(kx, ky)。第二步乘上传声函数也叫外推算子把频谱从测量面外推到重建面。第三步逆 FFT 回到空间域得到重建面上的声压或振速。整个过程在波数域中是逐点相乘计算量小一张 64x64 的阵列数据上Python 脚本几秒钟就能处理完。关键点在第二步对传播波成分kx²ky² k²外推算子是一个相位延迟对倏逝波成分kx²ky² k²外推算子是一个实指数函数。当从测量面向声源方向回推时这个实指数是放大倍数把曾经衰减掉的高频细节重新放大回来代价是背景噪声也被放大。正因如此所有 NAH 程序都离不开正则化。你会在程序包里看到Tikhonov、beta、regularization这些字眼它们就是用来抑制放大过程的。2.2 程序包里的典型文件organized7ah 目录里该有什么GitHub 上的声全息程序包不管用 MATLAB 还是 Python文件组织都很接近我在实际项目里见过的方式。主目录organized7ah下面一般会有这几类内容data/存放声压测量结果常见.mat也可能是.csv或.dat。如果作者用 LabVIEW 采集可能还会带上时间波形文件。scripts/或根目录下的.m、.py包含主程序和一系列函数。主程序一般叫holography_main或reconstruct_hologram负责读数据、调参、调用重建函数、画图。config/或参数设置脚本定义结构体或字典里面有阵列行数、列数、dx、dy、频率、声速、测量距离等。这个文件非常重要我拿到任何一个新包都会先打开它。results/作者跑好的示例输出用来跟你的结果对比。README作者写的使用说明通常解释了依赖环境和已知问题。别小看这个文件很多运行时崩溃在 README 里都会提醒。判断一个 GitHub 项目是否靠谱我一般不看星星数量先看有没有 README、示例数据和参数设置文件。三者齐全的包即使代码风格差也值得跑通否则你下载的可能只是半成品后面要花大量时间自己补数据格式。程序包的调用关系通常是主脚本读 config、读 data、调用外推函数、调用正则化函数、绘图。如果你直接运行主脚本遇到函数未定义的报错十有八九是当前目录没有包含函数文件这就是为什么解压时要保持目录结构原样。2.3 相位与参考信号程序包数据格式的第一道门槛近场全息图需要的是复声压也就是幅值和相位。测量时如果只有声压幅值而没有参考信号就无法获得各阵元相对于声源的相位后面的 FFT 外推全是空谈。很多程序包自带的.mat数据里字段名经过作者整理常见的有real_pressure、imag_pressure、frequency也有直接存complex_pressure的。还有一部分包给的是时域波形需要自己在脚本里做 FFT 取单频复声压。拿到数据先别急着跑主脚本用 Python 看一眼键名和维度能省去大量试错。如果包里有官方示例结果最好先跑通示例再换自己的数据。示例数据是从设备实测来的里面各种异常情况都有比仿真数据更能暴露脚本的隐藏依赖。3. 把 hologaphy_GitHub.rar 跑通解压、改路径、跑第一个重建3.1 下载与校验rar 压缩包最常见的损坏点在 GitHub 下载这类 rar我几乎从不用网页端直接点下载因为文件名带 rar 且体积稍大时浏览器下载经常中断。更稳定的方式是拿到 release 页或仓库里的实际下载地址后在终端里用 wget 加断点续传参数wget -c https://your-github-host/your-repo/releases/download/v1.0/hologaphy_GitHub.rar sha256sum hologaphy_GitHub.rar命令里的链接要替换成你实际在 GitHub 页面复制的地址。-c参数表示如果上次下载中断从断点继续下载sha256sum对下载结果做完整性校验打印一串哈希值需要和 release 页标注的哈希逐字对比。如果 release 页没提供哈希至少看下载文件大小和页面标注是否一致。我碰到很多次从 GitHub 下载的 rar 只有几十 KB解压时提示Unexpected end of archive这就是下载不完整重新下载比尝试修复更有效。GitHub release 附件经常是作者打包后二次上传的里面可能还嵌套一层目录。下载后建议放到专门的工作目录比如~/nah_workspace不要直接解压到桌面。后面所有路径问题会因为这个习惯少掉一半。3.2 解压与目录迁移Linux 和 Windows 下的差异rar 格式在 Linux 下默认没有工具需要自己装 unrar。在 Debian/Ubuntu 系上做法是sudo apt install unrar unrar x hologaphy_GitHub.rar这里x表示解压并保留压缩包内目录结构。如果换成e所有文件会被平铺到当前目录函数、数据、脚本全混在一起主脚本里的相对路径全部失效。解压后检查organized7ah是否完整用ls -R看目录树确认 scripts、data 这些文件夹都在。若发现里面还有一层同名目录比如organized7ah/organized7ah说明压缩包里包含根目录直接把内层文件移出来mv organized7ah/organized7ah/* organized7ah/移完再ls一遍别把隐藏文件落下。Windows 下我习惯用 7-Zip 而不是系统自带右键解压因为 Windows 自带的压缩文件夹对 rar 兼容性差经常报未知格式或文件损坏。7-Zip 右键选解压到 hologaphy_GitHub即可输出目录自动按文件名创建。解压完成后第一件改的事是路径。GitHub 上的项目路径都是作者机器的比如/Users/author/NAH/hologaphy而你在 Windows 下是D:\Work\NAH。如果程序是 MATLAB 写的检查主脚本开头有没有cd或addpath如果是 Python 脚本开头常有os.chdir。统一改成你的工作目录import os os.chdir(rD:\Work\NAH\organized7ah) print(os.path.exists(data))r前缀让反斜杠不转义print用来确认 data 目录能找到。如果返回 False后面的数据读取一定失败早发现早处理。3.3 最小重建脚本从仿真数据到声压云图如果压缩包里没有现成测量数据或者你想先验证重建流程可用一个最小仿真脚本走通全流程。这是我在调试 NAH 算法时固定用的自检脚本模拟一个点源测量面放 5cm 远然后重建回声源平面。import numpy as np from numpy.fft import fft2, ifft2, fftfreq import matplotlib.pyplot as plt def nah_reconstruct(p_h, dx, dz, c, f): 近场全息重建返回重建面的复声压。 p_h : 测量面复声压 (N, N) dx : 传感器间距 (m) dz : 测量面与重建面距离 (m)重建面更靠近声源时为正 c : 声速 (m/s) f : 分析频率 (Hz) N, _ p_h.shape fx fftfreq(N, dx) fy fftfreq(N, dx) kx 2 * np.pi * fx ky 2 * np.pi * fy KX, KY np.meshgrid(kx, ky, indexingij) k 2 * np.pi * f / c # 复数开方自动处理传播波与倏逝波 KZ np.emath.sqrt(k**2 - KX**2 - KY**2) G np.exp(1j * KZ * dz) return ifft2(fft2(p_h) * G) # 阵列与声场参数 f 2000.0 # 分析频率 2 kHz c 343.0 # 声速 dx 0.02 # 阵元间距 2 cm N 64 # 64x64 阵元 dz 0.05 # 到重建面距离 5 cm # 构建测量面坐标 x (np.arange(N) - N // 2) * dx X, Y np.meshgrid(x, x) # 模拟位于重建面中心的点源在测量面产生的复声压 k 2 * np.pi * f / c r np.sqrt(X**2 Y**2 dz**2) p_h np.exp(1j * k * r) / (4 * np.pi * r) # 执行重建 p_s nah_reconstruct(p_h, dx, dz, c, f) # 显示归一化幅值云图 plt.imshow(np.abs(p_s), extent[x.min(), x.max(), x.min(), x.max()], originlower, cmapviridis) plt.colorbar(labelNormalized amplitude) plt.title(NAH reconstruction of a point source) plt.show()这段代码里fftfreq生成空间频率坐标乘以2π变成波数坐标np.emath.sqrt对负输入返回纯虚数这样倏逝波区域的外推算子自然变成实指数不需要手工分支。G就是前面原理里说的传播算子fft2(p_h) * G在波数域完成外推逆变换后得到重建面声压。运行后你会看到一个集中在中心的亮斑这就是重建出来的点源位置。如果亮斑边缘出现明显同心圆纹不是声源信号而是测量面有限孔径带来的截断效应后面避坑部分会讲。4. 四个决定重建质量的核心参数4.1 传感器间距和测量孔径空间采样率的取舍近场声全息本质是对空间信号采样空间采样率是第一道关。传感器间距dx决定了可恢复波数的上限空间奈奎斯特波数k_Nyq π/dx。如果声源表面某个细节对应的波数高于这个值重建时它的能量会混叠到低波数上表现为云图里的方向性伪影。因此dx越小空间分辨率越高但dx小意味着传感器数量多、数据量大、采集成本高。下面是一张对照表声速 343 m/s供选型参考dx (cm)空间奈奎斯特波数 (rad/m)理论上可恢复的最小细节尺度 (cm)可用频率上限参考13142.0≤ 8.5 kHz21574.0≤ 4.2 kHz562.810.0≤ 1.7 kHz细节尺度按半波长估算实际重建受信噪比和正则化影响达不到理论极限。测量阵列的总孔径L N·dx决定成像范围重建面超出孔径的部分误差急剧增大。为了减小边缘误差阵列至少要比目标声源区域大上一两个阵元间距并把目标声源放在阵列中心区域。4.2 测量距离与重建距离近场条件怎么算近场声全息里近场是硬指标。测量面与声源面的距离必须足够近才能记录到倏逝波。一个粗略的判断基准测量距离取 0.1λ 到 0.5λ。对 2 kHz波长 17.15 cm测量距离应控制在 1.7~8.5 cm。工程上我见过的成功案例多在 2~5 cm。重建距离z_s是你要还原的那个面在声源结构上的位置。程序里的dz通常定义为z_h - z_s当重建面放在声源表面时dz就是测量距离。dz越大外推时放大的倏逝波越多信噪比需求越高超过一个波长后即使理论上可解结果也基本被噪声淹没。遇到重建结果垮掉先检查测量距离是否偏离近场条件。4.3 正则化参数让逆问题不发散外推算子对倏逝波有放大效应会导致高频噪声被同步放大。Tikhonov 正则化在波数域用G*/(|G|²β)替换原Gβ 是正则化参数。β 大平滑强细节被磨掉β 小噪声强云图出现颗粒噪点。找合适 β 的常用办法是 L-curve将重建残差和重建解能量取对数画曲线拐角处对应较优 β。不少程序包内置了beta_search.py或Tikhonov.m。如果没有就手动扫描betas np.logspace(-6, -2, 9) for beta in betas: p_s nah_reconstruct_tikhonov(p_h, dx, dz, c, f, beta) peak np.abs(p_s).max() background np.sort(np.abs(p_s).ravel())[-10] # 用第10大值近似旁瓣 print(fbeta{beta:.1e}, peak/bkg{peak/background:.1f})峰值与背景比随 β 变化会有一个峰值那个位置就是这个工况下的好参数。注意换了频率、距离都要重新扫不能拿一个 β 通吃所有工况。4.4 频率范围避开混叠和低信噪比区间频率对 NAH 有上下限。上限来自空间采样最大可分辨波数受dx限制对应频率f_max c/(2dx)。以 dx2cm、c343 为例f_max 8575 Hz但实际使用建议留 20% 裕量分析频率不要超过 6~7 kHz。因为波数域边缘的G随频率变化剧烈微小噪声都会被放大翻车。下限则由传感器灵敏度和阵列孔径决定频率太低波长很长声源到阵列的相位差很小重建出的云图只能看到一片大光斑。如果必须分析 1 kHz 以下的噪声源要么增大阵列孔径要么改用扫描式近场测量提高有效孔径——把测量面分成多个块用相位参考信号拼接。5. 近场声全息程序避坑五个高发问题与排查5.1 解压后中文路径乱码现象在 Windows 下解压hologaphy_GitHub.rar后data 目录下的中文文件名变成乱码脚本读不到文件报FileNotFoundError。原因rar 包内文件名使用的是 GBK 等非 UTF-8 编码Windows 资源管理器解压时按本地代码页解析错误。很多国内作者打包时没有转换编码这在 GitHub 二次下载的场景里很常见。解决用 7-Zip 打开压缩包时在选项里勾选保留原文件名编码或者先解压到临时目录用 glob 匹配文件绕开具体文件名import glob for f in glob.glob(rD:\Work\NAH\data\*.mat): print(f)如果全是乱码手动重命名成英文名。这比在脚本里逐一处理编码高效。整理好后建议重新打包成 zip 分发给同事避免再次踩坑。5.2 程序报错 Index exceeds matrix dimensions现象运行主脚本到读取声压矩阵或做 FFT 时MATLAB 报Index exceeds matrix dimensionsPython 报IndexError。原因声全息程序对阵列尺寸非常敏感。常见原因有三个一是数据矩阵维度和配置文件里的行列数不一致二是 MATLAB 数组按列优先存储读入后需要转置三是有的脚本从 1 开始索引移植到 Python 没改减 1。解决先看数据 shape再查 config。import scipy.io as sio d sio.loadmat(data/measurement.mat) print(d[p_h].shape)核对配置里的 Nx、Ny。如果数据维度是 (Ny,Nx) 而配置写成 (Nx,Ny)读取后加一行转置再进入重建函数。把这一步做成调试日志能省去大量试错。5.3 重建云图出现棋盘格现象重建后的云图除了中心亮斑还有明显的周期性细密条纹像棋盘。原因空间混叠。测量面阵列间距dx太大或分析频率太高导致倏逝波成分超出奈奎斯特波数高频能量折叠到低频位置。这个问题比较隐蔽因为云图仍有中心亮斑很多人误以为成功了。解决先检查f是否满足f 0.8*c/(2dx)。然后将测量面数据在波数域强制低通P_h fft2(p_h) P_h[np.abs(KX) np.pi/dx] 0 P_h[np.abs(KY) np.pi/dx] 0 p_h ifft2(P_h)注意这个低通会丢掉真实的高频近场细节所以它只是排查手段不是长期方案。长期方案是换用小间距阵列或降低分析频率上限。5.4 距离增加后重建幅值急剧衰减现象把测量距离从 2cm 改成 10cm重建云图依然能看出位置但幅值掉了几十倍。原因倏逝波强度随距离指数衰减远了之后测量面声压主要由传播波贡献近场信息微乎其微。此时外推算子虽然还能数学放大但放大的是原本的噪声底重建结果就成了噪声放大、信号淹没。解决把测量距离收回近场区。如果结构不允许阵列靠近就改用更低频率或者用等效源法替代平面 NAH。等效源法把声源近似为一系列单极子通过求逆拟合测量声压对测量距离的宽容度比平面外推好一些但对噪声同样敏感。5.5 rar 加密提示密码错误现象下载的hologaphy_GitHub.rar解压时提示需要密码试了常见密码都不对卡住无法继续。原因压缩包作者设置了密码。很多作者会把密码写在 GitHub 仓库的 README 或 release 页说明里也有的会写进压缩包注释在 7-Zip 里打开就能看到。解决先查 README 和 release 描述再用 Python 读压缩包注释最省事import rarfile rar rarfile.RarFile(hologaphy_GitHub.rar) print(rar.comment.decode(utf-8, errorsignore))rarfile需要系统安装 unrar 库。如果注释和 README 都没有密码再考虑用 Advanced RAR Password Recovery 这类工具但要清楚这是暴力破解对 RAR5 加密基本无能为力。更实际的做法是在 GitHub 仓库发 issue 问作者或者查作者的个人主页。我遇到过几次密码就是作者网址后几位多看两眼就找到了。6. 从仿真到实测用点源验证你的重建流程6.1 点源验证实验设计仿真跑通只是第一步真正让声全息程序可信的是实测验证。我在搭建 NAH 测量流程时第一个实验永远是点源验证找一只直径 3cm 的小扬声器放在半消声室或至少离墙 1 米以上的桌面用扫频信号在目标频率比如 2kHz稳态发声用传声器阵列在设定距离测量声压的幅值和相位。如果没有多通道阵列可以用单个传声器按网格步进扫描但声源必须保持相位稳定需要同步采集参考信号。实测数据和仿真数据有两个明显差别背景噪声和边界反射。所以重建前先对测量数据做加窗常用 Tukey 窗把测量面边缘压低减小有限孔径泄漏。程序包里找到窗函数设置把它设为tukey参数 alpha 取 0.3~0.5。6.2 评估指标与我的习惯重建完我会对比三个数字重建面峰值位置误差应小于半个阵元间距、峰值幅值与理论点源声压之差、峰值与背景平均的比值。峰值背景比低于 10dB 时我会认为正则化不够或测量距离偏大回去继续调参数。另一个容易忽略的指标是频谱一致性用重建面中心声压的频谱和近场探头直接测到的频谱对比如果趋势一致说明重建不是凭空画出来的。我自己的习惯是每次跑 NAH 都把参数日志保存成 txt记录日期、温湿度、阵列编号、dx、N、距离、频率、Tukey 窗 alpha、正则化 beta、数据文件名、结果图文件名。这个习惯帮我省了不少为什么今天结果跟上次不一样的纠结温度一变声速就变程序里默认声速 343但 25 度时实际声速是 346 m/s对 2kHz 的波长来说影响约 1% 相位累积起来足以让重建峰值偏移一个阵元。把声速按环境修正这一步比调正则化更重要。所以拿到这份声全息程序包不要急着改算法先把仿真验证和点源验证跑通再慢慢加边界条件。希望帮到你。本文还有配套的精品资源点击获取