我的代码是否正确进行了相机校准?

时间:2019-07-18 02:10:35

标签: opencv camera-calibration

我已经阅读过每一个相机校准和3D重建功能,除了文档以外,我找不到其他任何人。因此,话虽如此,我有了“相机校准”代码,可以在其中现场拍摄多张照片以进行相机校准。我敢肯定,除了实际的相机校准以外,其他所有功能都可以正常工作。每当我不使用Cv2.undistort进行扭曲时,就永远不会获得良好的图像,而是会得到一块甚至不属于棋盘的块。我做错了什么吗?

import numpy as np
import cv2

cam = cv2.VideoCapture(0)

cv2.namedWindow("test")

img_counter = 0
imgNames = []
size = (7,5)
while True:
    ret, frame = cam.read()
    gray =  cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)
    cv2.imshow("test", gray)
    if not ret:
        break
    k = cv2.waitKey(1)
    if k%256 == 27:
        break
    elif k%256 == 32:
        img_name = "{}.png".format(img_counter)
        cv2.imwrite(img_name, frame) 
        imgtemp = cv2.imread(img_name)
        graytemp = cv2.cvtColor(imgtemp,cv2.COLOR_BGR2GRAY)
        ret, corners = cv2.findChessboardCorners(graytemp, size,None)
        print (ret)
        if ret == True:
            print ("good!")
            imgNames.append(img_name)
            cv2.imwrite(img_name, frame)
            img_counter += 1
        else:
            print ("again")

cam.release()
cv2.destroyAllWindows()
criteria = (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 30, 
0.001)
objp = np.zeros((7*5,3), np.float32)
objp[:,:2] = np.mgrid[0:size[0],0:size[1]].T.reshape(-1,2) #multiply by 
length
objpoints = [] 
imgpoints = [] 

for fname in imgNames:
    img = cv2.imread(fname)
    gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
    ret, corners = cv2.findChessboardCorners(gray,size,None)

    if ret == True:
        objpoints.append(objp)
        corners2 = cv2.cornerSubPix(gray,corners,(11,11), 
(-1,-1),criteria)
        imgpoints.append(corners2)
    ret,mtx, dist, rvecs, tvecs = cv2.calibrateCamera(objpoints, 
imgpoints,gray.shape[::-1], None, None)
    img = cv2.imread(fname)
    h,  w = img.shape[:2]
    newcameramtx, roi=cv2.getOptimalNewCameraMatrix(mtx,dist,(w,h),1, 
(w,h))
    # undistort
    dst = cv2.undistort(img, mtx, dist, None, newcameramtx)

    # crop the image
    x,y,w,h = roi
    dst = dst[y:y+h, x:x+w]
    cv2.imshow('calibresult.png',dst)
    #Save parameters into numpy file
    np.save("ret", ret)
    np.save("mtx", mtx)
    np.save("dist", dist)
    np.save("rvecs", rvecs)
    np.save("tvecs", tvecs)

应该发生的是,我得到的图像没有失真,矩阵被保存了。但是,图像是随机的,我不知道出了什么问题。我已经查看了Google相机校准下弹出的所有内容以及所有Stack溢出问题。 我正在使用https://medium.com/@omar.ps16/stereo-3d-reconstruction-with-opencv-using-an-iphone-camera-part-ii-77754b58bfe0https://opencv-python-tutroals.readthedocs.io/en/latest/py_tutorials/py_calib3d/py_calibration/py_calibration.html

提前谢谢! 也很抱歉张贴了这么多问题。我只是在任何地方都找不到答案。

1 个答案:

答案 0 :(得分:0)

在您从所有图像中附加了cv2.calibrateCamera(objpoints, imgpoints, gray.shape[::-1], None, None)objpoints之后,应该执行imgpoints。它不应该在for循环中。

此外,请确保您有足够的图像以获得良好的校准结果。