我正在做一个项目,我需要使用立体视觉来计算人和物体与相机的深度和距离。我使用的是 OpenCV 和 Waveshare 的 IMX219-83 相机,与 Jetson Nano 开发人员套件集成。左摄像头,另一个来自右摄像头。我提供了带有校准参数的 XML 文件,但是当我运行代码时,出现了一个问题:图像向右倾斜,视差有噪声,导致无法识别更近的物体;这只是一个模糊。图像帧大小为 640x480。任何测试图像都会出现此问题。下面是校准代码和视差代码。
(如果问题不够清楚,请让我知道,因为我是使用该平台的新手。)
棋盘图像存储库的链接: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()