这道题gemini 2.5 pro做出来了,虽然不是一次做对的。 https://ai.studio/apps/drive/1D6FZW1zzal_TnGvfNqbh9oDdyX93eStF
开发规划文档
项目: Zernike 像差到光学质量 (PSF/OTF) 计算器
版本: 0.1 (MVP)
文档日期: 2025年10月28日
1.0 项目概述
1.1 项目背景
在眼科光学和视觉科学领域,人眼像差通常使用Zernike多项式系数来量化。像差仪、角膜地形图和波前引导手术设备(如屈光手术)都会生成这些系数。然而,Zernike系数本身(例如“ 的彗差 ”)对于临床医生、研究人员甚至患者来说都非常抽象。它们无法直观地回答一个关键问题:“这种像差到底对视觉质量有多大影响?”
本项目旨在开发一个计算工具,弥合这一差距。它将抽象的Zernike系数转换为视觉科学中最基本、最直观的光学质量指标:
- 点扩散函数 (PSF): 一个理想的点光源(如远处的一颗星星)在视网膜上实际形成的模糊图像。
- 光学传递函数 (OTF): 描述光学系统(人眼)传递不同空间频率对比度的能力。OTF 包含:
- 调制传递函数 (MTF): 对比度衰减的幅度(“图像有多模糊”)。
- 相位传递函数 (PTF): 相位是如何移动的(“图像形态扭曲了多少”,例如鬼影)。
通过本工具,用户可以直观地“看到”不同像差组合对成像质量的实际影响。
1.2 项目目标 (MVP)
开发一个核心计算引擎(MVP),该引擎接收符合特定行业标准(ANSI Z80.28)的Zernike系数,并计算出人眼模型的单色点扩散函数(PSF)、光学传递函数(OTF)、调制传递函数(MTF)和相位传递函数(PTF)。
1.3 核心假设与限制 (MVP v0.1)
此MVP版本仅支持一种固定的数据标准。用户(或调用者)有责任确保其输入数据符合以下规范。任何不符合这些规范的输入都将导致错误的计算结果。
- Zernike 标准: ANSI Z80.28 / ISO 24157 (使用 双索引)。
- 归一化 (Normalization): 正交归一化 (Orthonormal)。
- 系数单位 (Units): 微米 ()。
- 光学模型: 单色光(Monochromatic)计算。
- 瞳孔模型: 均匀透射的圆形光阑(不考虑Stiles-Crawford效应)。
2.0 理论基础与计算公式
本程序是基于傅里叶光学(Fourier Optics)的标准模型实现的。
2.1 Zernike 波前重建
波前像差 是在瞳孔平面上定义的。它通过Zernike系数 和对应的Zernike多项式 线性叠加而成。
- 是在瞳孔平面上的波前像差(单位:)。
- 是归一化的极坐标( 从 0 到 1)。
- 是输入的Zernike系数(单位:),对应 (n, m) 阶。
- 是 ANSI Z80.28 标准定义的Zernike多项式(无单位)。
2.2 瞳函数 (Pupil Function)
瞳函数 是一个复数函数,它完整地描述了光线如何通过瞳孔。
-
振幅 : 定义了瞳孔的形状和透光率。在MVP中,这是一个二元圆形掩模:
-
相位 : 描述了波前的畸变。
2.3 傅里叶光学 (PSF & OTF)
根据夫琅禾费衍射理论,PSF 和 OTF 可以通过傅里叶变换计算得出:
PSF (点扩散函数):
PSF 是瞳函数 的傅里叶变换的模的平方。
OTF (光学传递函数):
根据维纳-辛钦定理 (Wiener–Khinchin theorem),OTF 是 PSF 的傅里叶变换。
2.4 关键性能指标 (Metrics)
MTF (调制传递函数): OTF 的模。
PTF (相位传递函数): OTF 的相位角。
Strehl Ratio (斯特列尔比):
有像差系统的PSF峰值 与同一系统在衍射极限下(无像差)的PSF峰值 之比。
2.5 核心单位转换
空间频率 (lp/mm cpd):
: 用户输入的眼球焦距 (mm) (例如 16.67 mm)。
: 视网膜上的空间频率 (线对/毫米)。
: 视角空间频率 (周/度)。
转换公式:
空间坐标 (mm arcmin):
: 视网膜上的距离 (mm)。
: 对应的视角 (角分)。
转换公式:
3.0 用户需求文档 (URD) v0.1
3.1 📋 功能需求 (Functional Requirements)
FR-1: 用户输入(计算参数)
用户必须能够为每次计算提供以下参数:
FR-1.1: Zernike 系数列表
- 描述: 程序的输入核心。用户需提供一组Zernike系数。
- 格式: 应为 (n, m, C) 的组合,其中 为径向阶数, 为方位角频率, 是以 为单位的系数值。
FR-1.2: 瞳孔直径 (Pupil Diameter)
- 描述: Zernike系数所对应的瞳孔大小。
- 单位: 。
FR-1.3: 计算波长 (Wavelength)
- 描述: 用于计算的单色光波长。
- 单位: (例如: 550 nm)。
FR-1.4: 眼球焦距 (Focal Length)
- 描述: 用于空间频率单位转换的简化眼模型焦距(后节点到像面的距离)。
- 单位: 。
- 备注: 程序应提供一个合理的默认值(例如 ,对应约 60D 的眼球屈光力),但必须允许用户覆盖此值。
FR-2: 核心计算(后端引擎)
系统必须在内部执行以下计算:
- FR-2.1: 波前重建 (Wavefront Map): 根据输入的Zernike系数 (FR-1.1) 和瞳孔直径 (FR-1.2),在一个N x N的网格上重建出2D的波前像差图 ,单位为 。
- FR-2.2: 瞳函数 (Pupil Function) 生成: 构建复数瞳函数 。
- 振幅 : 在 (FR-1.2) 定义的瞳孔直径内为 1,直径外为 0。
- 相位 : ,其中 来自 (FR-2.1), 来自 (FR-1.3)。
- FR-2.3: PSF 计算: 计算2D的点扩散函数 (PSF)。
- 方法: ( 是2D傅里叶变换,应使用FFT实现)。
- FR-2.4: OTF 计算: 计算2D的光学传递函数 (OTF)。
- 方法: (根据维纳-辛钦定理)。
- 归一化: OTF必须被归一化,使其在零频率 处的值为 1。
- FR-2.5: 衍射极限 (Diffraction-Limited) 参考计算: 系统必须使用相同的参数(FR-1.2, FR-1.3, FR-1.4),但将所有Zernike系数设为0,计算出理想的、无像差的 ,用于 (FR-3.5) 的计算。
FR-3: 数据输出(计算结果)
系统必须向用户提供以下有意义的结果:
- FR-3.1: 2D PSF 图像/数据:
- 显示: 应能以线性标尺和对数标尺 (Log Scale) 两种方式显示,以便观察光晕和衍射环。
- 坐标轴: 空间坐标轴应能映射为 视角 (arcmin 或 degree) 或 视网膜上的 。
- FR-3.2: 2D MTF 图像/数据:
- 描述: 显示2D MTF的“俯视图”,直观展示不同方向的调制传递特性。
- FR-3.3: 1D MTF 曲线:
- 描述: 提供 径向平均 (Radially Averaged) 后的1D MTF曲线图。
- Y轴: 调制深度 (Modulation),范围 0 到 1。
- X轴 (空间频率): 必须提供单位换算选项:cycles/degree (cpd),lp/mm。
- FR-3.4: 1D PTF 曲线:
- 描述: 提供 特定方向切片 (Slice) 的1D相位传递函数曲线(注: PTF不应进行径向平均)。
- Y轴: 相位 (Phase),单位为 弧度 (Radians) 或 角度 (Degrees)。
- X轴 (空间频率): 必须与 (FR-3.3) 的X轴(cpd, lp/mm)保持一致,以便对比。
- FR-3.5: 斯特列尔比 (Strehl Ratio):
- 描述: 提供一个单一数值,作为光学质量的快速摘要。
- 计算: ,其中 来自 (FR-2.5)。
3.2 📚 非功能需求 (Non-Functional Requirements)
- NFR-1: 文档 (README.md 或 "关于" 页面):
- NFR-1.1 (标准声明): 必须在文档的显著位置清晰声明:本程序MVP版本仅接受 ANSI Z80.28 (双索引 )、正交归一化、单位为 的Zernike系数。
- NFR-1.2 (警告): 必须包含一个“警告”部分,说明:如果输入了其他标准(如Noll单索引、Fringe索引、P-V归一化或'waves'单位)的数据,将导致计算结果完全错误。
- NFR-2: 性能: 对于常规计算(例如10阶Zernike系数,256x256计算网格),PSF/OTF的完整计算应在数秒内完成。
- NFR-3: 精度: 在执行 (FR-2.3) 的FFT之前,必须对 (FR-2.2) 的瞳函数矩阵进行充分的补零 (Zero Padding)(例如,将 256x256 补到 1024x1024 或更高),以保证PSF的采样精度并避免OTF的混叠。
4.0 🏛️ 公理设计分析 (Axiomatic Design)
公理设计的核心是将“做什么”(功能需求 FR)映射到“怎么做”(设计参数 DP),并尽量保持这种映射关系的独立性。
4.1 映射表 (FR → DP)
| 功能需求 (FR) | 描述 (做什么) | 设计参数 (DP) | 实现 (怎么做) |
|---|---|---|---|
| FR-1: 用户输入 | 接收所有计算参数 | DP-1: ParameterConfig 对象 |
一个数据类 (dataclass)、结构体 (struct) 或纯粹的对象 (plain object),用于封装所有输入 (FR-1.1 至 1.4)。 |
| FR-1.1 | Zernike 系数列表 | DP-1.1: Zernike (n, m, C) 列表 | 一个数组的数组 (Array of Arrays)、元组列表 (List of Tuples) 或键值映射 (Map/Dictionary)。 |
| FR-1.2 | 瞳孔直径 | DP-1.2: pupil_diameter_mm 变量 |
一个浮点数 (Float) 类型的变量。 |
| FR-1.3 | 计算波长 | DP-1.3: wavelength_nm 变量 |
一个浮点数类型的变量。 |
| FR-1.4 | 眼球焦距 | DP-1.4: focal_length_mm 变量 |
一个浮点数类型的变量,具有 的默认值。 |
| FR-2: 核心计算 | 执行光学变换 | DP-2: OpticalEngine 模块 |
一个核心计算模块,包含执行傅里叶光学的函数。 |
| FR-2.1 | 波前重建 | DP-2.1: reconstruct_wavefront 函数 |
一个函数,输入 DP-1.1 和网格大小,循环Zernike多项式并求和,输出 2D 波前图 。 |
| FR-2.2 | 瞳函数生成 | DP-2.2: create_pupil_function 函数 |
一个函数,输入 和 DP-1.3,计算 ;并应用一个圆形二元掩模 (Mask) 和补零 (NFR-3)。 |
| FR-2.3 | PSF 计算 | DP-2.3: calculate_psf 函数 |
一个函数,对 DP-2.2 的输出执行 2D FFT、FFT 移位和取模的平方。 |
| FR-2.4 | OTF 计算 | DP-2.4: calculate_otf 函数 |
一个函数,对 DP-2.3 的输出执行 2D FFT、FFT 移位,并归一化。 |
| FR-2.5 | 衍射极限参考 | DP-2.5: 对 DP-2 的复用 | 一个流程,使用空的 Zernike 系数列表 (DP-1.1) 调用 DP-2.1 至 DP-2.3,以生成 。 |
| FR-3: 数据输出 | 分析和格式化结果 | DP-3: Analysis 模块 |
一个后处理模块,用于从原始 PSF/OTF 数据中提取可用的指标。 |
| FR-3.1 | 2D PSF (对数) | DP-3.1: process_psf_2d 函数 |
一个函数,对 数据取 并处理 的情况。 |
| FR-3.2 | 2D MTF | DP-3.2: get_mtf_2d 函数 |
一个函数,对 数据取 abs() (复数取模)。 |
| FR-3.3 | 1D MTF (径向平均) | DP-3.3: calculate_radial_mtf 函数 |
- |
| FR-3.4 | 1D PTF (切片) | DP-3.4: get_ptf_slice 函数 |
一个函数,对 数据取 angle() (复数取相位角),并提取指定方向的切片。 |
| FR-3.5 | Strehl Ratio | DP-3.5: calculate_strehl 函数 |
一个函数,输入 和 ,返回二者峰值之比。 |
| FR (隐式) | 为图表生成正确的坐标轴 | DP-4: UnitConverter 模块 |
一个工具模块,用于处理物理单位和坐标轴的映射。 |
| (来自FR-3.1) | PSF 坐标 (arcmin/µm) | DP-4.1: generate_spatial_axes 函数 |
一个函数,根据焦距 (DP-1.4) 和阵列大小,计算像平面的空间坐标。 |
| (来自FR-3.3/4) | OTF 坐标 (cpd/lp/mm) | DP-4.2: generate_frequency_axes 函数 |
一个函数,根据焦距 (DP-1.4) 和阵列大小,计算频率平面的坐标。 |
4.2 设计评估
此设计是高度解耦 (Decoupled) 的。
DP-1 (输入) → DP-2 (计算) → DP-3 (分析) → DP-4 (单位)。
我们可以独立更改 DP-2 中的 FFT 算法(例如,切换库),而不会破坏 DP-3 的 Strehl Ratio 计算。我们可以独立更改 DP-4 中的 cpd 计算公式(例如,从 tan(1°) 改为小角度近似),而不会破坏 DP-2 的 OTF 计算。
这种设计是健壮且易于维护的,符合公理设计的独立性公理。
5.0 🧩 模块化设计 (技术栈无关)
基于上述 DP,我们定义以下逻辑模块。这些模块可以实现为命名空间 (Namespaces)、独立的类 (Classes) 或文件 (Modules)。
Main Controller (应用主入口)
- 职责: 作为程序的入口点和协调器。
- 功能:
- 接收用户输入(在MVP中可能只是硬编码的配置对象)。
- 创建
ParameterConfig数据结构 (DP-1)。 - 按顺序调用 Zernike Engine、Optics Engine 和 Analysis Engine。
- 调用 Visualization 模块来显示结果。
Zernike Engine (Zernike 核心)
- 职责: 所有与Zernike多项式相关的数学计算。
- 关键依赖: 一个数学库(用于处理三角函数 sin, cos 和阶乘)。
- 接口 (Interface) / 导出的函数:
zernike_ansi(n, m, rho, theta): (DP-2.1) 计算单个 ANSI 标准 Zernike 多项式在 坐标的值。reconstruct_wavefront(coeffs, ...): (DP-2.1) 循环调用zernike_ansi,构建 2D 波前图 。
Optics Engine (傅里叶光学引擎)
- 职责: 执行核心的物理光学计算。
- 关键依赖: 一个支持复数 (Complex Numbers) 运算和 2D 快速傅里叶变换 (FFT) 的数值计算库。
- 接口 (Interface) / 导出的函数:
create_pupil_function(wavefront_map, ...): (DP-2.2) 创建带补零的复数瞳函数矩阵。calculate_psf(pupil_function): (DP-2.3) 计算 PSF。calculate_otf(psf): (DP-2.4) 计算 OTF。
Analysis Engine (后处理与分析)
- 职责: 从原始的 2D 矩阵数据中提取有意义的度量。
- 关键依赖: 一个数值计算库(用于矩阵操作、取模、取相位、求和、查找峰值)。
- 接口 (Interface) / 导出的函数:
process_psf_2d(psf_data): (DP-3.1) 生成对数标尺 PSF。get_mtf_2d(otf_data): (DP-3.2) 提取 2D MTF。calculate_radial_mtf(mtf_2d): (DP-3.3) 实现径向平均。get_ptf_slice(otf_data, axis): (DP-3.4) 提取 PTF 切片。calculate_strehl(psf_aber, psf_ideal): (DP-3.5) 计算 Strehl 比。
Utilities (实用工具与单位转换)
- 职责: 提供坐标轴生成和单位转换。
- 关键依赖: 基础数学库。
- 接口 (Interface) / 导出的函数:
generate_spatial_axes(config): (DP-4.1) 计算 和 坐标。generate_frequency_axes(config): (DP-4.2) 计算 和 坐标。
Visualization (结果可视化)
- 职责: 将分析后的数据绘制成图表。
- 关键依赖: 一个 2D 绘图/图表库。
- 接口 (Interface) / 导出的函数:
plot_psf(psf_data_linear, psf_data_log, axes): 绘制 2D PSF 图像 (热力图或等高线图)。plot_mtf_ptf(mtf_1d, ptf_1d, freq_axes, mtf_ideal_1d): 绘制 1D MTF/PTF 曲线 (折线图)。
6.0 🚀 项目实施计划 (技术栈无关)
这是一个按技术依赖排序的实施步骤(不含时间估计)。
阶段 0: 项目设置
- 初始化版本控制系统 (Git)。
- 初始化项目环境 (例如 npm, pip, conda 等)。
- 确定并安装核心依赖库:
- 数值计算与 FFT 库
- 2D 绘图库
阶段 1: Zernike 核心 (Zernike Engine)
- 实现
zernike_ansi函数 (DP-2.1)。 - 单元测试 1.1: 使用已知的 值(如 离焦)验证其数学形态是否正确。
- 实现
reconstruct_wavefront函数 (DP-2.1)。 - 单元测试 1.3: 传入一个纯离焦系数,验证生成的波前图是否为正确的抛物面。
阶段 2: 傅里叶光学引擎 (Optics Engine)
- 实现
create_pupil_function(DP-2.2),包括圆形掩模和补零 (NFR-3)。 - 实现
calculate_psf(DP-2.3)。 - 实现
calculate_otf(DP-2.4)。 - 关键集成测试 (衍射极限):
- 设置 Zernike 系数为 0 (DP-2.5)。
- 运行 2.1 → 2.2 → 2.3 计算。
- 验证:
- 是否为艾里斑 (Airy Disk)。
- (即 OTF 的模) 是否为已知的圆形成孔径的 MTF 理论曲线。(此步骤是 MVP 成功的关键验证点)
阶段 3: 分析与坐标 (Analysis Engine & Utilities)
- 实现
calculate_strehl(DP-3.5)。(需要 2.4 的 峰值)。 - 实现
calculate_radial_mtf(DP-3.3)。 - 实现
get_ptf_slice(DP-3.4)。 - 实现
generate_spatial_axes(DP-4.1) 和generate_frequency_axes(DP-4.2)。 - 单元测试 3.4: 验证焦距 (60D) 下, 是否正确对应于 。
阶段 4: 编排与可视化 (Main Controller & Visualization)
- 创建 Main Controller (DP-1),硬编码一组测试参数(如 的 离焦)。
- 在 Main Controller 中按顺序调用 core 模块,完成从输入到分析的全流程。
- 创建
plot_psf函数 (DP-3.1),并显示结果(包括对数标尺)。 - 创建
plot_mtf_ptf函数 (DP-3.3, 3.4),并显示结果。
阶段 5: 最终验证与文档
- 集成测试 (像差):
- 使用已知的像差(如纯离焦、纯散光、纯彗差)运行全流程。
- 验证:
- 离焦是否导致 PSF 弥散,Strehl 下降,MTF 在中频衰减。
- 散光是否导致 PSF 呈椭圆或线状,MTF 在两个正交方向上不一致。
- 彗差是否导致 PSF 出现拖尾,并且 PTF 曲线出现显著的非零相位。
- 创建 README.md 文件(或同等的项目文档)。
- 重要 在文档中添加 URD 中的 NFR-1.1 (标准声明) 和 NFR-1.2 (警告)。