1. 工具介绍
GPA(Geometric Phase Analysis,几何相位分析)是从原子分辨电镜图像 提取局部应变张量的标准方法。本工具把 Jacob Madsen 的开源桌面程序 Strain++(C++ / Qt)的核心算法 1 : 1 移植到浏览器,加了 以下扩展便于实际科研使用:
- 支持 DM3 / DM4 / EMD / TIF / PNG / JPG 输入(EMD 多通道自动挑 HAADF)
- FFT 窗口 滚轮缩放 + 拖动平移,方便找远端弱衍射斑
- FFT 衬度 γ 滑块,弱斑提亮 / 亮斑压暗
- 原图 拖矩形选参考区,自动 SVD 校准 g 让该区域应变 ≈ 0
- 计算前 勾选输出(ε 必选 / ω / Δ 可选)—— 按需付费
- 计算后 切色标 / 改量程 实时重渲染,不再扣费
- 点采样(半径可调,圆盘均值 ± 标准差)+ 线剖面(宽度可调,双面板谱线图)
- 所有图像 300 DPI 元数据,2400 px 上限的发表级 PNG
- 论文级 带刻度色标条(纵向细身,精确 ±vmax 范围)
术语提示:本手册严格区分 g(衍射矢量,reciprocal space)和 d(晶面间距,real space)。 FFT 上你点的亮斑位置是 g 矢量(单位:1/像素 或 1/nm),不是 d。
2. 工作流程总览
从打开工具到拿到论文级应变图,整体走 4 步。色标 / 量程 / 测量是结果区子功能。
全过程对一张 1024 × 1024 STEM 大约 20 ~ 40 秒(含上传、人工选 g、计算)。 4 K (4096 × 4096) 大图约 1 ~ 2 分钟,其中服务器侧 FFT + 应变计算 5 ~ 15 秒。
3. 第 1 步:上传图像
右栏「第 1 步:上传图像」拖入或点击文件框。
支持的文件格式
| 格式 | 读取库 | pixel size 自动校准 | 备注 |
|---|---|---|---|
.dm3 / .dm4 | ncempy.io.dm | ✅ 从 metadata 读 nm/px | Gatan DigitalMicrograph 原生 |
.emd | emd_converter (h5py) | ✅ Velox / Berkeley 双格式 | 多通道自动选 HAADF → MAADF → ADF → iDPC → BF → 兜底首个 |
.tif / .tiff | PIL | ⚠️ 仅当含 TIFF resolution tag | 非标 TIFF 像素尺寸未知 |
.png / .jpg / .jpeg | PIL | ❌ 无 metadata | 仅像素尺寸未知场景,距离按 px 显示 |
EMD 多通道场景:原始电镜可能同时输出 HAADF / BF / EDS map 等多个 2D 数据集,工具自动按 HAADF → MAADF → ADF → iDPC → BF 优先级挑一个 GPA 适合的(通常 HAADF 原子分辨最稳定)。
上传进度
上传时全屏覆盖一个进度框:
- 0 - 80 %:上传字节进度,显示
3.5 / 12.0 MB · 29 % - 80 - 100 %:服务器处理(DM 解析 + FFT 计算 + 渲染),显示「服务器解析 + FFT 计算 + 渲染中…」+ 动画扫描条
- 典型时间:1 K 图 1 ~ 3 秒;4 K 图 8 ~ 15 秒
常见错误与对策
| 报错 | 原因 | 对策 |
|---|---|---|
| 不支持的格式 .xxx | 扩展名不在白名单 | 转成 DM4 / TIF / PNG 再上传 |
| 文件太大(最大 200 MB) | nginx 413 | 降采样、压缩、或拆分 |
| 服务器处理失败(可能内存不足) | 4 K + 高复杂度时 OOM | 降到 2 K 重试,或开会员(同样的算力但优先级高) |
| 服务器超时 | nginx 504(处理 > 5 分钟) | 降采样后重试 |
| 网络中断 | 客户端断网 | 检查网络,重新上传 |
4 K STEM 文件经常 100 ~ 200 MB,上传需要一定耐心。建议优先 2 K × 2 K 起步验证流程,确认 g₁ / g₂ 选对后再上 4 K 跑最终结果。
4. 第 2 步:观察 FFT
上传后右栏(FFT 功率谱)自动出现 hot colormap 的 FFT 显示。这一步只是观察 + 准备点 g,不消耗计费额度。
FFT 衬度 γ 滑块
FFT 下方一个 γ 滑块(默认 1.00,范围 0.30 ~ 2.50):
- γ < 1(如 0.5)→ 提亮暗部,让弱 Bragg 斑可见
- γ = 1 → 默认 log-stretch
- γ > 1(如 2.0)→ 压低暗部,凸显最亮斑点
拖动后 200 ms 自动去抖刷新 FFT,服务端按缓存的 FFT 重新着色(不重算 FFT)。【重置】回 1.00。
缩放与平移
FFT 右上角显示当前缩放倍数(默认 1.0×)。操作:
- 🖱️ 滚轮:以鼠标位置为锚点 zoom in(×1.25 每次)/ out(÷1.25 每次),上限 20×
- 🤏 拖动:在 ≥ 1×zoom 状态下拖动平移视野(cursor 变 grabbing)
- ⤺ 复位按钮 或键盘 R:回到 1.0× 全图视野
FFT 缩放是视觉操作,不改变 g 矢量数值。点击仍然定位到原始 FFT 像素坐标。 缩放主要帮你在大图上找远端弱衍射斑(比如界面附近、高指数 Bragg)。
建议 g 半径环
上传完成后 FFT 上自动画一条金色虚线圆环,半径来自启发式算法(径向功率谱最强非中心峰)。
这只是参考,不是强制 — 用来快速指引第一组 Bragg 在哪个频率。实际你可以点任何位置当 g。
降采样估计:大图(> 2048)先 step 下采样到 ≤ 2048 算建议,结果按 FFT 周期不变定理(cycles per image 不变)直接用于原图。 如果建议半径明显偏小(如 1 px),通常是宽 DC 尾干扰,无视即可手动选。
5. 第 3 步:选取 g 矢量
右栏 Tab:g₁ 矢量 / g₂ 矢量 / 计算,前两步分别设置一个 g。
点击 FFT 设置 g₁ / g₂
选中 g₁ Tab 后在 FFT 上点击一个 Bragg 斑点(中心 DC 之外最亮的):
- FFT 上出现一个 橙色 g₁ 点 + σ 范围圆
- 右栏 g₁ 卡片显示
gₓ = +x.x px, g_y = +y.y px(相对 DC 中心的偏移)
切到 g₂ 矢量 Tab,重复操作选另一个 Bragg 斑(颜色用 绿色)。
g₁ 和 g₂ 必须不共线 —— 否则它们张不出 2D 平面,应变矩阵奇异。 建议选互相正交或夹角 ≥ 60°的两个,数值最稳定。
σ 高斯掩膜半径
每个 g 卡片有 σ 滑块(默认随建议 g 半径自适应,2 ~ 80 px):
- σ 控制 FFT 上以 g 为中心的高斯窗大小(用于 IFFT 提取相位)
- σ 太小 → 频率分辨率高,但抗噪差,相位边缘抖动
- σ 太大 → 包含相邻 Bragg 斑串扰,应变空间分辨率下降
- 典型取 g 半径 / 4,对应 σ ≈ 5 ~ 30 px
FFT 上 g 标记的圆环就是 2σ 高斯掩膜范围,可视化哪些频率被采到。
SVD 优化 g
点 g 卡片上的 SVD 优化 g₁(或 g₂)按钮:
- 系统在图像中心 60 %区域采相位
- 对相位做最小二乘线性拟合(SVD)
- 由残余梯度反推 Δg,把 g 校准到 该区域局部 g
- g 坐标更新到 2 位小数精度(亚像素),相位预览自动刷新
如果你要选「零应力参考区」(见第 6 节),那块区域才是 g 校准基准。 SVD 优化按钮用图像中心 ROI,适合样品大致均匀的场景;非均匀样品直接走参考区流程。
相位 + Bragg 预览
每选完一个 g(或调 σ),下方自动出现 4 张小图:
这 4 张预览免费,不消耗计费额度,鼓励你反复调 σ / 重选 g 直到满意。
6. 第 4 步:计算应变
切到「计算」Tab,进入主要扣费操作前的最后配置。
零应力参考区(可选)
点【🖱️ 在原图框选】→ 在原图上拖一个矩形:
- 选完美晶格区(远离界面 / 缺陷 / 位错的「干净」区域)
- 松手后系统对 g₁ 和 g₂ 各跑一次 SVD 校准,让该区域局部 g 完全对齐参考 g
- 意义:该区域应变 ≈ 0,其他区域的应变是相对此基准的值
- 视觉反馈:原图出现 青色虚线 REF 框 + 角落标签「REF (ε=0)」
什么时候用:样品有空间不均匀性(界面附近、夹杂物、位错周围)。 想问「这个界面引入多大应变」就必须参考区,否则 GPA 给的是相对全图平均 g 的偏离,物理意义弱。
框 < 16 × 16 px 不接受。点 g 重新选会自动清掉参考区。 校准失败会自动回滚 g 到上次的值,不会让你状态变坏。
应变坐标系旋转角
角度滑块(-90° ~ +90°):把应变张量从 image x / y 轴旋转到任意方向。
- 拖动时原图上实时画 青色 x' 和 金色 y' 箭头
- 对齐你想测应变的物理方向(界面法向、拉伸方向、晶向)
- 一般 0° 即可,除非你需要应变沿样品某个非水平方向看
输出选择 + 动态价格
「输出选择 · 价格」框内 3 个 checkbox:
| 分量 | 含义 | 价格 | 必选 / 可选 |
|---|---|---|---|
| ε(εxx εyy εxy) | 法向 + 对称剪切应变 | ¥5 | 必选 |
| ω(in-plane rotation) | 面内反对称分量(弧度) | +¥1 | 可选 |
| Δ(dilatation) | 体应变 = εxx + εyy | +¥1 | 可选 |
底部「本次合计」实时显示总价 ¥5 / ¥6 / ¥7。【计算应变】按钮文字同步更新。
勾哪个出哪个 —— 你要不要 ω / Δ 决定算什么 + 收多少。 计算后切色标 / 改量程不再扣费;想加分量必须重新计算重新扣费(数据缓存在原 g 配置下)。
量程 ε / ω
两个独立量程输入框:
- ε 量程(单位 %):默认 auto(按 ε 的 99 % 分位自动);填
1.5则 ε 和 Δ 色标 ±1.5 % - ω 量程(单位 rad):仅勾选 ω 时显示;默认 auto;填
0.005则 ω 色标 ±0.005 rad(≈ 0.29°)
计算后改这两个值会触发 recolor(免费重渲染)。
色标 cmap
9 种 colormap 可选:
| 名称 | 类型 | 用途 |
|---|---|---|
RdBu_r | 发散(蓝-白-红) | 默认 · GPA 标准 |
seismic | 发散(深红-白-深蓝) | 高对比 · 突出极值 |
coolwarm | 发散(柔和暖冷) | 论文图常用 |
PiYG | 发散(紫-绿) | 色弱友好 |
RdYlBu_r | 发散(红-黄-蓝) | 三色对比明显 |
BrBG | 发散(棕-青绿) | 地学风格 |
jet | 彩虹 | ⚠️ 视觉欺骗,仅兼容老论文 |
viridis | 顺序(深-黄) | 体应变只关心绝对量级时 |
inferno | 顺序(黑-红-黄) | 同上 · 暗背景 |
计算按钮 + 扣费弹窗
点【计算应变(¥X/次 · 会员无限)】:
- 扣费确认弹窗弹出(非会员):「本次操作将扣 ¥X · GPA 应变 ε + ω + Δ」+ 余额显示 + 「本会话不再提醒此工具」可选
- 确认后进入计算进度框:6 阶段轮播提示(FFT / 提取 g 相位 / 差分 / 应变张量 / 渲染 PNG)+ 扫描条动画
- 1 K 图约 3 秒,2 K 图 8 ~ 12 秒,4 K 图 30 ~ 60 秒
- 完成后结果区滑动到视野中央,5 张图(或 3 张)依次显示
7. 结果区
5 张面板(最多)
3 × 2 网格布局:
每张图左上标签显示分量名 + 量程(如 εxx (法向 x) · ±1.250%),右下【↓ PNG】按钮单图下载。
实时改色标 / 量程(免费)
计算完成后,所有以下操作免费、不再扣费(服务端缓存了 5 个 float32 分量数组,30 分钟 TTL):
- 切 cmap 下拉 → 自动 recolor 5 张图
- 改 ε 量程 → 按 Enter 或失焦触发 recolor
- 改 ω 量程 → 同上
- 所有图实时按新色标刷新,色标条也跟着换
想看 新分量(比如原本没勾 ω,现在想要):必须重新计算重新扣费。 recolor 只在原数据上重渲染。
300 DPI 论文图下载
每张图右下角【↓ PNG】下载:
- 分辨率:原图尺寸(≤ 2400 px 上限)
- DPI 元数据:300(Word / LaTeX 自动按物理英寸排版)
- 2400 px @ 300 DPI = 8 英寸打印宽(覆盖 Nature 双栏 7.2")
- 4 K 输入降采到 2400;2 K 输入保留原 2048
色标条下载 · 论文级带刻度
结果区色标下方 3 个按钮:↓ ε · ↓ ω · ↓ Δ(未勾的分量按钮 disabled)。
下载的色标 PNG 特点:
- 纵向 · 细身(0.55 × 4.5 英寸 @ 300 DPI)
- 5 个精确刻度:
-vmax、-vmax/2、0、+vmax/2、+vmax—— 端点 = 你设置的实际量程,不被 round 到「整齐数」 - raw decimal 标签(如
0.0125 / 0.00625 / 0 / -0.00625 / -0.0125),无 % 后缀,无 axis label,匹配 Nature / Science 论文最简风格 - 白底,可直接拖进 Word / Illustrator / Inkscape
8. 测量工具
结果区上方测量工具栏,模式切换:无 · 📍 点 · 📏 线。
点采样
- 切到「点」模式
- 调整半径滑块(1 ~ 40 px,默认 5)
- 在任意应变面板上单击
- 面板上画
P#圆标记 + 数字 ID - 下方表格出现一行:5 个分量的 mean ± std(ε 用 %、ω 用科学计数 rad)
表头:ID / x / y / r / εxx / εyy / εxy / ω / Δ。每行右侧 × 可删点。
【↓ 所有点 CSV】按钮免费导出全表(含 mean / std / n 样本数)。
线剖面 · CSV 收费
- 切到「线」模式
- 调整宽度滑块(1 ~ 40 px,默认 3)
- 在任意应变面板上拖一条线(width > 1 时垂直方向取均值)
- 松手后面板上画端点 + 中线 + 宽度虚线指示
- 下方出现「📏 线剖面」卡片:长度(px + nm)+ 宽度 + 采样点数
- 双面板 SVG 谱线图:上面板 εxx / εyy / εxy / Δ(共享 % 比例尺)+ 下面板 ω(独立 rad 比例尺)
- 图例点击可隐藏 / 显示单条曲线
每条线卡片 4 个按钮:
- [↓ PNG (浅底)] — 论文图:300 DPI 白底 matplotlib 渲染,免费
- [↓ PNG (深底)] — talk / PPT:同上深底,免费
- [↓ CSV] — 原始数据:¥1 / 条线,扣费弹窗确认
- [删除] — 删除此线
CSV 列:distance_px,可能含 distance_nm(若 pixel size 已知),然后 εxx / εyy / εxy / ω / Δ 5 列 fraction / rad 原值。
测量数据失效场景:重新点【计算应变】时所有点 / 线自动清除(避免用旧 g 的数据 + 新 cmap 给出误导值)。 但切 cmap / 改量程不会清测量,因为底层数据没变。
9. 完整价格表
| 操作 | 价格 | 说明 |
|---|---|---|
| 上传 + 看 FFT | 免费 | 无限次 |
| FFT γ 衬度 / 缩放 / 平移 | 免费 | 无限次 |
| 选 g₁ g₂ + 相位 / Bragg 预览 | 免费 | 反复试无成本 |
| SVD 优化 g | 免费 | 无限次 |
| 零应力参考区设置 | 免费 | 包含 g 校准 |
| 计算应变 ε(εxx εyy εxy 必出) | ¥5 / 次 | 基础 |
| + ω 面内旋转 | +¥1 | 勾选才扣 |
| + Δ 体应变 | +¥1 | 勾选才扣 |
| 切色标 / 改量程(recolor) | 免费 | 30 分钟会话内 |
| 单图 PNG 下载(300 DPI) | 免费 | 每张图 |
| 色标条下载(带刻度) | 免费 | 各分量独立 |
| 点采样 + CSV 全表 | 免费 | 不限点数 |
| 线剖面(图 + 预览) | 免费 | 不限线数 |
| 线剖面 PNG 下载(浅底 / 深底) | 免费 | |
| 线剖面 CSV 下载 | ¥1 / 条线 | 每次下载扣一次 |
会员(¥499 终身)
所有「在线工具」无限免费,不弹扣费确认。GPA 全部分量、所有线 CSV 不限次。
典型场景成本:非会员一次完整分析(ε + ω + Δ + 3 条线 CSV)= ¥10。 重复用同一张图换不同 cmap / 调参数 = 还是 ¥10(recolor 免费)。 想算别的图 → 重新扣费一次。
10. 算法原理简介
这一节给做电镜的同学参考,简要说明工具背后的数学。
核心思路
对一个理想晶格 cos(2π g · r),FFT 在 ±g 处有锐峰。如果晶格在某区域变形了:
r → r + u(r)
其中 u(r) 是位移场,那 FFT 的 Bragg 斑会出现局部相位扭曲。把 FFT 在 ±g 周围用高斯掩膜截取下来逆 FFT,得到的复数信号的相位就编码了位移:
Pg(r) = -2π · g · u(r)
两个独立 g → 完整 2D 位移
一个 g 只能给位移沿 g 方向的投影。两个不共线的 g(g₁ 和 g₂)可以联立解出完整的 2D 位移 u(r):
u(r) = -(1 / 2π) · G-T · (Pg₁, Pg₂)T
其中 G = [g₁; g₂] 是 g 矩阵。
应变张量 = 位移的空间导数
应变张量是位移的雅可比:
εij = ∂ui / ∂xj
本工具用 3 × 3 Prewitt-style 卷积核(FFT 频域加速)求一阶差分,得到 4 个分量:εxx εxy εyx εyy。
对称化 + 反对称化
原始 4 分量做对称分解:
- 对称剪切:εxy_sym = (εxy + εyx) / 2 ← 物理意义上的剪切应变
- 面内旋转:ω = (εxy − εyx) / 2 ← 反对称部分,对应局部刚体旋转
- 体应变:Δ = εxx + εyy ← 张量的迹,对应 2D 面积变化率
方法参考文献
- M. J. Hÿtch, E. Snoeck & R. Kilaas, Quantitative measurement of displacement and strain fields from HREM micrographs, Ultramicroscopy 74, 131-146 (1998).
- Jacob Madsen, Strain++ (open-source GPL v3):
github.com/JJPPeters/strainpp
本工具的 Python 实现(gpa_core.py)严格对齐 Strain++ 的 C++ 源码,包括 carrier subtraction 方向、Prewitt kernel 系数、对称化顺序、FFT shift 约定等所有细节。
合成测试:1 % 拉伸晶格 → 恢复 ε = +0.99 %(符号与 Hÿtch 1998 原始约定一致:晶格拉伸 = 正应变)。
11. 常见问题 + 实操技巧
Q:选 g 矢量时该选最亮的斑吗?
不一定。选 低阶 Bragg({100}, {110}, {111} 等)更稳定:
- 它们的信噪比最高
- 距 DC 距离适中,σ 高斯掩膜不容易污染相邻斑
- 高阶 Bragg({220}, {311} 等)周围斑点密,掩膜串扰大
Q:σ 高斯半径该选多少?
经验法则:σ ≈ g 半径 / 4,且满足 σ < 半个 Bragg 间距。
- g 半径 20 px → σ = 5 px
- g 半径 80 px → σ = 15 ~ 20 px
- 看相位预览:边缘抖动多 → σ 太小;细节平滑过头 → σ 太大
Q:参考区该多大?
越大越稳定(统计平均更可靠),但不能跨越任何应变特征。实操:
- 找一片看起来完美的晶格(远离任何界面 / 缺陷)
- 框尽量大,至少 50 × 50 px,最好 128 × 128 px 以上
- 避免框到样品边缘或被电子束损伤的区域
Q:应变值看起来都很大(> 10 %)?
可能原因:
- g₁ 和 g₂ 选错了 Bragg(不是真的斑)→ 看 Bragg 预览是否清晰
- 没设参考区,全图平均 g 偏离实际很远 → 加参考区
- 样品本身就有大应变(位错芯、强外延界面)→ 这是真实的
- FFT 上有伪影(drift / 漂移),相位含漂移分量 → 需要前处理
Q:ω 旋转图全是噪声?
ω 是反对称量,对噪声敏感。如果样品没有显著局部旋转(界面/位错附近才有),ω 图就是 ~ 0 的噪声背景。这是物理上正常的。
Q:怎么确认我的 g 选准了?
看 Bragg 预览:
- 选准 → 周期条纹清晰、对齐
- 选偏一像素 → 条纹方向 / 间距明显错
- 选到噪声 → Bragg 预览乱码
不放心就点 SVD 优化一次,让算法亚像素拉准。
Q:4 K 大图算太慢 / 服务器爆了?
- 4 K STEM 在 GPA 上算 30 ~ 60 秒正常
- 如果上传后 502,服务器 OOM 了 —— 先降采样到 2 K 验证流程,确认 g 选对再上 4 K
- 开会员(¥499 终身)的请求会有更高优先级
Q:能批量分析多张图吗?
目前不能。每张图独立上传、选 g、计算(因为 g 是样品特异的,无法跨图复用)。批量场景请联系工作室定制项目。
Q:算出来的 CSV / PNG 数据精度如何?
- 原始计算用 float64 / complex128(FFT 精度足)
- 缓存到服务器 session 用 float32(节省内存)
- 导出 CSV:6 位科学计数法
- 导出 PNG:8-bit 量化,DPI=300 元数据
- 这个精度对发表绝对足够
Q:会话 / 缓存多久过期?
30 分钟 不操作后服务器清掉缓存。表现为:
- 切 cmap → 报「image_id 不存在或已过期」
- 下载线 CSV → 同上
- 恢复:重新上传图 → 重新选 g → 重新计算