Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/opencv/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python OpenCV相机校准的奇怪结果_Python_Opencv - Fatal编程技术网

Python OpenCV相机校准的奇怪结果

Python OpenCV相机校准的奇怪结果,python,opencv,Python,Opencv,我正在按照OpenCV校准我的GoPro。为了校准,我在不同的位置有一堆带有棋盘的图片。然后我在棋盘顶部绘制3D轴,一切看起来都很好,校准似乎很好: 然后,我希望看到图像的未失真版本,而不剪切任何内容,我得到以下结果: 这显然毫无意义。我试着用另一组校准图像做同样的事情,结果成功了: 我不明白为什么第一组照片不起作用。有什么想法吗 以下是相关代码: # termination criteria criteria = (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRI

我正在按照OpenCV校准我的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()

米卡的观点很重要;确保校准网格尽可能多地填充图像很重要,或者至少在棋盘格靠近边界的位置有一些图片

这个问题是,中心附近的失真很小,边界处的失真很大。因此,较大的失真对图像的中心影响不大。等效地,从图像中心估计失真时的一个小错误可能导致失真的一个非常错误的总体估计


冗余图像“有点”重要;它有效地使这些图像(因此,棋盘格图案在这些图像中的位置)更加重要

第一组校准图像(全部)是什么样子的?根据我的经验,calibrateCamera函数在给定样本的图像区域内进行优化,因此尝试放置校准模式以尽可能覆盖图像的大部分@DanMašek我的校准图像看起来都很好(网格位于正确的位置)。我有很多图片都在非常相似的地方(多余的),我删除了一些,结果好多了。但我不知道原因。。冗余图像不应该很重要,对吧?冗余图像“有点”重要;有效地使这些图像(因此,棋盘格图案在这些图像中的位置)更加重要。米卡的观点也很重要;确保校准网格尽可能多地填充图像很重要,或者至少在棋盘格靠近边界的位置有一些图片。