繁体   English   中英

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

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

我试图摆脱图像中的桶形和其他失真效果,以专门应用于坐标。 我将 openCV 与棋盘一起使用,我设法获得了准确的角 - 但是,当我应用这些角时,我发现它们没有返回我所期望的。

图片:原始图片: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')

我试图通过绘制通过不失真 function 的角来查看校准的效果。 但是,当我 plot 他们到处都是

橙色的奇怪的未失真点

有谁知道出了什么问题?

cv2.undistortPoints期望从校准中检索到的相机矩阵和失真系数。 您向它提供了错误的信息。 您当前将相机矩阵和失真系数设置为 object 点和图像大小。 您也可以删除P 如果您打算将 map 未失真的点指向另一个坐标系,您只会指定此选项。 由于您正在仔细检查未失真点的样子,因此将P指定为您之前找到的相同相机矩阵只会 map 将它返回到您最初找到的点的位置,这不是您所追求的。

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

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 数组,第二个维度是 singleton。 确保每个变量都是np.float32类型,然后运行 function。

但是,我怀疑您是否会仅从一个角度获得体面的结果。 如果您要校准受大失真影响的相机,您通常需要更多。 尽管如此,以上是使该方法正常工作所需要的。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM