SuperAPI AI 工具集

openpiv

数据与分析

查看项目

更新于 10-21 16:21

技能介绍

OpenPIV(Open Particle Image Velocimetry)用于从 PIV 图像对中分析流体流动,覆盖预处理、互相关、矢量验证、异常值替换、平滑以及换算到物理单位等环节。以下内容基于 openpiv 0.25.4 验证;该库 API 在不同版本间会变化,使用其他版本前建议先用 inspect.signature() 核对。

【用途】 适用于实验 PIV 或流动可视化图像对:测量二维速度场、调整查询窗口参数、验证矢量,或推导涡量、应变率和湍流统计量。若需要模拟流动而非测量流动,应改用 CFD 技能。

【安装】 uv pip install openpiv 如需可复现分析,可固定版本:uv pip install "openpiv==0.25.4"

【快速开始】 对图像对运行 PIV 分析的基本流程:读取图像(tools.imread)、互相关(pyprocess.extended_search_area_piv,返回 u、v、s2n)、获取坐标(pyprocess.get_coordinates)、信噪比验证(validation.sig2noise_val)、异常值替换(filters.replace_outliers)、换算物理单位(scaling.uniform)并翻转坐标(tools.transform_coordinates),最后保存(tools.save)。也可使用捆绑的 CLI:python skills/openpiv/scripts/runner.py --image frame_a.bmp --image frame_b.bmp --output_dir results --verbose。

【核心概念】 PIV 是通过追踪两幅图像间被照亮的示踪粒子来测量流体速度的光学方法。流程为:采集间隔已知时间 dt 的图像对;划分查询窗口;对匹配窗口做互相关求峰值位移;验证矢量(信噪比、全局范围、局部中值);用插值替换异常矢量;将像素位移换算为物理单位。 查询窗口参数:window_size 为相关窗口像素(通常 16–128),越大相关越好但空间分辨率越粗;overlap 为相邻窗口共享像素(通常为 window_size 的 50–75%),越高矢量密度与成本越高但相邻矢量相关性增强;search_area_size 为第二帧中搜索的窗口,须 ≥ window_size,略大几像素可容纳更大位移,并应搭配 correlation_method="linear"(默认 "circular" 依赖 FFT 环绕,会把大位移混叠为小位移)。经验规则:最大位移保持在 window_size 约四分之一以内,每个窗口约 5–10 个粒子。 信噪比:s2n 衡量相关峰的显著程度,sig2noise_method 可为 "peak2mean"(函数默认)或 "peak2peak",两者尺度不同,阈值不可混用;peak2peak 典型阈值为 1.05–1.3。flags 为布尔数组,True 表示异常矢量,~flags 选出有效矢量。

【常用操作】 动态掩膜位于 openpiv.preprocess(不是 openpiv.masking),返回 (image, mask) 元组并期望浮点图像;method="edges" 适合暗色锐边物体,"intensity" 适合高对比物体。返回的图像已对掩膜区域置零,不要再将原始帧乘以 mask。 多遍处理(窗口变形)位于 openpiv.windef,由 PIVSettings 数据类驱动,pyprocess 没有多遍入口。可设置 windowsizes、overlap、num_iterations、sig2noise_threshold,再调用 windef.simple_multipass。注意:输出单位为像素/帧,需自行换算;PIVSettings 虽有 dt 和 scaling_factor 字段,但 windef 从不使用它们,设置 settings.dt 不会改变返回值。simple_multipass 已完成验证、异常值替换、NaN 填零和 transform_coordinates,不要重复这些步骤。

【验证与后处理】 每个验证器返回布尔数组,True 标记异常矢量。可用 sig2noise_val、global_val(接收 (min, max) 元组)、local_median_val(u_threshold 与 v_threshold 必填,size 为邻域半宽),并用布尔 OR 组合。阈值应使用 u、v 的单位而非像素/帧;extended_search_area_piv 会除以 dt,因此 dt=0.02 时 3 像素/帧位移会变成 150 像素/秒,文献中 (-30, 30) 这类像素/帧限制若直接用于像素/秒输出会拒绝整个场。 异常值替换使用 filters.replace_outliers,method 仅接受 "localmean"、"disk"、"distance";无法识别的名称不会被拒绝,而是退化为全零核并静默返回无用场。替换会用插值填充被标记位置,若之后又覆盖为 NaN 则替换被浪费,需二选一。 平滑使用 openpiv.smoothn.smoothn(没有 openpiv.smooth 模块),返回元组,首元素为平滑场,且不接受 NaN 输入。

【可视化】 display_vector_field 读取保存的矢量文件并在内部调用 plt.show(),批量运行时应选择非交互后端(如 matplotlib.use("Agg"))。也可自定义绘制速度幅值、U 分量、V 分量等。

【分析函数】 scripts/analyze.py 针对 runner.py 写出的 params.npz 打包了这些功能,会从保存的坐标推断物理网格间距,使导数按单位长度给出。可调用 PIVAnalyzer 的 compute_vorticity、compute_strain、compute_statistics、plot_vector_field。独立形式包括涡量(dv/dx - du/dy)、应变率张量 (exx, eyy, exy) 和湍流统计(u_mean、v_mean、rms_u、rms_v、tke)。注意:网格间距为 (window_size - overlap) / scaling_factor,dx=1.0 得到的是每网格单元而非每单位长度的涡量;符号约定方面,runner.py 末尾的 transform_coordinates 会重标网格为右手 y 向上但保留图像行序,独立形式假设相反,会翻转涡量与剪切应变符号,可对 axis=0 导数取负或使用 PIVAnalyzer。统计函数是单帧空间统计,并非雷诺分解;真正的雷诺分解需要图像对集合。

【CLI 用法】 基本运行:python skills/openpiv/scripts/runner.py --image img1.bmp --image img2.bmp --output_dir results --verbose。可调参数包括 --window_size(默认 32)、--overlap(默认 12)、--search_area(默认 38,须 ≥ window_size)、--dt(默认 0.02)、--scaling(默认 96.52)、--threshold(默认 1.05)、--mask(none 或 dynamic)、--mask_method(edges 或 intensity)、--drop_invalid、--verbose。可用 run_example.py 对 OpenPIV 自带图像对做端到端验证。

【输出文件】 vectors.txt(制表符分隔,%.4e 格式,含 # x y u v flags mask 注释头)、params.npz(含 x、y、u、v、flags 数组)、vector_field.png(叠加在第一帧上的矢量场)。flags 以浮点写出,0 为有效矢量,1 为被标记矢量。

【最佳实践】 参数选择:窗口大小 32×32 适合多数情况,64/128 相关更好但分辨率更粗,16/24 分辨率更细但噪声更大;重叠取窗口大小的 50–75%;提高阈值可拒绝更多矢量,切换 sig2noise_method 后须重新调参;缩放因子应针对已知参考(如标定网格)校准并保持单位一致(OpenPIV test1 教程数据中的 96.52 为像素/毫米)。图像质量:粒子可见且分布均匀,每个查询窗口 5–10 个;无饱和或过曝区域;背景噪声尽量小,可考虑整轮运行做背景减除。处理建议:从默认值开始再根据矢量场调参;检查 s2n 分布,中位数低意味着相关差而非阈值不当;尽早可视化;对大速度梯度或位移的流动使用多遍(windef);对反射和固体边界做掩膜而非让其生成矢量。

【资源与相关技能】 references/advanced_algorithms.md 涵盖相关与亚像素方法、多遍窗口变形、PIVSettings 字段、三维与相分离模块,需要详细算法或设置信息时可加载。相关技能:scvelo(对具有 spliced 和 unspliced 层的单细胞 RNA-seq AnnData 对象执行 RNA 速度分析)。