尧图网站设计 尧图网站设计YAOTU DESIGN
ARTICLE DETAIL

资讯详情

深耕网站设计与一线实操的经验洞察。

全聚焦TFM成像原理与Python实现:从FMC数据到延迟叠加

全聚焦TFM成像原理与Python实现:从FMC数据到延迟叠加 简介针对超声全聚焦TFM与相控阵成像技术的学习与仿真需求这份压缩包提供了一套轻量级Python实现面向从事无损检测、超声成像算法研究或相关课程设计的工程技术人员与研究者。其中tfm.py封装了全聚焦方法从信号采集到逐点聚焦成像的核心流程gui.py则通过界面交互让用户调整阵元数量、偏转角度等参数直观查看成像结果便于将算法原理与代码实现相互对照。资源仅含2个py文件压缩包大小约4KB结构精简适合快速运行与二次开发。目前已有258人浏览学习。通过阅读源码可以掌握TFM延迟叠加求和、像素聚焦坐标计算、阵列布局配置等关键实现思路代码注释清晰配合示例能够复现基础成像流程为后续扩展扫描策略或优化成像质量提供可直接修改的参考起点。1. TFM 为什么比常规扇扫更适合超声相控阵成像先把“全聚焦”想清楚total-focusing-methodTFM全聚焦法在超声相控阵成像里的位置恰好和传统扇扫S 扫相反扇扫在采集之前就设计好聚焦法则而 TFM 先把所有阵元“一发全收”的原始数据存下来再在后处理阶段对图像上任意一个像素点重新计算声程并叠加。这个反转让每个像素都能获得独立聚焦近表面分辨率和缺陷端部绕射表征能力明显优于固定聚焦成像。本文面向要把现有 16/32/64 通道相控阵仪器往全聚焦成像升级的工程师从 FMC 数据格式、最小 Python 重建内核写到孔径、栅格间距和声速修正这三组最关键参数。阅读前提你熟悉相控阵探头、A 扫和基本的传播时间TOF概念但不一定要写过成像算法。2. 全聚焦成像的物理基础从全矩阵捕获到双程声程与延迟求和TFM 的输入行业内俗称“全矩阵捕获”Full Matrix CaptureFMC。这不是某种特殊探头而是相控阵主机工作方式的一种改变N 个阵元轮流单独发射每次发射时所有 N 个阵元同时接收把 N×N 条 A 扫一字排开保存。常规扇扫在单次发射里完成了一大半聚焦TFM 则把这一工作推迟到了图像重建阶段因此它不需要预置聚焦法则只需要一组完整、同步的时域信号。2.1 全矩阵捕获FMC的数据排布N×N 个阵元对先约定记号把第i个阵元发射、第j个阵元接收得到的 A 扫记作a_ij(t)其中t是相对发射时刻的时间。FMC 数据集就是一张N × N × Ns的三维表Ns是每条 A 扫的采样点数。实际仪器里a_ii这类自发自收信号通常也保留只是它的信噪比低于斜向路径叠加时权重天然低一些不必刻意剔除。数据维度代表含义典型取值N探头阵元数16 / 32 / 64 / 128Ns单条 A 扫采样点数1024 ~ 4096fs采样率50 ~ 100 MS/spitch阵元中心距0.4 ~ 1.5 mm之所以要保存完整的 FMC 而不是只存几条合成孔径线是因为后续图像重建时每个像素点可能需要任意一个发射阵元和任意一个接收阵元的组合。提前把数据一次性采齐后处理算法就可以自由决定每个阵元对的贡献权重这正是 TFM 能在成像质量上超过固定聚焦规则的根源。2.2 像素的双程声程把一发一收变成某个像素点的幅值设探头位于z 0平面上阵元中心坐标为(x_i, 0)和(x_j, 0)。图像中任意一个像素点P的坐标为(x_p, z_p)其中z_p是从探头表面向被测材料内部计量的深度。对于均匀各向同性材料中的纵波直入射情形发射声程和接收声程分别是d_tx sqrt((x_p - x_i)**2 z_p**2) d_rx sqrt((x_p - x_j)**2 z_p**2) n int(round((d_tx d_rx) / c * fs)) # 采样点下标这里c是材料声速fs是采样率。计算出来的n就是我们在 A 扫a_ij上取幅值的下标。当n落在[0, Ns)之外时说明该阵元对在该像素位置没有真实回波直接跳过这一项。将所有阵元对的取值累加得到的就是该像素的灰度值img[x_p, z_p] sum_ij a_ij[n_ij(x_p, z_p)]这段代码背后是延迟叠加delay-and-sum思想但注意它和相控阵硬件中的“聚焦法则”有一个本质区别硬件聚焦是在发射时通过延时让声场在某个深度汇聚而 TFM 是在成像阶段对每一个像素分别计算“这个像素如果是一个点散射体哪条路径、什么时候会到达接收阵元”。因此近距离像素可以用小孔径远距离像素自动过渡到大孔径所有焦点都是后验的。2.3 用有效孔径来描述哪些阵元对可以参加求和虽然求和理论上要遍历全部N×N个阵元对但实际工程中不会把所有阵元对都无差别加进去。原因是当像素点靠近探头表面时边缘阵元相对该像素的入射角接近 90 度这些几乎平行于表面的路径不仅带入无效信号还会带来强烈的串扰和边界伪影。常规做法是设定一个最大入射角阈值G只有入射角小于G的阵元对才参与求和。入射角按下式计算sin_theta_tx abs(x_p - x_i) / d_tx sin_theta_rx abs(x_p - x_j) / d_rxG的取值通常在 30 度到 45 度之间。取小角度时近表面图像干净但深处有效孔径变小灵敏度下降取大角度时深处幅值更高但近表面会出现明显的圆弧状伪影。这个参数会在第 4 章结合阵列设计细说你现在只需要理解TFM 的“全聚焦”并不是物理上把所有阵元对全部叠加而是动态筛选可用孔径后再叠加。3. 用 Python 实现 TFM 后处理最小可运行代码与图像重建流程这一章给出一个能在笔记本上跑通的最小实现。它不会是最快的 TFM 内核但结构清晰方便你验证仪器数据、调试孔径参数也为后续换用 GPU 或多线程留出改造空间。我在这里假设你已经用探伤仪导出了 FMC 数据并且知道探头阵元数、阵元间距、采样率和材料声速。3.1 先定义像素网格和阵元坐标重建图像前需要确定两个坐标系统探头阵元坐标和成像区域网格。阵元坐标由pitch和阵元数唯一确定成像网格则由被测区域范围与期望的横向/纵向分辨率约定。下面代码直接定义一个常见配置宽度 40 mm、深度 60 mm、各取 400 个点。import numpy as np # fmc: shape (N, N, Ns) # pitch: 阵元中心距, 单位 mm # c: 声速, 单位 mm/us # fs: 采样率, 单位 MHz, 即 1 us 内的采样点数 pitch 0.8 N fmc.shape[0] x_elem (np.arange(N) - (N - 1) / 2) * pitch # 阵元 x 坐标, 探头中心为 0 # 成像网格: 横向 x, 深度 z, 单位都是 mm xg np.linspace(-20, 20, 400) zg np.linspace(0.5, 60, 400) img np.zeros((zg.size, xg.size))这里把zg的起点设为 0.5 mm 而不是 0是为了避免探头表面附近的直耦合波和表面回波把图像顶部淹没。x_elem以探头中心为原点左右对称这是大多数线阵探头默认的坐标系。如果你的仪器导出的数据带有一个固定的前沿延迟应该在计算距离时把前沿对应的路径长度先减掉否则整个图像会比真实深度偏深一段固定值。3.2 朴素延迟叠加先跑对功能再优化直接按照第 2 章的公式实现三层循环这是最直观、也最容易和公式对照的版本。数据量小的时候比如 32 阵元、每灰度取 200×200 像素这个版本几秒钟内也能完成。for ix, xp in enumerate(xg): for iz, zp in enumerate(zg): acc 0.0 for i in range(N): # 发射阵元 d_tx np.hypot(xp - x_elem[i], zp) for j in range(N): # 接收阵元 d_rx np.hypot(xp - x_elem[j], zp) n_idx int((d_tx d_rx) / c * fs 0.5) if 0 n_idx fmc.shape[2]: acc fmc[i, j, n_idx] img[iz, ix] acc逻辑说明内层循环中np.hypot计算的是每个阵元到当前像素点的直线距离(d_tx d_rx) / c是声波从发射阵元出发、到达像素点散射、再被接收阵元拾取的总时间乘以fs后得到离散采样点下标。这里用int(... 0.5)做四舍五入是为了减少采样量化造成的幅值抖动。acc累加的是所有阵元对的贡献最终赋值给当前像素。整个过程中没有任何波束成形系数也没有动态聚焦的时序控制全部计算都发生在取数据和求和这一步。这个朴素版本有三个明显的问题一是三层 for 循环在 Python 里很慢二是没有做入射角筛选靠近表面时会有圆弧伪影三是没有对信号做包络检波或 Hilbert 变换图像看起来会是振荡的明暗条纹。后两个才是影响图像可读性的关键速度问题可以用numba或把像素循环改为向量化数组运算解决。3.3 加入动态孔径筛选过滤无效阵元对在 2.3 节我们讨论了入射角阈值G。代码上只需要在内层循环入口处加一个判断如果当前阵元相对该像素点的入射角超过阈值就直接跳过。阈值用角度制写成常量方便你反复调整。G np.deg2rad(35) for ix, xp in enumerate(xg): for iz, zp in enumerate(zg): acc 0.0 for i in range(N): d_tx np.hypot(xp - x_elem[i], zp) if d_tx 0: continue if abs(xp - x_elem[i]) / d_tx np.sin(G): continue for j in range(N): d_rx np.hypot(xp - x_elem[j], zp) if d_rx 0: continue if abs(xp - x_elem[j]) / d_rx np.sin(G): continue n_idx int((d_tx d_rx) / c * fs 0.5) if 0 n_idx fmc.shape[2]: acc fmc[i, j, n_idx] img[iz, ix] acc参数说明d_tx 0的判断处理的是阵列正下方为整数倍 pitch 的像素点这时候入射角没有意义按中心路径直接接收集相当于i阵元正下方一点。np.sin(G)与abs(x_p - x_i) / d_tx的比较本质上是把入射角折换成“横向距离除以声程”的比例省去每次计算arcsin的开销。35 度只是出发点实际调试时建议从 25 度开始往上加观察近表面伪影和深层灵敏度之间的平衡。提示如果你发现图像里有沿阵列方向展开的细密条纹通常是某个固定阵元对的串扰信号被重复参与叠加。处理办法是去掉i j的自发自收对或者对所有 A 扫先做一次均值相减把系统串扰成分压掉。4. 网格间距、阵元孔径与声速超声相控阵 TFM 成像的三个关键配置跑通代码之后真正决定图像质量的就不是算法框架而是三个数值像素网格间距、参与聚焦的孔径范围、以及重建所用的声速。这三者分别对应分辨率、旁瓣和定位精度调试时不能只盯一个否则图像会出现“明明很锐利但位置全偏”的错觉。4.1 网格间距按波长缩放太密不涨信息太稀丢小缺陷TFM 图像中相邻两个像素点的距离显然越小越好但采样定理在这里同样适用像素间距对应的是“成像采样率”而信号的横向空间带宽受探头孔径和频率约束。理论极限近似是半波长工程上常用四分之一波长作为网格间距下限。对钢中 5 MHz 纵波声速约 5900 m/s波长约 1.18 mm四分之一波长就是 0.3 mm 左右。横向间距取 0.2 mm 就已经和这个小缺陷的物理尺度相当了。材料纵波声速m/s5 MHz 波长mmλ/4mm碳钢59001.180.30铝63201.260.32奥氏体不锈钢57401.150.29有机玻璃27300.550.14网格间距小于 λ/4 时图像只是变得更平滑并不会增加有效分辨率网格间距大于 λ/2 时小缺陷的幅值会出现栅瓣定位也会跳到相邻像素上。我一般会把横向间距取为 λ/4纵向间距同样取 λ/4然后整体做归一化。这样既保证重建结果不会丢失小缺陷又不会把 FMC 数据量不必要地放大。4.2 阵列孔径与最大成像深度的关系动态孔径的曲线第 3.3 节的G角度实际上限制的是每个深度上的有效孔径宽度。有效孔径宽度A_eff与深度z之间的关系约等于2z·tan(G)。当G 35°时tan(35°) ≈ 0.7所以深度 40 mm 处的有效孔径宽度约 56 mm。这个值如果超过探头总孔径说明该深度下所有阵元对都已经被纳入图像等价于全孔径聚焦。反过来深度 5 mm 处的有效孔径宽度只有约 7 mm这时候大约只有七八个阵元真正参与叠加这正是 TFM 近表面分辨率依然可观的原因。实际设置G时有一个容易被忽略的耦合因素角度太大时边缘阵元与像素点之间的路径在近表面区域与楔块底面反射混淆造成图像上出现一条平行于探头表面的低幅值亮带。角度太小时近表面虽然干净但 30 mm 以下的缺陷幅值可能比全孔径时低 6 dB 以上。一种常见做法是让G随深度线性展开近表面取 20 度每 10 mm 深度增加 2 度直到 40 度封顶。这个策略对大多数平面线阵探头都适用但如果你用的是曲面楔块孔径限制还应该考虑楔块到零件界面处的折射不能只看阵元几何角度。4.3 声速误差在图像上产生什么样的位移与散焦声速c错得再小也会同时造成两类后果图像散焦和缺陷横向偏移。散焦原因是所有阵元的延迟时间都按错误声速计算导致不同阵元对的相位不能对齐叠加后主瓣幅值下降、旁瓣抬高。横向偏移更大因为声程的横向分量对声速变化更敏感。简单估算一下如果真实声速是 5900 m/s你用了 5790 m/s即低估约 2%那么在 40 mm 深度、入射角 35 度的反射体上重建位置会横向偏移约 0.81 mm。这个偏移量对缺陷定量来说不可忽略。处理声速误差的标准方法是在标准试块上找一个孔径已知的小横孔先用第 3 章的代码重建图像然后调整c值重新重建观察横孔图像是否同时满足两个条件深度位置等于试块标称深度横向位置在探头中心线正下方。任何一个条件不满足都说明声速设置不合理。值得强调的是最好不要同时微调c和像素原点否则两者误差会互相掩盖导致看起来“位置对准了”实际声程计算仍然是错的。5. 用试块横孔验证一幅 TFM 图像的实用技巧TFM 图像看起来“很清楚”很容易但“清楚并且几何正确”就需要一组验证动作。这一章给出我每次在试样或管道上切换到 TFM 模式时都会做的两个技巧耗时不超过十分钟但能挡住大部分低级错误。5.1 用三枚不同深度的横孔校准声速与图像原点在试块上选三个深度相差明显的横孔比如 10 mm、25 mm、45 mm让它们位于探头下方同一水平线上。采集一次 FMC 数据重建 TFM 图后在每个孔的真实深度附近取横向切面记录图像上孔峰值的深度和横向坐标。如果三个孔的横向偏移都朝同一个方向且偏移量随深度近似线性增加那基本可以判定是声速误差按第 4.3 节的方向修正c。如果只有浅孔偏移、深孔位置正常则多半是探头前沿延迟或图像原点设置错误应该整体平移声程起点而不是动声速。5.2 叠加横波模式图像判断缺陷是近表面裂纹还是倾斜反射体标准 TFM 重建通常默认纵波-纵波路径也就是发射和接收都用纵波。当缺陷是倾斜平面或近表面裂纹时纵波路径回波幅值可能很低重建图上几乎看不到缺陷。解决手法是单独做一次横波模式的延迟计算把声速换成横波速度并将像素点到组件的路径按横波折射角重算。实际代码里只需要把前文c的取值从纵波速度改成横波速度再把成像区域的坐标系做一次倾斜修正即可。多模式图叠加时横向位置会因声速不同产生毫米级的差异这时以横孔校准结果为准不要为了让两幅图像重合去硬调声速。这一招在奥氏体不锈钢和异种钢焊缝检测里非常实用。5.3 用子孔径差分快速排除某组阵元的硬件串扰当 FMC 数据里某一两个阵元存在间歇性接触问题时整幅 TF 图会在对应位置出现一条贯穿深度方向的纵向条纹。判断方法是把阵元分成两组比如偶数下标和奇数下标各拿出一半做一次子孔径重建然后两幅图像相减。正常信号会被保留固定模式的硬件串扰会因两个子集对称而抵消。如果相减后的图像在高幅值条纹处依然清晰可见说明需要检查对应阵元的前端电路或耦合剂而不是继续调整算法参数。这个技巧不需要额外采集数据直接从已有 FMC 数据里抽子集即可对现场快速判断数据质量很有用。本文还有配套的精品资源点击获取
返回列表