Problems with camera calibration and calculating stereo disparity map

278 Views Asked by At

I'm working on a project where I need to use stereoscopic vision to calculate the depth and distance of people and objects from the camera. I'm using OpenCV and the IMX219-83 camera from Waveshare integrated with the Jetson Nano Developer Kit.right camera image input left camera image inputThere's an issue with this Python code where I'm trying to calculate the disparity between two images, one from the left camera and another from the right camera. I provided the XML file with the calibration parameters, but when I run the code, there's a problem: the images are tilted to the right, and the disparity is noisyDisparity issue, making it unable to recognize objects that are closer; it's just a blur. The image frame size is 640x480. This issue occurs with any test image. Below is the calibration code and the disparity code. (If the question is not clear enough, please let me know, as I am new to using the platform.) images output with calibration code

Link to repository to the chessboard images: https://drive.google.com/drive/folders/1jYZWDD02vziBKb2vnG1CTdzMo64xEUJI?usp=share_link

from __future__ import print_function

//code of disparity -----------------------------
//-----------------------------------------------------------

import numpy as np
import cv2


def main():
    cv_file = cv2.FileStorage()
    cv_file.open('stereoMap.xml', cv2.FILE_STORAGE_READ)
    stereoMapL_x = cv_file.getNode('stereoMapL_x').mat()
    stereoMapL_y = cv_file.getNode('stereoMapL_y').mat()
    stereoMapR_x = cv_file.getNode('stereoMapR_x').mat()
    stereoMapR_y = cv_file.getNode('stereoMapR_y').mat()
    imgL = cv2.imread("EpipolarGeometryAndStereoVision/left-images/left/fotoeditada.jpg", 0)
    imgL = cv2.resize(imgL, (640, 480))
    imgL = cv2.remap(imgL, stereoMapL_x, stereoMapL_y, 0, 0, 0)

    imgR = cv2.imread("EpipolarGeometryAndStereoVision/right-images/right/fotoeditadaright.jpg", 0)
    # imgR = cv2.resize(imgR, (640, 480))
    imgR = cv2.remap(imgR, stereoMapR_x, stereoMapR_y,  0, 0, 0)

    
    

    # Setting parameters for StereoSGBM algorithm
    minDisparity = 1
    numDisparities = 60 - minDisparity
    blockSize = 5
    uniquenessRatio = 1
    speckleWindowSize = 3
    speckleRange = 3
    disp12MaxDiff = 100
    # width = 640
    # baseline = 0.6
    P1 = 8 * 3 * blockSize ** 2
    P2 = 32 * 3 * blockSize ** 2

    stereo = cv2.StereoSGBM_create(
        minDisparity=minDisparity,
        numDisparities=numDisparities,
        blockSize=blockSize,
        uniquenessRatio=uniquenessRatio,
        speckleWindowSize=speckleWindowSize,
        speckleRange=speckleRange,
        disp12MaxDiff=disp12MaxDiff,
        P1=P1,
        P2=P2
    )

    # Calculating disparith using the StereoSGBM algorithm
    disparity = stereo.compute(imgL, imgR).astype(np.float32) / 16.0

    cv2.imshow('leftview',imgL)
    cv2.imshow('rightview', imgR)
    cv2.imshow('disparity', (disparity - minDisparity) / numDisparities)
    cv2.waitKey()


if __name__ == '__main__':
    main()
    cv2.destroyAllWindows()


//code of stereo camera calibration ---------------------------------------
//---------------------------------------------------------------------------

import numpy as np
import cv2 as cv
import glob

#####find chessboard corners - objecr points and image points

chessboardSize = (8,6)
frameSize = (480, 640)

#termination criteria

criteria = (cv.TERM_CRITERIA_EPS + cv.TERM_CRITERIA_MAX_ITER, 30, 0.001)


#prepare objetcs points

objp = np.zeros((chessboardSize[0] * chessboardSize[1], 3), np.float32)
objp[:,:2] = np.mgrid[0:chessboardSize[0],0:chessboardSize[1]].T.reshape(-1,2)

objp = objp * 24
print(objp)

# arrays to store object points and image points from all the images

objpoints = [] #3d point in the real world space
imgpointsL = [] # 2d points in image plane
imgpointsR = [] #2d points in image plane

imagesLeft = glob.glob('calibration/camera1/*.jpg')
# print(imagesLeft)
imagesRight = glob.glob('calibration/camera0/*.jpg')


for imgLeft, imgRight in zip(imagesLeft, imagesRight):
    imgL = cv.imread(imgLeft)
    imgR = cv.imread(imgRight)
    grayL = cv.cvtColor(imgL, cv.COLOR_BGR2GRAY)
    grayR = cv.cvtColor(imgR, cv.COLOR_BGR2GRAY)

    #find the chessboard corners
    retL, cornersL = cv.findChessboardCorners(grayL, chessboardSize, None)
    retR, cornersR = cv.findChessboardCorners(grayR, chessboardSize, None)

    #if found, add object points, images points (after refining them)

    if retL and retR == True:

        objpoints.append(objp)

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

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

        #Draw and display the coorners

        cv.drawChessboardCorners(grayL, chessboardSize, cornersL, retL)
        cv.imshow('img left', grayL)
        cv.drawChessboardCorners(grayR, chessboardSize, cornersR, retR)
        cv.imshow('img right', grayR)
        cv.waitKey(1000)

cv.destroyAllWindows()

####################### CALIIBRATION 

retL, cameraMatrixL, distL, rvecsL, tvecsL = cv.calibrateCamera(objpoints, imgpointsL, frameSize, None, None)
heightL, widthL, channelsL = imgL.shape
newCameraMatrixL, roi_L = cv.getOptimalNewCameraMatrix(cameraMatrixL, distL, (widthL, heightL), 1, (widthL, heightL))

retR, cameraMatrixR, distR, rvecsR, tvecsR = cv.calibrateCamera(objpoints, imgpointsR, frameSize, None, None)
heightR, widthR, channelsR = imgR.shape
newCameraMatrixR, roi_R = cv.getOptimalNewCameraMatrix(cameraMatrixR, distR, (widthR, heightR), 1, (widthR, heightR))

############ STEREO VISION CALIBRATION #######

flags = 0
flags |= cv.CALIB_FIX_INTRINSIC

#here we fix the intrisic camara matrixes so that only rot, trns, emat and fmat are calculated
#hence intriscic parameters are the same

criteria_stereo = (cv.TERM_CRITERIA_EPS + cv.TERM_CRITERIA_MAX_ITER, 30, 0.001)

#this step is performed to transformation between the two cameras and calculate essential and fundamental matrix

retStereo, newCameraMatrixL, distL, newCameraMatrixR, distR, rot, trans, essentialMatrix, fundamentalMatrix = cv.stereoCalibrate(objpoints, imgpointsL, imgpointsR, newCameraMatrixL, distL, newCameraMatrixR, distR, grayL.shape[::-1], criteria_stereo, flags)

########## Stereo Rectification #################################################

rectifyScale= 1
rectL, rectR, projMatrixL, projMatrixR, Q, roi_L, roi_R = cv.stereoRectify(newCameraMatrixL, distL, newCameraMatrixR, distR, grayL.shape[::-1], rot, trans, rectifyScale,(0,0))

stereoMapL = cv.initUndistortRectifyMap(newCameraMatrixL, distL, rectL, projMatrixL, grayL.shape[::-1], cv.CV_16SC2)
stereoMapR = cv.initUndistortRectifyMap(newCameraMatrixR, distR, rectR, projMatrixR, grayR.shape[::-1], cv.CV_16SC2)

print("Saving parameters!")
cv_file = cv.FileStorage('stereoMap.xml', cv.FILE_STORAGE_WRITE)

cv_file.write('stereoMapL_x',stereoMapL[0])
cv_file.write('stereoMapL_y',stereoMapL[1])
cv_file.write('stereoMapR_x',stereoMapR[0])
cv_file.write('stereoMapR_y',stereoMapR[1])

cv_file.release()

0

There are 0 best solutions below