4. 相位对焦(PDAF):片上相位检测像素、左右相位差计算、散焦量映射
相位对焦,圈里人常叫它PDAF。这玩意儿在单反上已经用了很多年,后来被搬到手机摄像头里。说白了,它比反差对焦快得多,不来回“拉风箱”,直接告诉你镜头该往哪转、转多少。
我最早接触PDAF是在做一款旗舰机摄像头调试的时候。当时客户要求对焦速度必须控制在200ms以内,反差对焦死活做不到,最后全靠PDAF救场。嗯,咱们今天就把它拆开看看。
4.1 片上相位检测像素
传统CMOS传感器每个像素就是一个光电二极管,只管收集光子。但PDAF传感器不一样,它在像素阵列里“藏”了一些特殊的像素对——相位检测像素。
每个相位检测像素其实只“看”到一半的光线。怎么做到的?
- 左半遮挡像素:微透镜下面只露出光电二极管的左半边,右半边被金属遮光层挡住。
- 右半遮挡像素:反过来,只露出右半边,左半边被挡住。
这两个像素挨在一起,组成一个“相位检测对”。左像素只接收从镜头左侧进入的光线,右像素只接收从右侧进入的光线。你想想看,这不就相当于在传感器上造了两个“小眼睛”吗?
关键点:相位检测像素牺牲了部分感光面积,所以它们比普通像素暗一些。后期ISP需要做增益补偿,否则图像上会出现“网格状”的亮度不均。
我在项目中遇到过一个问题:某款传感器的相位像素排布太密,导致预览画面有明显的“棋盘格”噪声。后来调整了补偿算法,才把这个问题压下去。
4.2 左右相位差计算
有了左右像素的信号,接下来就是算差值。这个计算过程其实不复杂,但细节挺多。
基本流程是这样的:
- 提取左右信号:从传感器原始数据中,把左半遮挡像素和右半遮挡像素的值分别提取出来,形成两个一维信号序列。
- 计算相关曲线:把左信号作为参考,右信号在水平方向上逐像素平移,每平移一次计算一次匹配度(通常用SAD或SSD)。
- 找到最佳匹配:相关曲线的最低点(SAD最小)对应的平移量,就是左右信号的相位差。
这里有个细节——亚像素精度。整像素级别的相位差精度不够,镜头对焦会来回抖动。我习惯用抛物线插值法,在最佳匹配点附近取三个点,拟合一条抛物线,顶点位置就是亚像素级别的相位差。
// 亚像素插值示例(C语言风格伪代码)
float phase_delta_subpixel(int16_t *corr, int best_idx) {
int16_t c0 = corr[best_idx - 1];
int16_t c1 = corr[best_idx];
int16_t c2 = corr[best_idx + 1];
float denom = 2.0f * (c0 - 2.0f * c1 + c2);
if (fabs(denom) < 1e-6f) return (float)best_idx;
float subpixel_offset = (c0 - c2) / denom;
return (float)best_idx + subpixel_offset;
}
避坑指南:我曾经在低照度场景下发现相位差计算抖动很大。原因是左右信号的信噪比太低。后来加了时域滤波——把连续几帧的相位差做加权平均,效果立竿见影。
4.3 散焦量映射
相位差算出来了,但它是一个像素偏移量,单位是“像素”。镜头马达需要知道的是“镜头该转多少步”,单位是“μm”或“步数”。这就需要一个映射关系。
映射公式其实是个线性模型:
defocus_amount = phase_delta * conversion_gain + offset
其中:
- phase_delta:上一步算出的相位差(亚像素精度)
- conversion_gain:转换增益,单位是“μm/像素”
- offset:零位偏移,用于校准
这个转换增益怎么来的?标定出来的。我一般在产线上拍一组不同物距的图卡,记录每个物距下的相位差,然后拟合出线性关系。
| 物距 (cm) | 相位差 (像素) | 镜头位置 (μm) | 转换增益 (μm/像素) |
|---|---|---|---|
| 10 | +12.3 | 150 | 12.2 |
| 20 | +6.1 | 75 | 12.3 |
| 50 | +2.0 | 25 | 12.5 |
| 100 | 0.0 | 0 | — |
你看,转换增益基本稳定在12.2~12.5之间。实际项目中我会取平均值,再根据温度做一次补偿——温度变化会影响微透镜的折射率,导致增益漂移。
注意:散焦量映射不是一成不变的。镜头模组有公差,每个模组的转换增益都不一样。量产时必须逐台标定,否则会出现“这台对焦快,那台对焦慢”的尴尬情况。
最后一步,把散焦量发给马达驱动。如果是VCM马达,直接换算成电流值;如果是步进马达,换算成步数。镜头就“嗖”一下推到目标位置,对焦完成。
整个PDAF流程,从像素读出到马达驱动,必须在单帧时间内完成——通常是16ms到33ms。我做过一个优化:把相位差计算和散焦量映射放在ISP的垂直消隐区里跑,不额外占用帧时间。嗯,效果很好。
这张图把PDAF的五个核心环节串起来了。从传感器上的相位检测像素开始,到最终马达推动镜头到位,每一步都有它的物理意义和算法细节。你想想看,整个对焦过程在几十毫秒内完成,背后是光学、半导体、信号处理、控制理论的协同工作。
我个人觉得,PDAF最妙的地方在于它把“对焦”这个看似模糊的问题,转化成了一个精确的数学计算。只要相位差算得准,散焦量映射标定得稳,对焦就是一次到位,不需要反复试探。