Исправленные изображения показывают нежелательные результаты, OpenCV со Stereo Vision - PullRequest
0 голосов
/ 03 августа 2020

У меня проблемы при попытке создать карту глубины с помощью OpenCV на Python. Проблема в том, что исправленные изображения выглядят перевернутыми или искаженными. Вот код.

import cv2

CAMERA_PORT1 = 2
CAMERA_PORT2 = 4
# Package importation

# Filtering
kernel = np.ones((3, 3), np.uint8)

# *************************************************
# ***** Parameters for Distortion Calibration *****
# *************************************************

# Termination criteria
criteria = (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 30, 0.001)
criteria_stereo = (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 30, 0.001)

# Prepare object points
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 images
objpoints = []  # 3d points in real world space
imgpointsR = []  # 2d points in image plane
imgpointsL = []

# Start calibration from the camera
print('Starting calibration for the 2 cameras... ')
#PicForCalibration/Cam1/LeftCam1.jpg
PATH_CALIBRATION_IMAGE_CAM1 = "PicForCalibration/Cam1/LeftCam" #Cam1 is the left one
PATH_CALIBRATION_IMAGE_CAM2 = "PicForCalibration/Cam2/RightCam" #Cam2 is the right one

# Call all saved images
for i in range(1, 68):  # Put the amount of pictures you have taken for the calibration inbetween range(0,?) wenn starting from the image number 0
    t = str(i)
    ChessImaL = cv2.imread(PATH_CALIBRATION_IMAGE_CAM1 + t + '.jpg', 0)  # Left side
    ChessImaR = cv2.imread(PATH_CALIBRATION_IMAGE_CAM2 + t + '.jpg', 0)  # Right side

    retR, cornersR = cv2.findChessboardCorners(ChessImaR,
                                               (9, 6), None)  # Define the number of chees corners we are looking for
    retL, cornersL = cv2.findChessboardCorners(ChessImaL,
                                               (9, 6), None)  # Left side
    if (True == retR) & (True == retL):
        objpoints.append(objp)
        cv2.cornerSubPix(ChessImaR, cornersR, (11, 11), (-1, -1), criteria)
        cv2.cornerSubPix(ChessImaL, cornersL, (11, 11), (-1, -1), criteria)
        imgpointsR.append(cornersR)
        imgpointsL.append(cornersL)

# Determine the new values for different parameters
#   Right Side
retR, mtxR, distR, rvecsR, tvecsR = cv2.calibrateCamera(objpoints,
                                                        imgpointsR,
                                                        ChessImaR.shape[::-1], None, None)
hR, wR = ChessImaR.shape[:2]
OmtxR, roiR = cv2.getOptimalNewCameraMatrix(mtxR, distR,
                                            (wR, hR), 1, (wR, hR))

#   Left Side
retL, mtxL, distL, rvecsL, tvecsL = cv2.calibrateCamera(objpoints,
                                                        imgpointsL,
                                                        ChessImaL.shape[::-1], None, None)
hL, wL = ChessImaL.shape[:2]
OmtxL, roiL = cv2.getOptimalNewCameraMatrix(mtxL, distL, (wL, hL), 1, (wL, hL))

print('Cameras Ready to use')

# ********************************************
# ***** Calibrate the Cameras for Stereo *****
# ********************************************

# StereoCalibrate function
flags = 0
flags |= cv2.CALIB_FIX_INTRINSIC

retS, MLS, dLS, MRS, dRS, R, T, E, F = cv2.stereoCalibrate(objpoints,
                                                           imgpointsL,
                                                           imgpointsR,
                                                           mtxL,
                                                           distL,
                                                           mtxR,
                                                           distR,
                                                           ChessImaR.shape[::-1],
                                                           criteria_stereo,
                                                           flags)

# StereoRectify function
rectify_scale = 0  # if 0 image croped, if 1 image nor croped
RL, RR, PL, PR, Q, roiL, roiR = cv2.stereoRectify(MLS, dLS, MRS, dRS,
                                                  ChessImaR.shape[::-1], R, T,
                                                  rectify_scale,
                                                  (0, 0))  # last paramater is alpha, if 0= croped, if 1= not croped
# initUndistortRectifyMap function
Left_Stereo_Map = cv2.initUndistortRectifyMap(MLS, dLS, RL, PL,
                                              ChessImaR.shape[::-1],
                                              cv2.CV_16SC2)  # cv2.CV_16SC2 this format enables us the programme to work faster
Right_Stereo_Map = cv2.initUndistortRectifyMap(MRS, dRS, RR, PR,
                                               ChessImaR.shape[::-1], cv2.CV_16SC2)
# *******************************************
# ***** Parameters for the StereoVision *****
# *******************************************

# Create StereoSGBM and prepare all parameters
window_size = 3
min_disp = 2
num_disp = 130 - min_disp

stereo = cv2.StereoSGBM_create(minDisparity=min_disp,
                               numDisparities=num_disp,
                               blockSize=window_size,
                               uniquenessRatio=10,
                               speckleWindowSize=100,
                               speckleRange=32,
                               disp12MaxDiff=5,
                               P1=8 * 3 * window_size ** 2,
                               P2=32 * 3 * window_size ** 2)

# Used for the filtered image
# stereoR = cv2.ximgproc.createRightMatcher(stereo)  # Create another stereo for right this time
#
# # WLS FILTER Parameters
# lmbda = 80000
# sigma = 1.8
# visual_multiplier = 1.0
#
# wls_filter = cv2.ximgproc.createDisparityWLSFilter(matcher_left=stereo)
# wls_filter.setLambda(lmbda)
# wls_filter.setSigmaColor(sigma)

# *************************************
# ***** Starting the StereoVision *****
# *************************************

# Call the two cameras
CamR = cv2.VideoCapture(CAMERA_PORT2)  # Wenn 0 then Right Cam and wenn 2 Left Cam
CamL = cv2.VideoCapture(CAMERA_PORT1)

while True:
    # Start Reading Camera images
    retR, frameR = CamR.read()
    retL, frameL = CamL.read()

    # Rectify the images on rotation and alignement
    Left_nice = cv2.remap(frameL, Left_Stereo_Map[0], Left_Stereo_Map[1], cv2.INTER_LANCZOS4, cv2.BORDER_CONSTANT,
                          0)  # Rectify the image using the kalibration parameters founds during the initialisation
    Right_nice = cv2.remap(frameR, Right_Stereo_Map[0], Right_Stereo_Map[1], cv2.INTER_LANCZOS4, cv2.BORDER_CONSTANT, 0)

    #Draw Red lines
    for line in range(0, int(Right_nice.shape[0]/20)): # Draw the Lines on the images Then numer of line is defines by the image Size/20
        Left_nice[line*20,:]= (0,0,255)
        Right_nice[line*20,:]= (0,0,255)

    for line in range(0, int(frameR.shape[0]/20)): # Draw the Lines on the images Then numer of line is defines by the image Size/20
        frameL[line*20,:]= (0,255,0)
        frameR[line*20,:]= (0,255,0)

    #Show the Undistorted images
    cv2.imshow('Both Images', np.hstack([Left_nice, Right_nice]))
    cv2.imshow('Normal', np.hstack([frameL, frameR]))

    # Convert from color(BGR) to gray
    grayR = cv2.cvtColor(Right_nice, cv2.COLOR_BGR2GRAY)
    grayL = cv2.cvtColor(Left_nice, cv2.COLOR_BGR2GRAY)


    # End the Programme
    if cv2.waitKey(1) & 0xFF == ord(' '):
        break

# Release the Cameras
CamR.release()
CamL.release()
cv2.destroyAllWindows() 

Короче говоря, код выполняет серию программ, начинающихся с:

  • Чтение файла изображения, снятого с двух камер
  • Калибруйте каждую камеру отдельно
  • Использование точных матриц и значений искажения в качестве параметров, когда я вызываю StereoCalibrate()

Папки изображений, которые я использовал, содержат 68 различных изображений для каждой камеры (всего 136 ). Результаты из calibrateCamera() составляют 0,77 и 0,94 для каждой камеры.

RetVal, который я собрал из StereoCalibrate(), был огромным, 39,0. Итак, я догадался, что проблема в кодах.

Здесь показаны изображения кадра камеры, снятые до и после исправления: исходное изображение исправленное изображение

Я действительно расстроен, потому что не знаю, что я сделал не так? Я также пытался найти эту проблему в Google, но похоже, что решение состоит в том, чтобы больше откалибровать камеры, чтобы получить более точные значения матриц и искажений. Лично я не верю, что это основная проблема, и думаю, что я выбрал неправильные параметры для вместо этого. Что вы думаете? Пожалуйста, дайте мне несколько советов ... ~

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...