OpenCV Python立体校准和视差图

4

我希望找到一个场景的差异图。首先,我使用以下代码进行了立体校准(我自己编写了它,并在谷歌的帮助下略微调整,因为我没有找到任何有用的使用Python和OpenCV 2.4.10编写的相同教程)。

我同时在两个相机上拍摄了棋盘图像,并将它们保存为left*.jpg和right*.jpg。

import numpy as np
import cv2
import glob

# 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((6*9,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.
objpointsL = [] # 3d point in real world space
imgpointsL = [] # 2d points in image plane.
objpointsR = []
imgpointsR = []

images = glob.glob('left*.jpg')

for fname in images:
    img = cv2.imread(fname)
    grayL = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)

    # Find the chess board corners
    ret, cornersL = cv2.findChessboardCorners(grayL, (9,6),None)
    # If found, add object points, image points (after refining them)
    if ret == True:
        objpointsL.append(objp)

        cv2.cornerSubPix(grayL,cornersL,(11,11),(-1,-1),criteria)
        imgpointsL.append(cornersL)


images = glob.glob('right*.jpg')

for fname in images:
    img = cv2.imread(fname)
    grayR = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)

    # Find the chess board corners
    ret, cornersR = cv2.findChessboardCorners(grayR, (9,6),None)

    # If found, add object points, image points (after refining them)
    if ret == True:
        objpointsR.append(objp)

        cv2.cornerSubPix(grayR,cornersR,(11,11),(-1,-1),criteria)
        imgpointsR.append(cornersR)



retval,cameraMatrix1, distCoeffs1, cameraMatrix2, distCoeffs2, R, T, E, F = cv2.stereoCalibrate(objpointsL, imgpointsL, imgpointsR, (320,240))

如何矫正图像?在寻找视差图之前我需要进行哪些其他步骤?我看到有人说,在计算视差图时,两个帧上检测到的特征应位于同一水平线上。请在这里帮助我。非常感谢您的任何帮助。


仅供参考,目前我在这方面有很多经验,并且可以自信地说,opencv中的图像矫正代码不如Bouguet matlab工具箱稳健。如果您的数据质量好,您可能会发现opencv存在严重过拟合问题,这种情况下矫正将失败,并且您将得到大部分黑色图像。 Bouguet工具箱很好,因为您可以比opencv更加精细地排除回归参数,以减少立体校准中的过拟合。也许您不会遇到这个问题。 - kevinkayaks
3个回答

3

您需要使用cameraMatrix1distCoeffs1cameraMatrix2distCoeffs2和"newCameraMatrix"来进行cv2.undistort()操作。

您可以使用cv2.getOptimalNewCameraMatrix()来获得"newCameraMatrix"。

因此,在您的脚本的其余部分中,粘贴以下内容:

# Assuming you have left01.jpg and right01.jpg that you want to rectify
lFrame = cv2.imread('left01.jpg')
rFrame = cv2.imread('right01.jpg')
w, h = lFrame.shape[:2] # both frames should be of same shape
frames = [lFrame, rFrame]

# Params from camera calibration
camMats = [cameraMatrix1, cameraMatrix2]
distCoeffs = [distCoeffs1, distCoeffs2]

camSources = [0,1]
for src in camSources:
    distCoeffs[src][0][4] = 0.0 # use only the first 2 values in distCoeffs

# The rectification process
newCams = [0,0]
roi = [0,0]
for src in camSources:
    newCams[src], roi[src] = cv2.getOptimalNewCameraMatrix(cameraMatrix = camMats[src], 
                                                           distCoeffs = distCoeffs[src], 
                                                           imageSize = (w,h), 
                                                           alpha = 0)



rectFrames = [0,0]
for src in camSources:
        rectFrames[src] = cv2.undistort(frames[src], 
                                        camMats[src], 
                                        distCoeffs[src])

# See the results
view = np.hstack([frames[0], frames[1]])    
rectView = np.hstack([rectFrames[0], rectFrames[1]])

cv2.imshow('view', view)
cv2.imshow('rectView', rectView)

# Wait indefinitely for any keypress
cv2.waitKey(0)

希望这能帮助你迈向下一个阶段,也许是计算“视差图”;)

参考资料:

http://www.janeriksolem.net/2014/05/how-to-calibrate-camera-with-opencv-and.html


1

尝试这段代码,我已经能够解决错误:

retVal, cm1, dc1, cm2, dc2, r, t, e, f = cv2.stereoCalibrate(objpointsL, imgpointsL, imgpointsR, (320, 240), None, None,None,None)

Edmauricio 已经复活了! - kevinkayaks

0
首先,使用OpenCV标定应用程序或matlab calibration toolbox计算您的相机参数。有了这些参数,您就可以矫正您的图像。
矫正后,请参考OpenCV代码库中的Python示例 (samples/python/stereo_match.py)来计算视差图。

我使用上述发布的代码计算了相机参数。如何矫正我的图像? - Clive
2
-1 是因为校准参数已经获得。stereo_match.py 中的示例代码假定图像已经被矫正。然而,这里的问题是我们还没有矫正过的图像! - samkhan13

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接