不想设计镜头的程序员不是好摄影师——我说的(无误 →_→) 小的时候我对望远镜很着迷,透过这小小的镜筒,竟能让远处的景物纤毫毕现,简直是魔法。在初中的时候,凭借学到的仅有的一点平面几何的知识,在 Excel 里写公式计算了两个反射球面组成的系统的轴向球差曲线(当然了那个时候不懂叫这个名词),亲手验证了球面反射镜系统对平行光不能完美成像,为此还和自然科学课的老师讨论了很久。后来通过手动调整两个球面的曲率(人肉优化?),看到了球差曲线的变化,第一次亲眼见证了球差补偿之后的勺子形状的曲线,激动不已。时隔多年之后的今天回想起来,仍然清晰地记得那时激动的心情。
这篇文章,就来带领大家真正从头设计一个折射望远镜(的物镜)。我希望可以让大家体会到我当年的那些激动的心情。也许读者朋友们也会像我当年一样,深深地被光学所吸引,走进一个广阔的天地。
既然是设计镜头,难免需要写一些公式进行计算。如果不感兴趣可以只看大概,然后跳到结果看图就可以。
1. 基本情况
在动手之前,我们先确定一些基本的情况,对我们要设计的系统有一个大体的估计。我比较喜欢这种思考风格,先不陷入各种细节,而是从整体上,从第一性原理出发,看看我们要研究的这个对象应该具有哪些性质,它的性能边界在哪里。有了整体的印象和边界,我们才不会走错路。
首先确定一些基本参数。我希望设计一款用于单反拍摄的望远镜,主要用来拍摄月亮,以及一些中等大小的深空目标(比如昴星团、猎户座大星云等),那么有效视角可以设定为 1.3° 左右(半视场角 0.65°)。单反的感光元件对角线长度约为44mm,按照有效视场角推算,焦距在 2000mm 左右是比较合适的。
在成像质量方面,我们主要关注哪些像差呢?
在前面的文章《光学系统像差杂谈(6):第一眼天空》中,我们知道,望远镜的特点是焦距长,视场小。也就是说望远镜的工作状态就是几乎只对无穷远的轴上物体进行成像。这个特点决定了对望远镜而言,最需要关注的像差就是球差,因为球差是唯一的轴上像差。对于其他单色像差,在望远镜的这种小视场的使用场合下并不显著。我们的设计必须对球差有良好的校正。
此外,我们要设计的是折射望远镜,那么就必然会遇到色差,我们也必须对色差有良好校正。在之前的文章《光学系统像差杂谈(7):跌宕起伏的斑斓路》中我们了解到,至少需要两种不同性质的光学玻璃,才能对两种颜色的光消除色差。即使这样也仍然有二级光谱的问题。对常规玻璃组合来说,二级光谱几乎是一个常量。若要消除或者减弱二级光谱,也就是所谓的复消色差要求(APO),则要么采用特殊的光学材料(比如萤石),要么采用复杂的结构。作为一个简单的设计,我们就先不关注二级光谱了。
要消除色差,我们至少要两片透镜进行组合,那么最简单的形式就是双胶合镜组了。对于双胶合镜组,一共有 3 个表面曲率作为变量(或许大家会想到还有 2 个透镜厚度可以作为变量,但是对于普通透镜来说,厚度的变化对像差的影响非常小),那么理论上我们可以达成最多 3 个方面的目标。恰好,我们上面的分析已经给出了这三个目标:焦距等于 2000mm、消除色差、消除球差。事实上,双胶合镜组就是能满足这三个目标的最简单结构。
2. 初始设计
在初始设计中,我们尽可能做简化,忽略不重要的东西,抓住主体。在双胶合设计中,什么是重要的,什么是不重要的呢?很明显,三个表面的曲率是至关重要的因素,而透镜的厚度不重要。我们可以采用「薄透镜」假设,也就是令透镜厚度等于零,这可以大大简化计算过程。我们以薄透镜来作为出发点,开始我们的初始计算。
假设双胶合镜的三个表面曲率分别为 c1,c2,c3,两个透镜分别用 a 和 b 来标记。在上一段中分析得到的三个目标,我们来逐个分析一下。
第一个,焦距等于 2000mm。我们知道,焦距是光学系统的一阶性质,在这个目标下,其他单色像差是高阶量,可以忽略。我们可以只用高斯光学来列出方程式。
\frac{1}{f_a}=(n_a-1)(c_1-c_2)\tag{1}
\frac{1}{f_b}=(n_b-1)(c_2-c_3)\tag{2}
\frac{1}{f_a}+\frac{1}{f_b}=\frac{1}{f}=\frac{1}{2000}\tag{3}
上面 (1) 和 (2) 是薄透镜的焦距计算公式,(3) 是两个薄透镜合成焦距的计算公式。
第二个,消除色差。根据《光学系统像差杂谈(7):跌宕起伏的斑斓路》中所讨论的,色差也是光学系统的一阶性质。在那篇文章末尾已经列出了消除色差所需要的方程式。
\frac{1}{f_a V_a}+\frac{1}{f_b V_b}=0\tag{4}
上面 Va 和 Vb 是两片透镜所用玻璃的阿贝数。
第三个,消除球差。球差是三阶像差,无法在高斯光学的范围内表达。要列出消除球差的方程式,那只能借助于赛德尔三阶像差理论了。这是初始设计中最难的一点。根据赛德尔像差多项式中的球差部分(推导实在非常繁琐,有兴趣的同学可以查阅相关资料,本系列文章应该不会对它进行推导了),我们可以写出单个薄透镜的球差系数:
\begin{align} S=\;& y^4\frac{1-n}{n}(c_1-c_2)\\ &\left((c_1-c_2)^2n^3s+2(c_1-1/s)^2-\\ (c_1-c_2)n^2(2c_1-3/s)+n(c_1-1/s)(c_2-3/s)\right)\tag{*} \end{align}
这里 c1 和 c2 是薄透镜的两个表面的曲率,s 是物距,y 是光线高度。对于我们这个双胶合镜组来说,由于采用薄透镜假设,两个透镜上的光线高度是一样的,从而可以在最终结果里约去这个高度。而第一个透镜的物位于无穷远,第二个透镜的物就是第一个透镜的像,所以有 s_a=\infty, s_b=f_a ,带入 (*) 式,加以整理,得到(这么长的式子肯定不是我手工推导出来的,mathematica 是个好东西 ←_←):
\begin{align} S_{\text{all}}=\;&-\frac{c_1^3 (n_a-1)}{n_a^2}-\frac{(n_a-1) (c_1(n_a-1)-c_2 n_a)^2 \left(c_1( n_a^2-1)-c_2 n_a^2\right)}{n_a^2} \\[0.7em] &-\frac{(n_b-1) (c_2 f_a (n_b-1)-c_3 f_a n_b+1)^2 \left(c_2 f_a \left(n_b^2-1\right)-c_3 f_a n_b^2+n_b+1\right)}{f_a^3 n_b^2}\\[0.7em] &-\frac{(n_b-1) (c_2 f_a-1)^2 (c_2 f_a-n_b-1)}{f_a^3 n_b^2}\\[0.7em] =\;&0 \tag{5} \end{align}
好了,我们现在写出了所有的方程(方程 (1)-(5) 式)。接下来就是把实际的参数代入求解了。对于普通双胶合镜组,两个透镜的玻璃并不需要特殊选择(反正二级光谱几乎是个常量),我们就用最常见的 BK7 和 F2(这里采用 Schott 玻璃牌号,国内对应的玻璃牌号是 K9 和 F4),这两种玻璃的折射率和阿贝数分别为: n=1.51680,\;V=64.17 以及 n=1.62000,\;V=36.37
联立方程 (1)-(5),把实际参数代入求解,我们得到了两组可行解(虽说手工通过变量代换最后能规化为一个一元二次方程,但是这么复杂的方程我是没耐心求解啦,所以 mathematica 是个好东西)。一组是:
c_1=0.000494801\,\text{mm}^{-1}, \,c_2= -0.00173844\,\text{mm}^{-1}, \,c_3 = -0.000683377\,\text{mm}^{-1} \tag{C-1}
另一组是
c_1=0.00107824\,\text{mm}^{-1},\, c2 = -0.001155\,\text{mm}^{-1}, \, c3= -0.0000999369\,\text{mm}^{-1} \tag{C-2}
这里我在求解的时候,把 BK7 作为第一枚透镜的材料,F2 作为第二枚。但其实并没有特殊的理由一定要这样安排,如果我们用 F2 作为第一枚透镜的材料,BK7 作为第二枚,我们同样可以得到两组可行解:
c_1=0.000876168\,\text{mm}^{-1},\, c2= 0.00193123\,\text{mm}^{-1},\, c3= -0.000302009\,\text{mm}^{-1} \tag{F-1}
c_1=0.00131893\,\text{mm}^{-1},\, c2= 0.00237399\,\text{mm}^{-1},\, c3 =0.000140752\,\text{mm}^{-1} \tag{F-2}
至此,我们得到了四个可行的初始设计。这四个设计都可以在薄透镜近似的条件下满足我们的三个目标。按照冕玻璃在前还是火石玻璃在前,依次记为 C-1,C-2,F-1,F-2
当然,实际透镜都是有厚度的,这与我们的初始设计的假设有点不同。可以想见,如果直接引入厚度,结果将偏离我们预计的三个目标,所以我们需要进一步进行综合优化,对三个表面的曲率进行微调。
引入实际厚度之后的四个初始解,从左上至右下依次为 C-1, C-2, F-1, F-2。深浅颜色代表了玻璃折射率
3. 综合优化
到上面这一步为止,我完全沿着古典主义的路子走:根据高斯光学理论和赛德尔三阶像差理论,计算需要校正的像差,求得合适的解。由于采用了薄透镜近似,极大简化了计算过程(如果有耐心,完全可以手工计算求解,求解过程所需知识不超过中学数学),但也使得最后的结果与实际情况略有偏离。(为什么不一开始就代入厚度计算?这一点留给读者思考)
如果沿着古典主义的路线继续做的话,就该用微扰理论进行优化了。在上一步得到的解,虽然与实际情况有所偏离,但偏差不会很大。在这种情况下,可以把像差理论在这个解的附近进行微扰展开,只取线性部分,求解一个线性方程,就可以得到更符合实际情况的解了。这个过程可以反复迭代进行,在通常情况下迭代一两次就足够精确了。
不过在这里我想带大家走一条更现代的路线。赛德尔像差理论的确是划时代的成果,但也只是对实际像差的某种程度的近似。在今天计算机算力非常充分的情况下,我们没必要使用近似计算,可以直接计算实际像差,并对此进行优化。现代商业光学设计软件已经非常成熟,比如 OSLO、zemax、Code V 等,都具有非常强大的优化功能。通过简单指定一些指标,让软件自动优化,就可以找到最优的系统结构。
对于我们这个例子来说,我还是希望能把优化这块也展开说说,介绍一下那些强大的商业软件背后到底做了什么事情,这也是标题「从零开始」的意义所在了。正好假期有点空闲,于是我花了一些时间,用 MATLAB 写了一个简单版本的光学仿真软件。感兴趣的同学不妨去看看
为了使用计算机进行优化,我们把目标函数写成这样的形式:
f^{\:\text{all}}=\sum_{i}w_i(f_i(c_1,c_2,c_3)-f_i^{\:\text{des}})^2
其中 f_i(c_1,c_2,c_3) 代表根据实际光线追踪得到的某一个指标, f_i^{\:\text{des}} 代表对应指标的目标值,或者说设计值,前面的 w_i 是权重系数,用来调节各个目标值之间的重要程度。这里采用平方和(sum of square)的形式,一方面是保证目标函数非负,最小值就对应最优解;另一方面也使得目标函数是光滑的,利于算法进行优化求解。
这里的重点是如何写出具体的目标函数。一旦目标函数确定了,利用一些数值优化的方法(阻尼牛顿法、拟牛顿法、Nelder–Mead 法、置信域法等),即可对目标函数进行优化。例如 MATLAB 中 fminunc 函数默认采用置信域法,也可以采用拟牛顿法,而 fminsearch 函数默认采用 Nelder-Mead 法。早期的光学设计软件 OSLO 用的也是类似 Nelder-Mead 法的算法。为什么不用近年来在深度学习领域大放光彩的随机梯度法(SGD)呢?这就留给读者思考了。
回到主题。这里计算机的任务就是,调整 c1, c2, c3 的值,使得目标函数最小。在我们的例子里,初始目标是三个:焦距等于 2000mm、消除色差、消除球差。我们看看怎么设计目标函数,把这几个目标合理地融合在一起。
焦距是最简单的目标,根据各个表面的曲率和厚度,反复进行近轴光线计算,很容易得到结果(参见前篇《光学系统像差杂谈(4):近轴光学》),只要把计算得到的焦距,和设计值(2000mm)相减然后平方,就可以加入目标函数了。
色差和球差的情况稍微复杂一些。根据《光学系统像差杂谈(7):跌宕起伏的斑斓路》中的介绍,我们可以使用轴向球差曲线 LSA 来评价轴上物体的球差和色差。理想情况下对于不同波长的光,都应该是与 y 轴重合的一条线,任何的偏离都是球差或者色差的体现。那么我们可以用不同波长的曲线与 y 轴包围的面积(积分)来当做评价指标,加入目标函数。
四个初始系统的轴向球差曲线图,可以看出球差和色差得到了一定程度的校正
但这只针对完全的轴上物体,我们的望远镜还有 1.3° 的视场(0.65° 半视场角)呢,虽然很小,但在综合优化阶段也不可忽视。所以我们还必须把轴外像差纳入考虑。一种做法是,利用光线扇面追踪,得到垂轴像差特性曲线(zemax 等光学设计软件中称为 ray fan plot),利用上面类似的手段,把曲线与坐标轴的偏差,用计算面积(积分)的方法加入目标函数。(目前的篇章中还没有介绍过垂轴像差特性曲线,今后我会慢慢介绍)
四个初始系统的垂轴像差特性曲线(Ray fan plot),可以看出 d 光球差得到了良好的校正,有明显的二级光谱,同时有比较明显的彗差,C-1、F-1 系统带有正的彗差,C-2、F-2 系统带有负的彗差
对轴外像差我们还可以采用另一种手段。在设计阶段我们根据赛德尔像差理论把像差拆分了五大单色像差和色差。但对于实际应用来说,可以不用深究具体是哪一种像差,而直接关心最终的目标:像点的大小。不论哪一种像差,最终都会引起像点变形,变得不再是一个点,而是形成某种形状的弥散图样。既然我们能方便地对真实光线进行追踪,那么我们完全可以直接把成像面上的光斑尺寸作为一个优化目标,加入到目标函数中。这个方法不仅对轴外像差适用,也可以用于轴上像差。这个目标函数非常直观,容易理解,不需要对应的像差知识。
四个初始系统的光斑图,采用了 F/e/d/C 四个波长,画出了 0°、0.38°、0.65° 视场角下的焦平面光斑形状。从这里可以很清晰看出左侧两个系统有正的彗差,右侧两个有负的彗差。光斑图中心的白圈代表艾里斑的大小(衍射极限)。图中同时标示了一些典型的像素尺寸大小。
在设计目标函数的时候切记,我们的双胶合系统本质上只有 3 个有效变量,理论上最多只能达成 3 个方面的目标。我们加入多种不同的目标函数,是希望在不同的目标之间进行权衡。比如在这个系统里我们不可能同时消除球差、彗差、和色差。从上面的光斑图可以很清楚地看到系统带有或正或负的彗差。在综合优化阶段我们可以稍微放松一些对球差的限制,使得彗差略微减小一点,但从根本上我们没办法同时消除两者。光学设计是一种权衡的艺术,这一点需要牢记。
经过优化,我们得到了最终的四个系统。在设计优化函数的时候,我放松了球差的要求,稍稍引入一点球差,同时进行了适当的离焦(defocus)以寻求最佳焦点。最终得到了如下的光斑图
经过优化后四个系统的光斑图
与前面的图进行对比可以看出,彗差有所减小,色差进一步减小。同时由于离焦,使得轴上像差增大,但整个视场内的画质更平衡。
4. 再往前一小步
其实这篇文章写到这里已经完整了,我们得到了四个经过优化的双胶合系统,在我们设计的场景下都可以满足我们的设计需求。不过在最后我想进一步深入一些,看看如果我们再往前走一小步,能得到怎样的结果。
最直观能想到的一个改进就是,把胶合面分开,让双胶合镜组变成双分离的两片式,这样我们就有 4 个表面的曲率作为变量,有了更多的自由度,增加了校正像差的潜力。在这种情况下,我们有希望对彗差也进行校正。
我们可以用上面的优化结果作为初始值,把两片透镜稍稍分开(例如 1~2mm),并且让 4 个表面曲率都作为变量参与优化。结果让人惊喜,上面 C 组的两个系统都收敛于同一个最优解,F 组的两个系统也都收敛于同一个最优解。细想起来也不奇怪,在上面的四个系统中,同一组的两个系统具有相反的彗差,那么容易想到,增加更多变量来消除彗差,将得到一个位于中间的最优解。
从光斑图中可以看到,这个最优解表现优异,完全校正了色差、球差、彗差,留有轻微的像散,整个视场内画质非常均衡。
左侧为 C 组最优解的光斑图,右侧为 F 组最优解的光斑图,两边的性能几乎完全一致,几乎看不到彗差的痕迹,留有轻微的像散,整个视场内画质很平衡。
如果我们把总焦距作为一个单位,那么 C 组的最优解的四个表面半径分别为:
R_1=0.6015,\;R_2=-0.3573,\;R_3=-0.3598,\;R_4=-1.4876
这就是历史上著名的 Fraunhofer 型设计,几乎成为了消色差折射镜的代名词。他能够同时校正色差、球差、彗差,得到很高的成像质量。在近代电子计算机广泛用于光学设计之前,这代表了消色差折射镜的最高成就。当然,F 组的最优解的表现同样优秀,这就是历史上同样著名的 Steinheil 型设计,四个表面半径分别为:
R_1=0.4401,\;R_2=0.2273,\;R_3=0.2268,\;R_4=-14.5265
同样能够校正色差、球差、彗差,发明略晚于 Fraunhofer 型。从专利时间上看,最初发明的动机很可能是避开 Fraunhofer 型的专利,干脆把两片玻璃调换位置,从而得到了新的设计。在实际应用中,消费级望远镜更倾向于采用 Fraunhofer 型设计,因为冕玻璃的物化稳定性更好,作为第一片直接与外界环境接触,冕玻璃更有优势。
Fraunhofer 型与 Steinheil 型的外形
细心的读者朋友应该发现了,不管是 Fraunhofer 型还是 Steinheil 型设计,中间两个表面的曲率半径都几乎一致,仅有千分之一左右的微小差别。对比一下双胶合镜组,要求中间两个表面曲率半径完全一致(这样才能胶合在一起),就是这千分之一的变化,就校正了彗差,极大提升了画质。这不得不令人感慨。世间事多有如此,看似毫厘之差,结果却往往天壤之别。 |
|