畸变校正的定义与常用算法
畸变校正是一种用于消除图像或视频中因镜头光学特性或传感器排列问题而产生的几何失真的技术。在计算机视觉和摄影领域,畸变校正对于提高图像质量、精确测量以及后续分析(如目标检测、三维重建)至关重要。常见的畸变类型包括径向畸变(桶形或枕形失真)和切向畸变(由于镜头与图像平面不平行导致)。
常用的畸变校正算法包括:
- 张正友标定法:通过多幅不同角度的棋盘格图像估计相机内参和畸变系数。
- 直接线性变换(DLT):基于共线方程的线性解法,适用于已知控制点的情况。
- 多项式模型:使用多项式函数(如Brown-Conrady模型)描述径向和切向畸变。
- 基于物理模型的方法:考虑镜头光学特性的物理模型,如鱼眼镜头的统一投影模型。
传统畸变校正算法的Python实现
下面是基于OpenCV库实现的张正友标定法和多项式模型畸变校正:
import numpy as np
import cv2
import glob
import matplotlib.pyplot as plt
# 1. 张正友标定法实现
def camera_calibration(images_path, pattern_size=(9, 6)):
"""
使用张正友标定法计算相机内参和畸变系数
参数:
images_path: 包含标定板图像的路径模式,如'./calibration_images/*.jpg'
pattern_size: 标定板内角点的行数和列数
返回:
camera_matrix: 相机内参矩阵
dist_coeffs: 畸变系数
rvecs: 旋转向量
tvecs: 平移向量
"""
# 准备对象点,如 (0,0,0), (1,0,0), (2,0,0) ..., (8,5,0)
objp = np.zeros((pattern_size[0] * pattern_size[1], 3), np.float32)
objp[:, :2] = np.mgrid[0:pattern_size[0], 0:pattern_size[1]].T.reshape(-1, 2)
# 存储对象点和图像点的数组
objpoints = [] # 三维点在世界坐标系中的位置
imgpoints = [] # 二维点在图像平面的位置
# 读取图像
images = glob.glob(images_path)
for fname in images:
img = cv2.imread(fname)
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
# 查找棋盘格角点
ret, corners = cv2.findChessboardCorners(gray, pattern_size, None)
# 如果找到,添加对象点和图像点
if ret:
objpoints.append(objp)
# 亚像素级角点检测,提高角点精度
corners2 = cv2.cornerSubPix(gray, corners, (11, 11), (-1, -1),
(cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 30, 0.001))
imgpoints.append(corners2)
# 标定相机
ret, camera_matrix, dist_coeffs, rvecs, tvecs = cv2.calibrateCamera(
objpoints, imgpoints, gray.shape[::-1], None, None)
return camera_matrix, dist_coeffs, rvecs, tvecs
# 2. 图像畸变校正函数
def undistort_image(image_path, camera_matrix, dist_coeffs):
"""
使用相机内参和畸变系数校正图像畸变
参数:
image_path: 待校正图像的路径
camera_matrix: 相机内参矩阵
dist_coeffs: 畸变系数
返回:
undistorted_img: 校正后的图像
"""
# 读取图像
img = cv2.imread(image_path)
# 获取图像尺寸
h, w = img.shape[:2]
# 优化相机内参
new_camera_matrix, roi = cv2.getOptimalNewCameraMatrix(
camera_matrix, dist_coeffs, (w, h), 1, (w, h))
# 校正畸变
undistorted_img = cv2.undistort(img, camera_matrix, dist_coeffs, None, new_camera_matrix)
# 裁剪图像以去除黑边
x, y, w, h = roi
undistorted_img = undistorted_img[y:y+h, x:x+w]
return undistorted_img
# 3. 示例使用
if __name__ == "__main__":
# 标定相机
camera_matrix, dist_coeffs, rvecs, tvecs = camera_calibration(
images_path='./calibration_images/*.jpg', pattern_size=(9, 6))
print("相机内参矩阵:")
print(camera_matrix)
print("\n畸变系数:")
print(dist_coeffs)
# 校正示例图像
test_image_path = './test_image.jpg'
undistorted_img = undistort_image(test_image_path, camera_matrix, dist_coeffs)
# 显示原始图像和校正后的图像
original_img = cv2.imread(test_image_path)
original_img = cv2.cvtColor(original_img, cv2.COLOR_BGR2RGB)
undistorted_img = cv2.cvtColor(undistorted_img, cv2.COLOR_BGR2RGB)
plt.figure(figsize=(12, 6))
plt.subplot(121), plt.imshow(original_img)
plt.title('原始图像'), plt.axis('off')
plt.subplot(122), plt.imshow(undistorted_img)
plt.title('校正后图像'), plt.axis('off')
plt.tight_layout()
plt.show()
代码解释
上述代码主要实现了两个核心功能:
相机标定:
camera_calibration
函数使用张正友标定法计算相机内参和畸变系数。它通过以下步骤工作:- 准备标定板的三维坐标点(世界坐标系)
- 在多幅图像中检测棋盘格角点并精确化其位置
- 使用OpenCV的
calibrateCamera
函数计算相机内参矩阵和畸变系数
图像畸变校正:
undistort_image
函数使用计算得到的相机参数校正图像畸变:- 读取待校正图像并获取尺寸
- 优化相机内参以减少黑边
- 使用
undistort
函数校正畸变 - 裁剪图像以去除校正后可能出现的黑边
基于AI的畸变校正最新进展
近年来,基于深度学习的畸变校正方法取得了显著进展,主要包括以下方向:
端到端学习方法:
- 直接学习从畸变图像到无畸变图像的映射,如使用U-Net、GAN等架构
- 无需显式的相机标定过程,适用于未知畸变模型的场景
物理感知的深度学习:
- 将物理模型(如径向畸变模型)融入神经网络设计
- 结合传统方法的优势,提高校正精度和泛化能力
无监督与自监督学习:
- 利用图像自身的几何约束(如直线保持性)进行无监督训练
- 无需大量成对的畸变-无畸变图像数据
多模态与多视角融合:
- 结合RGB、深度信息或多视角图像进行更精确的畸变校正
- 适用于复杂场景下的三维重建和增强现实应用
轻量级网络设计:
- 针对移动设备和实时应用,设计高效轻量级畸变校正网络
- 如GhostNet、ShuffleNet等架构的应用
未来研究方向
畸变校正技术的未来发展可能集中在以下几个方面:
跨设备与泛化能力:
- 开发能够适应不同相机型号和未知畸变模式的通用校正方法
- 利用元学习(meta-learning)快速适应新设备
动态场景与视频畸变校正:
- 处理视频序列中的时变畸变和运动模糊
- 结合光流估计和时序信息进行连续帧的一致性校正
与其他计算机视觉任务的协同优化:
- 将畸变校正与目标检测、语义分割等任务联合优化
- 设计多任务学习框架,提高整体系统性能
3D感知的畸变校正:
- 结合深度信息和场景几何先验进行更精确的畸变校正
- 应用于增强现实、自动驾驶等需要精确3D建模的领域
实时与边缘计算优化:
- 开发适合边缘设备的低功耗、高效率畸变校正算法
- 利用硬件加速(如GPU、NPU)实现实时处理
伦理与隐私保护:
- 在畸变校正过程中考虑隐私保护,如人脸模糊、敏感信息遮挡
- 开发可解释的AI畸变校正方法,提高技术透明度
总之,畸变校正技术正朝着更智能、更高效、更普适的方向发展,AI方法与传统物理模型的融合将是未来研究的重要趋势。