简介:CODE V 建立镜头、缩放镜头与像差曲线分析是光学设计从入门到实操的关键环节。这份实例文档面向光学工程初学者与刚上手 CODE V 的工程师,以一个低价位定焦 VGA 数码相机物镜为完整案例,从规格输入讲到起始点选取与结果评估。内容围绕新镜头向导展开:按 F/#、半视场角与元件数在专利镜头库中筛选起点,设定孔径光阑、波长权重与视场,再用一阶近轴属性窗口核对有效焦距是否为 6mm,并通过表面缩放操作完成镜头缩放;随后结合畸变、相对照度、透过率与 MTF 像差曲线判断成像质量,给出优化方向。案例规格涵盖 640×480 解析度、7.4μm 像素、3.55×4.74mm 像面、F/3.5 孔径与 IR 滤光片选型等。包内为 1 个 doc 文档,约 45KB,篇幅紧凑、便于随查随用,已有 1346 人学习,适合作为 CODE V 建模流程与像质评价的对照参考。
1. 拿到「6mm 定焦、F/3.5、640×480」这份规格,先别急着点优化
一个低价位 VGA 数码相机的定焦物镜,规格摊开其实就几行:焦距 6mm、F/3.5 定孔径、对角线 6mm 的传感器、畸变小于 4%、17 lp/mm 处 MTF 过 85%。很多人拿到这种单子,第一反应是随便导一个专利镜头、把焦距缩到 6mm,然后挂上变量让它自己跑,跑完发现 51 lp/mm 那条曲线糊成一片,回头连是哪一步埋的雷都找不到。这个 CODE V 设计实例走的顺序刚好相反:先把规格翻译成半视场角、截止频率、F/# 这几个硬数,再用新镜头向导挑一个像样的起始点,缩放到 6mm,最后用光线像差曲线、点列图、畸变网格和衍射 MTF 给这个起始点做一次完整体检。适合手里装着 CODE V、想把「建立镜头—缩放镜头—看像差曲线」这条链路一次跑通的人,也适合已经会点按钮但说不清每个数从哪来的人。
2. 把规格翻译成输入参数:半视场角 26.5° 和 67.6 lp/mm 是怎么算出来的
规格表是给采购和项目看,CODE V 认的是另一套语言。这一章做的事只有一件:把「640×480、6mm、F/3.5」翻译成可以往对话框里敲的数字。翻译错了,后面缩放到 6mm 也是白缩。
2.1 用 h = f·tanθ 把像面尺寸换成视场角
传感器的有效成像面对角线是 6mm,半对角线就是 3mm。有效焦距定在 6mm,无穷远物距下的近轴关系是 h = f·tanθ,代进去 tanθ = 3/6 = 0.5,解出半视场角 26.5°。这就是后面填进视场设定页的最大视场角,也是过滤器里那个「20~33」区间的由来。
这里有个容易混淆的点:CODE V 里的视场可以按角度定义,也可以按像高定义,两种方式的数值不是一回事。这个案例从专利库起步,专利镜头的像高尺度跟 6mm 焦距对不上,所以统一用角度定义视场更稳——角度在缩放前后不变,像高会跟着焦距一起变。等你缩放到 6mm 再回头看,近轴像高应该落在 2.99~3.0mm,这个数就是半对角线 3mm 的验证。
顺带做个规格自洽性校验,我一般会花十秒算一下:4.74mm 除以 7.4μm 等于 640.5,3.55mm 除以 7.4μm 等于 479.7,跟标称的 640×480 对得上,说明这份规格里的像面尺寸和像素尺寸是一套的,不是抄错的。这一步省不得,规格本身矛盾的情况在真实项目里并不罕见,等到优化不收敛才回头查,成本高得多。
2.2 像素 7.4μm 决定 67.6 lp/mm 的截止频率
CCD 阵列由一个个有限大小的像素构成,设计阶段把它当成单个采样单元看就行。采样能分辨的最高空间频率取像素尺寸倒数的二分之一,也就是 1/(2×0.0074) = 67.6 lp/mm。超过这个频率的细节,传感器本身分辨不出来,光学系统做得再好也送不到后端。
这条结论对设计的约束是:光学 MTF 在 67.6 lp/mm 处不能已经掉到零,否则合成 MTF 在这段频率上完全没有余量。规格里给的 17 lp/mm 和 51 lp/mm 两个采样点,大约就是截止频率的四分之一和四分之三——一个盯大轮廓的对比度,一个盯细节。低频低了一般是渐晕、杂散光或者面型精度的问题,高频低了多半是残余像差没收干净。知道每个采样点归哪类问题,后面看曲线才不会瞎猜。
提示:67.6 lp/mm 是这块传感器的死线,不是设计目标。真正的设计目标要往回退,让 51 lp/mm 处还有 25% 以上的余量,给公差和装配留空间。
2.3 一张能直接填进向导的清单
把上面几步算完,得到的就是下面这张表。我在做类似项目时会把它贴在工程文件旁边,后面每一步操作都对着这张表核。
| 项目 | 数值 | 填在哪 / 怎么验 |
|---|---|---|
| 有效焦距 EFL | 6mm | Edit > Scale,勾 Scale EFL 后填 6.0 |
| 相对孔径 | F/3.5 定孔径 | 孔径光阑页选 Image F/Number,填 3.5 |
| 最大半视场角 | 26.5° | 视场设定页 Y 方向角度 |
| 视场采样 | 0 / 11 / 19 / 26.5 | 视场设定页,中间补两档 |
| 波长与权重 | 可见光波段,589nm 权重 2 | 波长设定页 |
| 元件数 | 1~3 片 | 专利过滤器 Element Number |
| 几何畸变 | < 4% | 畸变网格,X 21.55° / Y 16.48° |
| 中心 MTF | 17 lp/mm > 85%,51 lp/mm > 25% | 衍射 MTF,上限 68、步进 17 |
| 角落相对照度 | > 60% | 相对照度分析(渐晕) |
| 透过率 | 400~700nm 单镜片 > 80% | 透过率分析 |
| 物距范围 | 0.75m ~ 无穷远 | 离焦 MTF 或按物距扫 MTF |
| IR 滤光片 | 1mm 厚红外截止片 | 建模时作为平行平板加入 |
表里最后两行是这个案例里最容易被跳过的:物距从 0.75m 到无穷远,意味着焦深必须够,靠单一的 MTF 曲线看不出这件事;IR 滤光片是块 1mm 厚的平板,它会引入球差和轴向位移,建模时漏掉,仿真结果和实物就是两回事。
3. 建立起始点并缩放到 6mm:向导、LDM 与 Scale 的完整动作
从零手搓一个三片式物镜是熟练工的活,从专利库挑一个接近的再改,是大多数人的路子。这一章把「挑—建—读表—缩放—复核」串成一条线,每一步都落一个可核对的数。
3.1 专利库过滤器:范围一定要放宽
走 File > New,在欢迎页点 Next,选 Patent Lens。这个库里有一批年代久远的轴对称专利镜头,用新镜头向导或者独立的专利搜索都能访问,关键在过滤器怎么填。目标是 F/3.5、半视场 26.5°、元件数越少越好,但填条件时我一般会松一档:F/# 填 1~4,半视场填 20~33,元件数填 1~3。
放宽的理由很实在——视场角从大变小的路好走,从小变大的路很难走。想扩大视场,往往要加元件、加非球面或者换玻璃,等于重做;而把大视场镜头的边缘裁掉一点,或者把相对孔径收小,代价小得多。同理,起始点的 F/# 比目标更小(更快)是好事,收光圈通常让像质变好,反过来就难。
按这组条件筛下来剩十几个候选。列表里那个半视场 27.5°、F/2.4 的镜头是比较有潜力的一类:视场比我们要的略大,光圈比 F/3.5 快接近一档,两样都有往下调的余地。选中它,点 Next 进下一步。
3.2 三个页面的填法:孔径、波长、视场
孔径光阑页。下拉列表里选 Image F/Number,填 3.5。为什么不填入瞳直径,这里有个关键区别:F/# 是个比值,镜头缩放时它不变;入瞳直径是绝对长度,缩放时会跟着一起放大。你要是填了 EPD,缩放到 6mm 焦距之后 F/# 就跑到别处去了,得重新算一遍光圈,纯粹给自己添麻烦。
波长设定页。把 589.0nm 那一行的权重改成 2,其余可见光权重留 1。权重只在优化里参与误差函数的加权,对单次光线追迹没有影响——也就是说,改权重不会让当前镜头变好或变坏,它只决定后面优化时谁说了算。把主波长权重抬高,是因为可见光中心波段的成像质量对这个应用最关键,色差也主要靠它压。
参考波长页。默认值别动。这个波长用来做近轴计算和参考光线追迹,是整套一阶数据的基准,改了它,后面 First Order Data 里的数就跟你以为的不是一回事。
视场设定页。选中第二视场,右键菜单 INSERT 插入新行,把 Y 方向角度依次填成 0、11、19、26.5。四档视场里,0 是轴上,26.5 是最大视场,中间补 11 和 19 两档。常规做法至少要有 0、0.7 倍和全视场三档,这里额外加一档中间值,是为了控制像散这类与视场强相关的带状像差——只给三档采样,像散在中间视场鼓起来的那个包很容易被漏掉,等到看场曲曲线才发现,就得回头重建评价函数。
填完点 Next 走到最后一页,点 Done,模型正式进 LDM 表格。
3.3 LDM 表格怎么读:灰色格子、STOP 和带 S 的求解
CODE V 里绝大部分操作的本质都是光线追迹,而光线追迹靠的就是这张镜头数据管理表。表里一行是一个表面,从物面开始到像面结束,中间必然有一行被标了 STOP,那就是孔径光阑,限制轴上光束的那一面。只要没启用主光线对准,任何视场的主光线都会穿过光阑中心。
几个字段值得单独说:
- Y Radius:曲率半径,是曲率的倒数。旋转对称面只有一个曲率,用 Y 方向表示。Edit > Use Radius Mode 勾不勾,决定你输入的是半径还是曲率,输错这一项后面全乱。
- 厚度:定义到下一表面的距离,沿当前表面 Z 轴测量。注意某个面的厚度是灰的、旁边还带个小 S,那是 Paraxial Image solve——程序自动调这个厚度,让近轴边缘光线在下一面的高度为 0。它定的是近轴像位置,不是最佳焦点。真正的像面位置是这一面厚度加上像面那一面的厚度,通常的做法是把 PIM 求解和像面偏移(离焦变量)配合用,前者定基准,后者在优化里找最佳焦。
- Glass:空白代表空气。填的名字可以是实际玻璃牌号,也可以是虚拟玻璃——虚拟玻璃的折射率和阿贝数都能设成变量参与优化,后面再用宏把它拟合回可采购的实际牌号。这个案例里先用虚拟玻璃把形状做出来,是常见做法。
- Y Semi-Aperture:默认由程序按所有视场、所有变焦位置的参考光线算出通光口径。起始阶段接受默认值就行,等做相对照度分析时再回头调。
还有一个提交机制上的坑,值得提前知道:带 OK / Cancel 的对话框,不点 OK 就什么都不提交,点了 Cancel 就是彻底没改;而表面属性窗口和系统数据窗口没有 OK,改动是即时提交的。所以你在表面属性里调完一堆参数,随手点了个 Cancel 想放弃,其实早就生效了。想确认到底提交了什么,看命令窗口里滚出来的命令。
3.4 Scale 对话框:从 0.9528mm 缩到 6.0mm
先看一阶数据。Display > List Lens Data > First Order Data,输出的窗口里 EFL 大概率是 0.9528mm 这种量级——专利镜头是按它自己的尺度存档的,不是错,是没缩放到你的应用。
缩放的动作是六步:
- 在 LDM 里点表面 1 的编号,按住拖到像面那一行,选中 1 至像面的全部表面;
- Edit > Scale 打开对话框,确认范围显示的是 1 到 Image;
- 勾选 Scale Effective Focal Length;
- Scale Value 里填 6.0;
- 点 OK;
- 回到 First Order Data 窗口点重算。
缩放是等比例操作,所有半径、厚度、半孔径一次性乘以 6/0.9528 ≈ 6.297。缩完 EFL 应该是 6.0mm,近轴像高 2.99mm 左右,跟期望的 3.0mm 差一点点属于正常。顺手 File > Save Lens As,存成 DigCamStart.len——这个文件是后面所有优化的基线,命名带版本号,我在类似项目里吃过没存基线的亏。
| 复核项 | 期望值 | 对不上先查哪 |
|---|---|---|
| 有效焦距 EFL | 6.0mm | 缩放时是否包含像面,是否真的勾了 Scale EFL |
| 近轴像高 | 2.99~3.0mm | 视场设定是否为 26.5°,波长是否为参考波长 |
| 相对孔径 | 仍为 F/3.5 | 孔径类型是不是 Image F/Number;填了 EPD 的话这里一定跑偏 |
| 元件口径与厚度 | 不出现过小、过薄片 | 缩放比例是否正确,原专利镜头本身是否太紧凑 |
| 总长 | 与焦距量级匹配 | 有无异常厚度或负厚度 |
最后一行不是走形式。缩放到 6mm 之后,某个镜片的中心厚度可能只剩零点几毫米,口径也小到难以夹持——这种设计在软件里跑得通,在车间里做不出来。判断标准要靠经验或者找做过类似系统的人确认:太小、太薄、太弯的片子,加工和装配成本都会往上跳。这一步花十分钟,能省掉后面一轮返工。
4. 像差曲线和 MTF:给起始方案做一次体检报告
缩放完成只是把尺度调对了,跟规格还差多远完全不知道。这一章的分析动作,目的不是把像质做好,而是搞清楚「现在差在哪、往哪个方向优化」。
4.1 光线像差曲线:0.023mm 的自动比例在骗你
Analysis > Diagnostics > Ray Aberration Curve,选项名 RIM。横轴是瞳坐标,纵轴是横向光线像差——同一视场点发出的某条光线,与参考光线在像面上的交点距离;理想透镜这条曲线应该贴着横轴。
第一眼看的不是曲线形状,是比例。工具自动定的纵向比例是 0.023mm,也就是 23μm。拿它跟艾利斑比一下:艾利斑直径约 2.44·λ·F/#,取 λ = 0.5μm、F/# = 3.5,算出来大约 4.3μm,按原文的记法约 0.004mm。23μm 差不多是艾利斑的六倍,说明这个起始方案的像差远没到衍射极限,同时也说明曲线看上去「还行」很大程度上是因为比例被压扁了。
判读的顺序是:先看横向——哪个视场的曲线张得最开;再看纵向——不同波长是不是分开成几束,分开了就是色差;最后看形状,中间交叉、两端翘起这类特征对应球差,一头大一头小是彗差,两个视场的最佳焦点位置不一致就是场曲加像散。这些判断不需要精确计算,看一眼就知道该往哪个方向加东西:色差大就换玻璃或者加一片,单色像差大就考虑非球面。
注意:快速像差曲线是宏实现的,比例自动适配。任何时候拿两张图做对比,先确认比例尺是不是同一个,否则比较出来的结论全是错的。
4.2 点列图与畸变网格:先看比例条,再看形状
Analysis > Geometrical > Spot Diagram(SPOT)给出的是每个视场一簇光线在像面上的散布。这个镜头跑出来的结果是各视场点的大小大致相近、形状不同——大小相近说明各视场的像差量级差不多,形状不同说明主导像差类型随视场在变。比例条显示 0.050mm,也就是 50μm,跟艾利斑再比一次,同样是一个量级偏大的结果。
有个现成的宏很好用,spotdet.seq,可以在点列图上叠一个方块或圆圈,代表像元尺寸或艾利斑,一眼就能看出光斑是铺满一个像素还是一小坨。位置的调用方式是在宏菜单的示例宏里找几何分析那组。
场曲和畸变一起看:Analysis > Diagnostics > Field Curves,纵轴视场、横轴畸变百分比,这一项在规格里限的是 4% 以内。这个起始方案跑下来全视场畸变小于 ±1%,中间视场有一小段残留的带状起伏,属于可以接受但值得盯一眼的量级。
想看更直观的,用 Analysis > Diagnostics > Distortion Grid。这里必须先把传感器的物理尺寸换算成视场角:这块阵列是 4.74mm × 3.55mm(横向长边对应 X),半宽 2.37mm 和 1.775mm 分别除以 6mm 再取反正切,得到 X 半视场 21.55°、Y 半视场 16.48°。在对话框里把这两个数填进去,参考网格选 Fiducial Marks Only,执行。因为畸变本来就小于 1%,网格上的偏移很小,得放大局部才看得清——这种「看不出问题」本身就是好消息,但也意味着靠肉眼判断会漏,还是以曲线上的百分比为准。
4.3 衍射 MTF:68 lp/mm 上限、17 的步进怎么填
Analysis > Diffraction > MTF,工具栏上那个快速 MTF 按钮不支持指定频率,要看细节得走完整对话框。在 Frequency / Calculation 选项卡里,Maximum frequency 填 68,Increment 填 17,这样算出来正好落在 17、34、51、68 四个频率点,前两个之后正好覆盖规格里的 17 lp/mm 和 51 lp/mm。
填完之后,选项卡标题旁边会冒出一个红色星号,那是改动指示器,提醒这个页里参数改过、还没重新执行。这个小标记别忽略,我见过有人改完频率直接看旧图,对着上一版数据下了半天结论。
曲线出来怎么读:横轴空间频率,纵轴 MTF,1.0 是完全的黑白对比,0 是彻底糊平。规格要求 17 lp/mm 处中心视场高于 85%、51 lp/mm 处中心高于 25%。起始方案在这两个点大概率都不达标,这是正常的——起始点的作用是提供一个形状合理、可以优化的工作模型,不是直接交货。真正要看的是曲线的走向:如果高频段掉得特别快,说明残余像差没收;如果低频段一开始就低,那多半是渐晕或者孔径设置有问题,得回头查 LDM 里的半孔径和渐晕因子。
同一批体检里还有两件事不能漏。一是相对照度,规格要求角落照度高于 60%,这一项由渐晕和孔径共同决定,MTF 达标但角落暗一截的设计在相机上是不能用的。二是透过率,400~700nm 波段单镜片要求 80% 以上,镀膜方案和玻璃吸收都要算进去,加上那块 1mm 厚的红外截止片,实际到传感器的能量还得再打折。这三项一起过了,才谈得上「起始方案可用」。
5. 避坑排查:这五处翻车最费时间
这些坑大多不是软件不会用,而是操作顺序和默认行为上栽的。每一条我都按「现象—原因—解决」写,对着查就行。
第一条:缩放完发现 F/# 跟着变了。现象是缩放到 6mm 之后,一阶数据里 F/# 不再是 3.5,而是个奇怪的数,重新设回去之后像质分析又全变了。原因几乎都是孔径类型填成了入瞳直径(EPD)——EPD 是绝对长度,等比例缩放时跟着放大 6.3 倍,而 F/# 是比值,概念上不该变。解决方式是把孔径光阑页的类型改成 Image F/Number 再重填 3.5;如果镜头已经缩过了,改完孔径后记得重新看一眼近轴像高,确认没有连带改动。
第二条:灰色厚度单元格里输入不进去,改完又弹回去。现象是某个面的厚度是灰的、旁边带 S,双击改数字没反应,或者改完过一会儿又回到原值。原因是这个厚度上挂着 Paraxial Image solve,程序在算「让近轴边缘光线在下一面高度为 0」的那个值,你手动填的数会被求解覆盖。解决是右键该单元格,先取消求解状态,再改成变量或固定值。但取消之前想清楚:这个求解放在那儿是有原因的,它定了近轴像面位置,取消掉之后像面会飘,所有 MTF 结果都不可比。常规做法是保留 PIM,另加像面偏移作为离焦变量,两者配合用。
第三条:畸变网格怎么画都对不上传感器的边。现象是网格填了视场角,画出来发现边缘视场和实际像面范围不一致,或者横竖方向搞反了。原因是视场定义用的是角度,而传感器给的是毫米,中间必须过一遍 h = f·tanθ 的换算,而且 X 和 Y 要分别算:4.74mm 那条长边对应 21.55°,3.55mm 那条短边对应 16.48°。解决是把这两个数各自填进对应的半视场格子里,别拿一个数凑两个方向;换传感器的话,这两个数必须重算,不能沿用。
第四条:MTF 达标了,角落却暗得没法用。现象是中心视场 17 lp/mm 过得挺轻松,一出相对照度分析,角落只有 40% 出头,离规格的 60% 差一截。原因是把注意力全放在 MTF 上,忽略了 Y 半孔径是程序自动算的,而自动口径不考虑你想要的渐晕水平。解决是先跑一遍相对照度分析定位是哪个面在拦光,再回头手动设定关键面的通光孔径或加渐晕因子。这里要提醒的是,渐晕和 MTF 是互相拉扯的:放宽口径照度上来、像差跟着上来,收紧口径像质好、角落变暗,优化时两个指标要放在一起看,不能分两轮各调各的。
第五条:改崩了想回退,发现 Undo 是灰的。现象是调了一堆参数,想按 Undo 退回去,菜单项点不动。原因是 Undo 只在数据表或命令窗口处于当前状态时可用,图形窗口或对话框窗口一激活,这个功能就失效了。这个设计很容易理解——图形窗口有自己的缩放历史,跟数据修改不是一条线。解决是养成节点保存的习惯:每完成一个有意义的状态(缩放完、视场改完、优化跑完一轮)就 File > Save Lens As 存一份带版本号的文件。这是唯一可靠的后悔药,Undo 顶多救你一两步。
6. 进阶验证:用离焦 MTF 把「0.75m 到无穷远」这件事验掉
前面所有分析都是在无穷远物距、单一像面上做的,而这份规格里写着物距从 0.75m 到无穷远都要能用。这一条如果只用单张 MTF 曲线验证,等于没验。我在类似项目里的做法是把离焦 MTF 当成交付前的必过关卡:在 MTF 对话框里把物距或像面偏移设成一组扫描值,看 17 lp/mm 那条曲线随离焦衰减的宽度,宽度就是这个系统实际可用的焦深。衰减太快,说明焦深不够,0.75m 处已经糊了;衰减平缓但整体水平低,那是像差限制不是焦深限制,得回去优化而不是调焦。
具体操作上有两个参数要拿捏。一是扫描步长,别一上来就铺满整个范围,先用粗步长(比如 0.02mm 像面偏移)看趋势,找到 MTF 掉到规格线附近的区间,再在这个区间里用细步长加密。二是判据频率,看 51 lp/mm 还是 17 lp/mm 得出的焦深结论可能差一倍,工程上一般用规格里那个较高的采样频率当判据,因为低频在离焦下太耐打了,用它算出来的焦深会虚高。
验证阶段还有三件事值得一起做。其一,把红外截止片作为 1mm 平行平板加进模型后重跑一遍 MTF,平板引入的球差和焦点位移在 F/3.5 这种相对孔径下不算小,漏掉它,仿真和实拍的差距会集中在高频段。其二,跑一遍透过率分析,确认 400~700nm 波段单镜片透过率在 80% 以上,镀膜方案定下来之后再用实际膜系数据替换。其三,如果这个设计要往下走,公差分析应该在优化收敛之后、而不是之前做,因为像差本身很大的系统,公差分析给出的结果会好看得没有意义——像差把公差的影响盖住了。
有件事我印象很深:早些年做一个类似的小视场物镜,前面几步都规规矩矩,唯独缩放的时候图省事只选了中间几片,没把像面框进去,结果 EFL 是对的、F/# 也是对的,只有近轴像高差了 0.3mm,怎么优化畸变都压不下去。查了大半天才回到 Scale 对话框看范围那一行。从那以后我每次做 Scale 都强制走一遍「拖全选—看范围—勾 EFL—填数—重算一阶」这五步,一步不省,而且缩完立刻存一个基线文件。这套动作看着笨,但它把最容易出错的一环变成了不会出错的一环。希望帮到你。
本文还有配套的精品资源,点击获取