我正在按照OpenCV tutorial校准我的GoPro。为了校准,我有一堆图片,棋盘位于不同的位置。然后我在棋盘上绘制3D轴,一切看起来都很好,校准似乎很好:
然后我想看到没有裁剪任何东西的图像的未失真版本,我得到了这个:
这显然没有任何意义。我试图用另一组校准图像做同样的事情并且它起作用了:
我不明白为什么它不能用于第一组图片。有什么想法吗?
以下是相关代码:
# termination criteria
criteria = (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 30, 0.001)
# prepare object points, like (0,0,0), (1,0,0), (2,0,0) ....,(6,5,0)
objp = np.zeros((9*6,3), np.float32)
objp[:,:2] = np.mgrid[0:9,0:6].T.reshape(-1,2)
# Arrays to store object points and image points from all the images.
objpoints = [] # 3d point in real world space
imgpoints = [] # 2d points in image plane.
files = os.listdir('frames')
for fname in files:
g = re.match('frame(\d+).png',fname)
n = g.groups()[0]
if n not in numbers:
os.remove('frames/%s'%fname)
continue
img = cv2.imread('frames/%s'%fname)
gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
# Find the chess board corners
ret, corners = cv2.findChessboardCorners(gray, (9,6),None)
# If found, add object points, image points (after refining them)
if ret == True:
corners2 = cv2.cornerSubPix(gray,corners,(11,11),(-1,-1),criteria)
img = cv2.drawChessboardCorners(img, (9,6), corners2,ret)
objpoints.append(objp)
imgpoints.append(corners2)
cv2.imshow('img',img)
cv2.waitKey(1)
cv2.destroyAllWindows()
ret, K, D, rvecs, tvecs = cv2.calibrateCamera(objpoints, imgpoints, gray.shape[::-1],None,None)
# K: intrinsic matrix - camera matrix
# D: Distortion coefficients
#Compute reconstruction error
mean_error = 0
for i in xrange(len(objpoints)):
imgpoints2, _ = cv2.projectPoints(objpoints[i], rvecs[i], tvecs[i], K, D)
error = cv2.norm(imgpoints[i],imgpoints2, cv2.NORM_L2)/len(imgpoints2)
mean_error += error
print "total error: ", mean_error/len(objpoints)
ret, rvec, tvec = cv2.solvePnP(objp, corners2, K, D)
# project 3D points to image plane Using openCV
imgpts, jac = cv2.projectPoints(axis, rvec, tvec, K, D)
img = draw(img,corners2,imgpts)
cv2.imshow('img',img)
k = cv2.waitKey(0) & 0xff
f = file('camera.pkl','wb')
cPickle.dump((K,D,rvec,tvec),f)
f.close()
#get the Undistorted image
h, w = img.shape[:2]
newcameraK, roi=cv2.getOptimalNewCameraMatrix(K,D,(w,h),1,(w,h))
dst = cv2.undistort(img, K, D, None, newcameraK)
plt.figure()
plt.axis("off")
plt.imshow(cv2.cvtColor(dst,cv2.COLOR_BGR2RGB))
plt.show()
答案 0 :(得分:0)
Micka的观点很重要;确保校准网格尽可能多地填充图像很重要,或者至少有一些棋盘格靠近边界的图片。
这个问题是中心附近的变形很小而边界处的变形很大。因此,大的失真不会非常影响图像的中心。同样地,从图像中心估计失真的小误差导致可能非常错误的失真总体估计。
冗余图像很重要"一点点&#34 ;;它有效地使这些图像(因此,棋盘图案在这些图像中的位置)更加重要。
答案 1 :(得分:0)
我也观察到了同样的效果,但更奇怪:
当我使用 getOptimalTransformationMatrix 时,我得到的图像也有像上面那样强烈的圆形失真效果。改变 alpha 也不能解决它。但是:当我在没有 getOptimalTransformationMatrix 的情况下使用相同的失真/校准结果(所以我使用与相机校准结果相同的 fx/fy/cx/cy)时,我在不失真方面得到了非常好的结果......非常奇怪......>
会不会是在某些情况下 getOptimalTransformationMatrix 函数有问题?我的校准(图像等)看起来很好,点也在边缘