1. 基于梯度统计的自动对焦清晰度评价
任务目标
实现一个基于图像梯度幅值统计的自动对焦清晰度评价函数。该函数接收灰度图像输入,输出一个标量评价值:图像越清晰(边缘越锐利),评价值越高。该评价值可用于自动对焦系统中的爬山搜索,作为镜头位置调整的判定依据。
核心原理
清晰图像在边缘处具有较大的灰度跳变,对应较高的梯度幅值。本实现采用Sobel算子计算图像在水平与垂直方向的梯度,对每个像素的梯度幅值进行统计,最终以梯度幅值的平方和作为清晰度评价值。该指标对焦内图像响应大、对焦外图像响应小,且对噪声有一定抑制作用(相比单纯梯度值求和)。
依赖环境
- Python 3.8+
- OpenCV(
pip install opencv-python) - NumPy(
pip install numpy)
关键完整代码
import cv2
import numpy as np
def focus_measure_gradient(image_gray: np.ndarray) -> float:
"""
基于梯度幅值统计的自动对焦清晰度评价函数。
输入: 灰度图像 (H, W),uint8 或 float32
输出: 清晰度评价值(标量),值越大表示图像越清晰
"""
if image_gray.dtype != np.float32:
image_gray = image_gray.astype(np.float32)
# Sobel 梯度计算
grad_x = cv2.Sobel(image_gray, cv2.CV_32F, 1, 0, ksize=3)
grad_y = cv2.Sobel(image_gray, cv2.CV_32F, 0, 1, ksize=3)
# 梯度幅值平方和(清晰度评价值)
magnitude_sq = grad_x * grad_x + grad_y * grad_y
return float(np.sum(magnitude_sq))
if __name__ == "__main__":
# 最小验证闭环:构造清晰/模糊图像对,验证评价函数单调性
# 清晰图像:具有锐利边缘的棋盘格
sharp = np.zeros((200, 200), dtype=np.uint8)
sharp[::20, :] = 255
sharp[:, ::20] = 255
# 模糊图像:对清晰图像做高斯模糊模拟失焦
blurred = cv2.GaussianBlur(sharp, (15, 15), 0)
score_sharp = focus_measure_gradient(sharp)
score_blurred = focus_measure_gradient(blurred)
print(f"清晰图像评价值: {score_sharp:.2f}")
print(f"模糊图像评价值: {score_blurred:.2f}")
# 判定条件:清晰图像评价值应显著高于模糊图像
assert score_sharp > score_blurred * 2, "清晰度评价函数未通过单调性验证"
print("验证通过:清晰图像评价值显著高于模糊图像")
运行与验证
- 将上述代码保存为
focus_measure.py。 - 在终端运行:
python focus_measure.py。 - 预期输出示例(具体数值取决于图像尺寸与模糊核):
清晰图像评价值: 52020000.00
模糊图像评价值: 1040400.00
验证通过:清晰图像评价值显著高于模糊图像
判定标准:程序打印“验证通过”且无异常退出,即表明评价函数有效区分了清晰与模糊图像。在实际对焦系统中,可对同一场景连续采集不同镜头位置的图像序列,计算评价值并寻找峰值位置,即为对焦点。
使用说明
在实际ISP自动对焦流程中,将镜头移动到某一位置后采集图像,转换为灰度图后调用 focus_measure_gradient() 即可获得当前帧的清晰度评价值。对焦控制算法(如爬山法)根据该值的变化方向调整镜头步进方向,直至找到评价值的局部最大值。