仅已知相对径向畸变函数时如何通过OpenCV为图像添加畸变
核心逻辑说明
cv2.undistort 本身的默认能力是消除图像畸变,如果要实现添加畸变的需求,可通过设置虚拟归一化参数调用其映射逻辑实现,以下是无实际相机参数时的参数设置方案:
1. 内参矩阵(cameraMatrix)设置
因为不需要对应真实物理相机参数,可直接构造匹配你畸变函数定义域的虚拟内参,假设输入图像宽为w、高为h:
import numpy as np h, w = src_image.shape[:2] # 焦距设为图像高度的一半,保证相对视场高度1刚好对应图像上下边缘 cameraMatrix = np.array([ [h/2, 0, w/2], # fx为虚拟x方向焦距,cx为图像x方向中心 [0, h/2, h/2], # fy为虚拟y方向焦距,cy为图像y方向中心 [0, 0, 1] ], dtype=np.float32)
2. 畸变系数(distCoeffs)转换
OpenCV 径向畸变的计算逻辑为:畸变后坐标 = 无畸变坐标 * (1 + k1*r² + k2*r⁴ + k3*r⁶)
其中r就是你提到的相对视场高度,和你的畸变函数定义域完全匹配。
你可以根据自定义畸变函数的输出拟合k1、k2、k3三个径向畸变参数:
- 若r=1时畸变值为5%桶形畸变(边缘向内收缩),一阶拟合取
k1=0.05即可 - 若为枕形畸变(边缘向外扩张),对应k值取负数即可
- 不需要切向畸变的话,其余参数固定填0
最终畸变系数构造示例:
# 顺序为[k1, k2, 切向畸变p1, 切向畸变p2, k3] distCoeffs = np.array([0.05, 0, 0, 0, 0], dtype=np.float32)
3. 完整加畸变实现代码
cv2.undistort 本身不直接支持加畸变,可通过映射函数反向实现:
import cv2 import numpy as np src = cv2.imread("你的输入图像路径") h, w = src.shape[:2] # 构造内参和畸变系数 cameraMatrix = np.array([[h/2, 0, w/2], [0, h/2, h/2], [0,0,1]], dtype=np.float32) distCoeffs = np.array([0.05, 0, 0, 0, 0], dtype=np.float32) # 生成畸变映射表并输出畸变后图像 map1, map2 = cv2.initUndistortRectifyMap(cameraMatrix, distCoeffs, None, cameraMatrix, (w,h), cv2.CV_32FC1) distorted_img = cv2.remap(src, map1, map2, interpolation=cv2.INTER_LINEAR)
注意事项
- 如果你的畸变函数是非对称的,或者包含径向畸变之外的其他畸变类型,上述方案不适用,需要额外调整参数
- 如果需要100%匹配自定义畸变函数的输出,建议直接遍历像素计算畸变后坐标做映射,不需要套OpenCV的标准畸变模型,避免拟合误差
内容的提问来源于stack exchange,提问作者think nice things
相关产品推荐
相关产品推荐

