基于OpenCV从畸变/无畸变图像求解投影仪畸变系数的技术问询
投影仪畸变系数求解问题
我存在概念理解上的困惑,现说明我的条件与需求:
- 拥有两张模拟图像:一张畸变图像,一张无畸变图像(可为棋盘格或任意图像)
- 实际场景为投影仪(非相机),任务是使用OpenCV计算畸变系数
目前尝试的方法全部失败,我认为原因在于常规相机校准需要多组不同姿态的平面图像,教程式的自动方法在此场景下不适用。
我猜测无需求解相机矩阵(可直接使用Unity生成的矩阵),仅需获取畸变系数、旋转向量(rvecs)和平移向量(tvecs)。我多次尝试相机校准,将畸变图像视为z=0的虚拟物体,但得到的结果误差极大。
单独获取rvecs和tvecs不成问题,通过透视变换即可实现且效果良好。但是否存在半自动方法,仅从这两张图像中求解畸变系数?常规相机校准完全行不通。
问题复现代码
我编写了如下代码来体现问题:手动畸变/去畸变功能正常(多数参数设为0以简化),但相机校准结果完全错误。是否存在OpenCV中我尚未发现的可用函数?
#%% import numpy as np import cv2 import matplotlib.pyplot as plt # 桶形畸变对应负径向位移,枕形畸变对应正径向位移 # 畸变系数 k1 = -3e-2 k2 = -5e-4 p1 = 0e-4 p2 = 0e-2 k3 = 0e-12 k4 = 0e-5 k5 = 0e-9 k6 = 0e-14 s1 = 0e-3 s2 = 0e-7 s3 = 0e-3 s4 = 0e-7 tx = 0e-1 ty = 0e-3 dist = np.array([k1, k2, p1, p2, k3, k4, k5, k6, s1, s2, s3, s4, tx, ty], dtype = "float32") # 生成网格状物体点 grid_size, square_size = [20, 20], 0.2 object_points = np.zeros([grid_size[0] * grid_size[1], 3], dtype="float32") mx, my = [(grid_size[0] - 1) * square_size / 2, (grid_size[1] - 1) * square_size / 2] for i in range(grid_size[0]): for j in range(grid_size[1]): object_points[i * grid_size[0] + j] = [i * square_size - mx, j * square_size - my, 0] # 绘制原始物体点 plt.scatter(object_points[:, 0], object_points[:, 1]) plt.title("原始物体点(物体平面)") plt.axis('equal') plt.xlim((-4, 4)) plt.ylim((-4, 4)) plt.grid() plt.show() # 设置相机参数 fx=2. fy=2. cx= 0. cy= 0. alpha = 0 # 倾斜因子,用于修正坐标系切变 mtx = np.array([[fx, alpha, cx], [0, fy, cy], [0, 0, 1]]) rvec = np.array([0.0, 0.0, 0.0]) tvec = np.array([0.0, 0.0, 0.0]) # 对物体点添加畸变,结果在图像平面上 image_points, jacobian = cv2.projectPoints(object_points, rvec, tvec, mtx, dist) # 绘制畸变后的图像点 plt.scatter(*zip(*image_points[:, 0, :])) plt.title("畸变后点(图像平面)") plt.axis('equal') plt.xlim((-4, 4)) plt.ylim((-4, 4)) plt.grid() plt.show() # 用已知相机矩阵和畸变系数去畸变,功能正常 undistpoints= cv2.undistortPoints(src= image_points , cameraMatrix= mtx, distCoeffs=dist) # 绘制去畸变后的点 plt.scatter(*zip(*undistpoints[:, 0, :])) plt.title("去畸变后点(物体平面)") plt.axis('equal') plt.xlim((-4, 4)) plt.ylim((-4, 4)) plt.grid() plt.show() objp =[object_points] imp= [undistpoints] retval, cameraMatrix, distCoeffs, rvecs, tvecs = cv2.calibrateCamera(objectPoints=objp, imagePoints=imp, imageSize=(100,100), cameraMatrix= None, distCoeffs= None) print("相机矩阵:") print(cameraMatrix) print("畸变系数:") print(distCoeffs) print("旋转向量:") print(rvecs) print("平移向量:") print(tvecs)
内容的提问来源于stack exchange,提问作者Philipp Enöckl
相关产品推荐
相关产品推荐

