Python - OpenCV:calibrateCamera 返回相机矩阵,但它是荒谬的

问题描述

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

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

我试图通过绘制通过 undistort 函数运行的角来查看校准效果如何。然而,当我绘制它们时,它们到处都是

strange undistorted points in orange

有人知道出了什么问题吗?

解决方法

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

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

import cv2
import numpy as np

camera_matrix = np.array([[1300.,0.,600],[0.,1300.,480.],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 类型,然后运行该函数。

但是,我怀疑您仅凭一种观点就能获得不错的结果。如果您要校准受大失真影响的相机,则通常需要更多。尽管如此,以上内容是您使该方法工作所需的内容。

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...