2. 对焦评价函数:常见的反差评价函数及其数学表达

在反差式自动对焦(Contrast Detection Auto Focus, CDAF)系统中,对焦评价函数(Focus Measure Function)是衡量图像清晰度的核心算子。其本质是对图像高频分量(边缘、纹理)的能量进行量化:对焦越准确,边缘越锐利,高频能量越高;离焦越严重,图像越模糊,高频能量越低。

本章将详细解析三种最经典的灰度域反差评价函数:Tenengrad、Laplacian 和 Brenner,并给出其离散数学表达与工程实现要点。

2.1 评价函数的设计原则

一个实用的对焦评价函数应满足以下条件:

  • 单峰性:在最佳对焦位置附近呈现唯一的全局最大值。
  • 无偏性:峰值位置与真实对焦面一致,不因场景纹理分布产生偏移。
  • 灵敏度:在峰值附近斜率足够大,能够区分微小离焦量。
  • 抗噪性:对传感器噪声、光照变化具有一定的鲁棒性。
  • 计算效率:适合在 ISP 流水线中实时处理,通常只使用整型运算。
工程提示: 实际 ISP 中很少单独使用一种评价函数,而是将多种算子加权融合,或在不同对焦阶段切换不同的评价策略(粗搜索用 Brenner,精搜索用 Tenengrad)。

2.2 Tenengrad 算子

Tenengrad 算子基于 Sobel 梯度算子,分别计算图像在水平方向(x)和垂直方向(y)的一阶梯度,然后取梯度幅值的平方和(或绝对值之和)作为清晰度度量。

数学表达

对于像素点 \((x, y)\),其灰度值为 \(I(x, y)\),Tenengrad 评价函数定义为:

F_Tenengrad = Σ_x Σ_y [ G_x(x,y)² + G_y(x,y)² ]

其中 \(G_x\) 和 \(G_y\) 分别为 Sobel 算子在 x 和 y 方向的卷积结果:

G_x = I * S_x ,   S_x = [[-1, 0, +1],
                        [-2, 0, +2],
                        [-1, 0, +1]]

G_y = I * S_y ,   S_y = [[-1, -2, -1],
                        [ 0,  0,  0],
                        [+1, +2, +1]]

实际工程中常使用绝对值近似以降低计算量:

F_Tenengrad_abs = Σ_x Σ_y ( |G_x| + |G_y| )

特点

属性 说明
方向敏感性 各向同性较好,对水平和垂直边缘均有响应
噪声敏感度 中等;Sobel 核本身有平滑作用,但梯度平方会放大噪声
峰值锐度 高;在焦点附近曲线陡峭,适合精对焦
计算开销 较高(2 次 3×3 卷积 + 平方运算)
ISP 实现要点: 在硬件 ISP 中,Sobel 卷积通常使用 Line Buffer 实现 3 行流水线,梯度平方运算可查 LUT 表加速。
Tenengrad 算子计算流程 输入图像 I Sobel X 卷积 Sobel Y 卷积 Gx² Gy² Σ(Gx²+Gy²)

2.3 Laplacian 算子

Laplacian 算子是一种二阶微分算子,它直接计算图像灰度值的二阶空间导数。对于理想边缘,二阶导数在边缘处会产生过零点,而 Laplacian 响应的绝对值可以反映边缘强度。

数学表达

离散 Laplacian 算子定义为:

∇²I = ∂²I/∂x² + ∂²I/∂y²

常用的 3×3 离散卷积核为:

L = [[ 0, -1,  0],
     [-1,  4, -1],
     [ 0, -1,  0]]

评价函数取所有像素点 Laplacian 响应的绝对值之和(或平方和):

F_Laplacian = Σ_x Σ_y |∇²I(x,y)|

变体:Laplacian of Gaussian (LoG)

为抑制噪声,可先对图像做高斯平滑,再计算 Laplacian,即 LoG 算子。工程中常用 DoG(Difference of Gaussian)近似 LoG 以提高计算效率。

属性 说明
方向敏感性 各向同性(旋转不变性)
噪声敏感度 高;二阶微分对噪声极为敏感,需配合降噪使用
峰值锐度 极高;但易出现多峰(伪峰)
计算开销 低(单次 3×3 卷积)
避坑指南: Laplacian 算子对孤立噪点响应强烈,在低照度场景下直接使用可能导致对焦曲线剧烈抖动。建议先做 3×3 均值滤波或高斯滤波预处理。
Laplacian 与 LoG 算子对比 输入图像 I Laplacian 卷积 |∇²I| 累加 输入图像 I 高斯平滑 Laplacian 卷积 |LoG| 累加

2.4 Brenner 算子

Brenner 算子是最简单的一阶差分评价函数之一,它只计算水平方向上相隔两个像素的灰度差值的平方和。因其计算量极小,在早期数码相机和低功耗 ISP 中广泛使用。

数学表达

F_Brenner = Σ_x Σ_y [ I(x+2, y) - I(x, y) ]²

也可以加入垂直方向分量以增强各向同性:

F_Brenner_2D = Σ_x Σ_y { [I(x+2,y)-I(x,y)]² + [I(x,y+2)-I(x,y)]² }

特点

属性 说明
方向敏感性 强;基本版本仅响应水平边缘
噪声敏感度 低;差分步长为 2 相当于做了简单的低通滤波
峰值锐度 中等;曲线较平缓,适合粗对焦
计算开销 极低(仅减法和乘法,无卷积)
工程经验: Brenner 算子常作为粗搜索阶段的评价函数,配合大步长快速扫描对焦范围。当曲线进入上升区域后,再切换为 Tenengrad 或 Laplacian 进行精搜索。

2.5 三种算子对比总结

算子 阶数 计算量 抗噪性 峰值锐度 适用阶段
Brenner 一阶 极低 高 低 粗搜索
Tenengrad 一阶 中 中 高 精搜索
Laplacian 二阶 低 低 极高 精搜索(需降噪)
三种评价函数对焦曲线对比(示意) 镜头位置(步数) 评价函数值 Brenner Tenengrad Laplacian 最佳对焦位置

2.6 工程实现示例(Python)

以下代码展示了三种评价函数的 NumPy 实现,可直接用于 ISP 原型验证:

import numpy as np
import cv2

def brenner_focus_measure(image: np.ndarray) -> float:
    """Brenner 评价函数(水平方向,步长2)"""
    if image.ndim == 3:
        image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
    diff = image[:, 2:] - image[:, :-2]
    return float(np.sum(diff ** 2))

def tenengrad_focus_measure(image: np.ndarray) -> float:
    """Tenengrad 评价函数(Sobel梯度平方和)"""
    if image.ndim == 3:
        image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
    gx = cv2.Sobel(image, cv2.CV_64F, 1, 0, ksize=3)
    gy = cv2.Sobel(image, cv2.CV_64F, 0, 1, ksize=3)
    return float(np.sum(gx ** 2 + gy ** 2))

def laplacian_focus_measure(image: np.ndarray) -> float:
    """Laplacian 评价函数(绝对值累加)"""
    if image.ndim == 3:
        image = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
    lap = cv2.Laplacian(image, cv2.CV_64F, ksize=3)
    return float(np.sum(np.abs(lap)))
性能提示: 在嵌入式 ISP 中,上述运算通常使用定点数(Q8.8 格式)实现,避免浮点运算。Brenner 的平方运算可替换为绝对值以进一步降低功耗。

2.7 本章小结

  • Brenner:计算量最小,抗噪性最好,适合粗搜索阶段的大步长扫描。
  • Tenengrad:各向同性好,峰值锐利,是精搜索阶段的首选。
  • Laplacian:二阶微分灵敏度最高,但噪声放大效应明显,需配合预处理使用。
  • 实际 ISP 系统通常采用多阶段评价策略,在不同对焦阶段切换不同的评价函数,以平衡速度与精度。