새소식

장비 사용 설명서

ELP 스테레오 카메라를 사용해서 Depth Image 생성하기(1) : 캘리브레이션

  • -

ELP 스테레오 카메라를 써 보았습니다. 

 

https://www.aliexpress.us/item/3256805491174881.html?gatewayAdapt=kor2usa4itemAdapt 

 

https://www.aliexpress.us/item/3256805491174881.html?gatewayAdapt=kor2usa4itemAdapt

Welcome to AliExpress! Sign Out Register Sign in   My Orders My Coins Message Center Payment Wish List My Coupons

www.aliexpress.us

 

  • Resolution : 1920 x 1200
  • FOV : 120도

 

이 카메라는 특이하게 Left, Right 이미지가 따로 들어오는 게 아니라 이런 식으로 

 

 

이미지 하나로 들어오기 때문에 Width 를 반으로 나눠서 사용해야 합니다. 

 

이 카메라의 영문을 알 수 없는 점은, 케이블에 따라 컴퓨터에 연결이 되기도 하고 안 되기도 한다는 점입니다... 파워 케이블이 아니라 데이터 케이블임을 계속 확인했음에도 불구하고, 알 수 없는 이유로 케이블을 가립니다...

 

아무튼 연결이 되었다면 ls /dev 를 이용해서 이름 (video0, video1,.. 등) 을 확인한 후 캘리브레이션을 진행합니다. 

 

 

체커보드 사진을 촬영하고 사진들을 폴더에 저장합니다. 이후 사진을 읽어들여서 캘리브레이션을 수행할 수 있도록 다음 코드를 실행합니다. 

 

이 코드는 폴더 내부의 사진을 읽어들여서 캘리브레이션을 진행하고, 추출한 코너 정보를 포함하는 사진을 새로 저장하고 결과값을 출력합니다. 

 

import cv2 import numpy as np import glob import os # Number of inner corners per a chessboard row and column CHECKERBOARD = (6,9) # 이 부분을 사용하는 체커보드에 맞게 수정합니다. # 3D point real world coordinates objpoints = [] # 2D point image plane coordinates imgpoints1, imgpoints2 = [], [] objp = np.zeros((1, CHECKERBOARD[0]*CHECKERBOARD[1], 3), np.float32) objp[0,:,:2] = np.mgrid[0:CHECKERBOARD[0], 0:CHECKERBOARD[1]].T.reshape(-1, 2) * 20 # 이 부분을 실제 체커보드 사이즈에 맞게 (mm단위) 수정합니다. images = glob.glob('/home/jiwon/socap_ws/src/python_stereo_camera_calibrate/frames_prev/*.png') # 경로를 수정합니다. images.sort() gray_l = None gray_r = None # Create directory to save images with drawn corners os.makedirs("/home/jiwon/socap_ws/src/python_stereo_camera_calibrate/corners", exist_ok=True) for i, img_path in enumerate(images): img = cv2.imread(img_path) h, w = img.shape[:2] img_l = img[:, :w//2] # Left half img_r = img[:, w//2:] # Right half gray_l = cv2.cvtColor(img_l, cv2.COLOR_BGR2GRAY) gray_r = cv2.cvtColor(img_r, cv2.COLOR_BGR2GRAY) # 체스보드 코너 추출 ret_l, corners_l = cv2.findChessboardCorners(gray_l, CHECKERBOARD, cv2.CALIB_CB_ADAPTIVE_THRESH + cv2.CALIB_CB_FAST_CHECK + cv2.CALIB_CB_NORMALIZE_IMAGE) ret_r, corners_r = cv2.findChessboardCorners(gray_r, CHECKERBOARD, cv2.CALIB_CB_ADAPTIVE_THRESH + cv2.CALIB_CB_FAST_CHECK + cv2.CALIB_CB_NORMALIZE_IMAGE) if ret_l and ret_r: objpoints.append(objp) imgpoints1.append(corners_l) imgpoints2.append(corners_r) # Draw and display the corners cv2.drawChessboardCorners(img_l, CHECKERBOARD, corners_l, ret_l) cv2.drawChessboardCorners(img_r, CHECKERBOARD, corners_r, ret_r) # Stitch images back together img_combined = np.concatenate((img_l, img_r), axis=1) # Save image with drawn corners cv2.imwrite(f"/home/jiwon/socap_ws/src/python_stereo_camera_calibrate/corners/corners_{i}.png", img_combined) if imgpoints1 and imgpoints2: # Calibration is only performed if there are points # Perform camera calibration ret, mtx1, dist1, _, _ = cv2.calibrateCamera(objpoints, imgpoints1, gray_l.shape[::-1], None, None) ret, mtx2, dist2, _, _ = cv2.calibrateCamera(objpoints, imgpoints2, gray_r.shape[::-1], None, None) # Stereo calibration retval, _, _, _, _, R, T, E, F = cv2.stereoCalibrate(objpoints, imgpoints1, imgpoints2, mtx1, dist1, mtx2, dist2, gray_l.shape[::-1]) # Print intrinsic parameters print("Intrinsic parameters for camera 1:\n", mtx1) print("Distortion coefficients for camera 1:\n", dist1) print("Intrinsic parameters for camera 2:\n", mtx2) print("Distortion coefficients for camera 2:\n", dist2) # Print extrinsic parameters print("Rotation matrix:\n", R) print("Translation vector:\n", T) else: print("No chessboard could be detected in one or more images.")

 

 

코너가 잘 추출된 것을 볼 수 있습니다. 

 

 

사용한 ELP 스테레오 카메라의 캘리브레이션 결과는 다음과 같습니다. 

 

Intrinsic parameters for camera 1: [[608.48750953 0. 346.97177753] [ 0. 609.30750258 292.6478 ] [ 0. 0. 1. ]] Distortion coefficients for camera 1: [[ 0.00588765 0.45781552 -0.01111286 -0.01784361 -0.74075112]] Intrinsic parameters for camera 2: [[618.1437757 0. 376.95327818] [ 0. 622.6234544 290.76871985] [ 0. 0. 1. ]] Distortion coefficients for camera 2: [[ 8.93213509e-02 3.01508457e-01 -3.72771266e-05 -7.69577151e-04 -9.83399362e-01]] Rotation matrix: [[ 9.99600363e-01 -7.57917527e-04 -2.82584318e-02] [ 9.24993227e-05 9.99722857e-01 -2.35414733e-02] [ 2.82684427e-02 2.35294514e-02 9.99323401e-01]] Translation vector: [[-59.83977288] [ 1.11698986] [ 11.2134471 ]]

 

포스팅 주소를 복사했습니다

이 글이 도움이 되었다면 공감 부탁드립니다.