Zernike多项式:用hcipy构建Zernike光场
文章目录
- Zernike多项式
- 索引号
HCIPy(High Contrast Imaging for Python)是一个开源、模块化的Python框架,专为天文高对比度成像系统的端到端仿真而设计。它主要用于模拟系外行星等暗弱天体在明亮恒星附近的成像过程,核心功能包括大气湍流仿真、自适应光学控制、日冕仪设计以及光波衍射传播计算。该框架采用面向对象架构,引入"场"(Field)数据结构统一处理空间坐标与光学场量,有效简化代码语法并降低用户操作错误。
Zernike多项式
Zernike多项式是一种用于描述波前的正交多项式,因其低阶项与赛德尔相差一一对应,故而用途广泛。其前15阶的波前图像如下

基于hcipy的生成与绘图代码如下
import hcipy
import matplotlib.pyplot as plt
plt.rcParams['font.sans-serif'] = 'Times New Roman'
grid = hcipy.make_pupil_grid(500, 1.0)
plt.figure(figsize=(10, 8))
for i in range(1, 16):
mode = hcipy.zernike_ansi(i-1, 1, grid)
m = 6 if i in [2,3,7,8,9,10] else 5
if i == 1:
n = 3
elif i in [2, 3]:
n = i + 7
elif i in [4, 5, 6]:
n = i + 8
elif i in [7, 8, 9, 10]:
n = i + 13
else:
n = i + 10
plt.subplot(5, m, n)
#img = modes[i-1].shaped # hcipy Field → 2D array
plt.imshow(mode.shaped, cmap='jet', origin='lower')
plt.axis('off')
plt.title(f'Z{i-1}', fontsize=8)
plt.tight_layout()
plt.show()
【zernike_ansi】用于生成Zernike多项式基函数对应的波前,其输入参数分别为ANSI序号、入瞳直径以及离散网格。其中只有第一个参数是必不可少的,入瞳直径D默认为1m,离散网格grid默认为None,如果不输入grid,则该函数会返回一个Zernike光场的生成器,而非现在这样直接返回模式。此外,还有一个布尔型参数radial_cutoff默认为True,表示用圆孔对模式进行切断。
【make_zernike_basis】可以一次性生成多组Zernike多项式基函数对应的波前,其输入参数分别为模式数、入瞳直径以及离散网格。上例中,网格是通过make_pupil_grid生成的直径为1m的圆孔。除了这三项之外,该函数中还有一些可缺省参数,starting_mode默认为1,表示输出从那个模式开始;ansi默认为False,表示不按照ansi标准的顺序输出;radial_cutoff与zernike_ansi中功能一致。
索引号
早在1934年,Zernike便构造出了单位圆上的正交多项式的集合,即Zernike多项式,表达式为
Z n m ( ρ , θ ) = [ 2 ( n + 1 ) 1 + δ m 0 ] 1 2 R n m ( ρ ) cos m θ R n m ( ρ ) = ∑ s = 0 n − m 2 ( − 1 ) s ( n − s ) ! s ! ( n + m 2 − s ) ! ( n − m 2 − s ) ! ρ n − 2 s egin{aligned} Z^m_n( ho, heta)&=left[rac{2(n+1)}{1+delta_{m0}} ight]^{rac{1}{2}}R^m_n( ho)cos m heta R^m_n( ho)&=sum_{s=0}^{rac{n-m}{2}}rac{(-1)^s(n-s)!}{s!left(rac{n+m}{2}-s ight)!left(rac{n-m}{2}-s ight)!} ho^{n-2s} end{aligned} Znm(ρ,θ)Rnm(ρ)=[1+δm02(n+1)]21Rnm(ρ)cosmθ=s=0∑2n−ms!(2n+m−s)!(2n−m−s)!(−1)s(n−s)!ρn−2s
其中 R n m R^m_n Rnm为径向函数。尽管这个多项式看上去有些复杂,但 m , n m,n m,n这两个明晃晃的编号却表明,Zernike多项式不像一维函数的Taylor级数那样存在一个天然的编号次序。
1975年,Noll在基于Zernike多项式研究大气湍流时,将其写成如下形式
Z j ( ρ , θ ) = { n + 1 R n m ( ρ ) 2 cos m θ , m ≠ 0 , for even j n + 1 R n m ( ρ ) 2 sin m θ , m ≠ 0 , for odd j n + 1 R n 0 ( ρ ) , m = 0 Z_j( ho, heta)=left{egin{aligned} &sqrt{n+1}R^m_n( ho)sqrt2cos m heta, &m& ot=0, ext{ for even }j &sqrt{n+1}R^m_n( ho)sqrt2sin m heta, &m& ot=0, ext{ for odd }j &sqrt{n+1}R^0_n( ho),&m&=0 end{aligned} ight. Zj(ρ,θ)=⎩ ⎨ ⎧n+1Rnm(ρ)2cosmθ,n+1Rnm(ρ)2sinmθ,n+1Rn0(ρ),mmm=0, for even j=0, for odd j=0
在Noll的论文中,列了一个 j j j与 m , n m,n m,n的对应表格,这个表就是Noll索引,其特点是通过奇偶性区分 cos cos cos和 sin sin sin项,索引从1开始。
2002年,ANSI和OSA指定了眼科光学标准,给出了Zernike多项式的另一组一维编号,并推荐使用该编号用于人眼像差报告,业内将这个顺序成为ANSI索引。此索引通常从0开始,但有的时候也会从1开始。
Noll和ANSI排序都是先排 n n n,二者的关键区别是对 m m m顺序的处理上,ANSI排序根据m的自然大小排序,Noll则按照 ∣ m ∣ ert mert ∣m∣的大小进行排序。在前面的绘图示例中,采用了ANSI顺序,对每一行 n n n,其 m m m从负值排到正值,左右对称;如果按照Noll标准,则从左到右更能体现出畸变程度的变化。
hcipy中提供了Zernike索引与Noll和ANSi索引之间相互转换的函数,如下表所示
noll_to_zernike(i)
zernike_to_noll(n, m)
ansi_to_zernike(i)
zernike_to_ansi(n, m)
根据这几个函数,可以绘制出三者之间的对应关系
| Noll顺序 | Zernike | ANSI | ∣ ert ∣ | ANSI顺序 | Zernike | Noll |
|---|---|---|---|---|---|---|
| 1 | 0,0 | 0 | ∣ ert ∣ | 0 | 0,0 | 1 |
| 2 | 1,1 | 2 | ∣ ert ∣ | 1 | 1,-1 | 3 |
| 3 | 1,-1 | 1 | ∣ ert ∣ | 2 | 1,1 | 2 |
| 4 | 2,0 | 4 | ∣ ert ∣ | 3 | 2,-2 | 5 |
| 5 | 2,-2 | 3 | ∣ ert ∣ | 4 | 2,0 | 4 |
| 6 | 2,2 | 5 | ∣ ert ∣ | 5 | 2,2 | 6 |
| 7 | 3,-1 | 7 | ∣ ert ∣ | 6 | 3,-3 | 9 |
| 8 | 3,1 | 8 | ∣ ert ∣ | 7 | 3,-1 | 7 |
| 9 | 3,-3 | 6 | ∣ ert ∣ | 8 | 3,1 | 8 |
| 10 | 3,3 | 9 | ∣ ert ∣ | 9 | 3,3 | 10 |
| 11 | 4,0 | 12 | ∣ ert ∣ | 10 | 4,-4 | 15 |
| 12 | 4,2 | 13 | ∣ ert ∣ | 11 | 4,-2 | 13 |
| 13 | 4,-2 | 11 | ∣ ert ∣ | 12 | 4,0 | 11 |
| 14 | 4,4 | 14 | ∣ ert ∣ | 13 | 4,2 | 12 |
for i in range(1,15):
n, m = hcipy.noll_to_zernike(i)
j = hcipy.zernike_to_ansi(n, m)
print(f"|{i}|{n},{m}|{j}")
for i in range(14):
n, m = hcipy.ansi_to_zernike(i)
j = hcipy.zernike_to_noll(n, m)
print(f"|{i}|{n},{m}|{j}")
针对这三种顺序,hcipy提供了三个函数,用于生成单项Zernike基函数,即
- 【zernike】输入 n , m n,m n,m
- 【zernike_noll】输入Noll序号
- 【zernike_ansi】输入ANSI序号,即上例绘图中使用的函数











