Python - OpenCV: calibrateCamera 返回相机矩阵,但它是无意义的

Python - OpenCV: calibrateCamera returning camera matrix, but it is nonsensical

我正在尝试去除图像中的桶形和其他扭曲效果以专门应用于坐标。我在棋盘上使用 openCV,我设法获得了准确的角点 - 但是,当我应用这些角点时,我发现它们并不 return 我期望的。

图片:the orginal image: calibrationImage.bmp

import cv2
import numpy as np
img = cv2.imread('calibrationImage.bmp')
corners = array([[[136.58304, 412.18762]],

       [[200.73372, 424.21613]],

       [[263.41006, 431.9114 ]],

       [[334.     , 437.     ]],

       [[405.     , 436.     ]],

       [[470.78467, 428.75998]],

       [[530.23724, 420.48328]],

       [[152.61916, 358.20523]],

       [[210.78505, 368.59222]],

       [[270.52335, 371.8065 ]],

       [[335.67096, 373.8901 ]],

       [[400.88788, 373.57782]],

       [[462.57724, 371.10867]],

       [[517.49524, 366.26855]],

       [[168.55394, 310.78973]],

       [[228.     , 321.     ]],

       [[277.43225, 319.48358]],

       [[336.7225 , 320.90256]],

       [[396.0194 , 321.13016]],

       [[452.47888, 320.15744]],

       [[503.7933 , 318.09518]],

       [[183.49014, 270.53726]],

       [[231.8806 , 273.96835]],

       [[283.5549 , 275.63623]],

       [[337.41528, 276.47876]],

       [[391.28375, 276.99832]],

       [[442.8828 , 277.16376]],

       [[490.67108, 276.5398 ]],

       [[196.86388, 236.63716]],

       [[241.56177, 238.3809 ]],

       [[288.93515, 239.1635 ]],

       [[337.9244 , 239.63228]],

       [[386.90695, 240.31389]],

       [[434.21832, 241.17548]],

       [[478.62744, 241.05113]],

       [[208.81688, 208.1463 ]],

       [[250.11485, 208.97067]],

       [[293.5653 , 208.92986]],

       [[338.2928 , 209.22559]],

       [[382.94626, 209.92468]],

       [[426.362  , 211.03403]],

       [[467.76523, 210.82764]],

       [[219.20187, 184.123  ]],

       [[257.52582, 184.09167]],

       [[297.4925 , 183.80571]],

       [[338.5172 , 183.91574]],

       [[379.46725, 184.64926]],

       [[419.45697, 185.74242]],

       [[457.93872, 185.08537]],

       [[228.31578, 163.70671]],

       [[263.87802, 163.11162]],

       [[300.8062 , 162.71281]],

       [[338.686  , 162.79945]],

       [[376.43716, 163.36848]],

       [[413.39032, 164.23444]],

       [[449.21677, 163.16547]]], dtype=float32)

w, h = 7, 8
objp = np.zeros((h*w, 3), np.float32)
objp[:, :2] = np.mgrid[0:w, 0:h].T.reshape(-1, 2)
img_points = []
obj_points = []
img_points.append(corners)
obj_points.append(objp)
image_size = (img.shape[1], img.shape[0])

ret, mtx, dist, rvecs, tvecs = (obj_points, img_points, image_size, None, None)

updatedCorners = cv2.undistortPoints(corners, mtx, dist, P=mtx)
updatedCorners = updatedCorners.reshape([56,2])

ret = True
checkers = cv2.drawChessboardCorners(img, (7, 8), corners, ret)

fig, (img_ax) = plt.subplots(1, 1, figsize=(12,12))
img_ax.imshow(checkers)
img_ax.scatter(updatedCorners.T[0], updatedCorners.T[1], c='orange')

我试图通过不失真功能绘制角 运行 来查看校准效果如何。然而,当我绘制它们时,它们到处都是

有人知道哪里出了问题吗?

cv2.undistortPoints 需要从校准中检索到的相机矩阵和畸变系数。您向其提供了错误的信息。您当前已将相机矩阵和畸变系数设置为物点和图像大小。您也可以删除 P。如果您打算将未失真的点映射到另一个坐标系,则只能指定此选项。由于您正在仔细检查未失真的点是什么样子,将 P 指定为您之前找到的相同相机矩阵只会将其映射回您最初找到的点的位置,这不是您想要的。

这是一个最小的工作示例:

import cv2
import numpy as np

camera_matrix = np.array([[1300., 0., 600], [0., 1300., 480.], [0., 0., 1.]], dtype=np.float32)

dist_coeffs = np.array([-2.4, 0.95, -0.0004, 0.00089, 0.], dtype=np.float32)

test = np.zeros((10, 1, 2), dtype=np.float32)
xy_undistorted = cv2.undistortPoints(test, camera_matrix, dist_coeffs)

print(xy_undistorted)

相机矩阵是从校准中检索到的 3 x 3 矩阵,后面是一维 NumPy 数组的畸变系数。 test 是具有单例第二维的 3D NumPy 数组。确保每个变量都是 np.float32 类型,然后是 运行 函数。

不过,我怀疑您仅从一个角度就能获得不错的结果。如果您要校准变形严重的相机,通常需要更多。不过,以上是您需要使该方法起作用的内容。