카메라 캘리브레이션(camera calibration)은 카메라의 내부 파라미터와 외부 파라미터를 정확하게 계산하는 과정을 말합니다. 이를 통해 카메라의 이미지 센서와 실제 세계(world) 간의 관계를 정확하게 매핑할 수 있게 되며, 이를 통해 영상에서 발생하는 왜곡과 오차를 보정할 수 있습니다.
쉽게 말해서, 사진(이미지)에 있는 수많은 2D점들과 world 공간상의 3D 좌표들간의 관계를 알아가는 것인데, 이 관계는 카메라의 외부/내부 파라미터에 의해 결정되고, 그 파라미터들을 찾는 과정을 camera calibration이라 합니다.
Internal parameters
: 카메라나 렌즈 시스템의 focal length, optical center, radial distortion coefficient에 관한 parameter.
초점 거리 (focal length) -
주점 거리 (principal point) -
비대칭 계수 (skew coefficient) -
External parameters
우선, 3D좌표살의 한 점이 어떻게 이미지상에 대응되는 지 알아야합니다. 그러려면, 그전에 좌표계(coordinate system)에 대해서 이해하고 넘어가야 합니다.
쉽게 이해하기 위해서, 한 공간에 카메라가 설치되어 있다고 합시다. 그리고 그 공간에 하나의 3D 점이 있고, 카메라를 통해서 그 점을 pixel 좌표 ()를 찾고자하는 것이 목표라고 합니다.
좌표계에는 World Coordiate System, Camera Coordiate System, Image Coordiate System이 있는데요. 더 자세히는 아래에서 봅시다.
World Coordiate System
Camera Coordiate System
위에서 world좌표가 정의되었고, 그 공간에 카메라도 위치할 것인데, 그 카메라가 가많이 한 곳에만 있을 수 있으면 좋으련만...그렇지 않겠죠? 게다가 다양하게 회전도 할 수 있을 것입니다. 따라서 카메라 중심의 카메라 좌표계도 정의가 되어야하죠.
카메라가 world상의 임의의 위치 에 있고, 만큼 회전되어 있을때, 카메라 좌표는 아래 처럼 표현 할 수 있습니다.
Image Coordinate System
평행이동과 회전이 적용된 카메라를 통해서 공간에 있는 점을 이미지산에 project한다고 했을때, 그 점이 존재하는 좌표계를 Image Coordinate System, 영상 좌표계이라고 합니다.
optical center (pin hole)을 라고 하고, 이미지 평면(image plane)위에 점이 찍혀있다는 가정으로 시작해봅니다. 센서로 부터 읽힌 이미지는 180도 돌아간 상태로 있고, image plane은 optical center 바로 앞에 있습니다.그리고 image plane은 (focal length)만큼 optical center로 부터 떨어져 있죠.
그럼, 3D점 ()가 아래식으로 project하여 이미지상에 ()로 표현할 수 있죠.
다르게 표현해보면, 이 됩니다.
여기서 Intrinsic Matrix 을 얻을 수 있습니다.
하지만 이미지가 정사각형이 아닐 수 있으니, 를 로 나눌 수 있고요.
다음은 여기서 optical center가 이미지 중간에 있다는 가정을 없애고, 비대칭()도 존재한다고 하면, Intrinsic Matrix 가 됩니다.
위에서 World Coordiate System, Camera Coordiate System, Image Coordiate System를 이해하고 나면, world좌표와 image좌표간의 관계식은 아래와 같이 정리할 수 있습니다.
위의 배경 지식을 알고, 드디어 어떻게 캘리브레이션을 하는지를 보려고 합니다.
Define real world coordinates with check board
체크보드를 벽에 붙임으로 world 좌표를 정해놓습니다. 체크보드의 사각형 모서리의 점들을 3D 점들이라고 하고, 하나의 점을 world 좌표계의 origin으로 설정합니다. 는 벽을 따라 있고, 는 그 벽에 수직이라 설정합니다. 그럼, 체크보드는 XY 평면에 있게 됩니다.
calibration과정에서 3D 점들()과 그에 대응하는 이미지상의 위치 () 세트들로 camera parameter를 얻습니다.
이때ㅐ, 3D 점들을 알고 있는 차원상의 다양한 방향에서 촬영합니다. 모든 꼭지점들의 world 좌표는 체크보드위에 있기때문에, 는 0으로 설정될 수 있습니다. 그리고, 그 점들은 다 같은 간격으로 떨어져 있기 때문에, 한점을 알면 모든 점들을 쉽게 정의할 수 있습니다.
Capture multiple images of the checkerboard from different viewpoints
체크보드는 가만히 둔 상태로 여러 방향에서 많은 이미지들을 촬영하거나 카메라를 고정시키고 체크보드를 움직이거나 둘 중 하나를 선택하여 실행합니다.
Find 2D coordinates of checkerboard
# C++
bool findChessboardCorners(InputArray image, Size patternSize, OutputArray corners, int flags = CALIB_CB_ADAPTIVE_THRESH + CALIB_CB_NORMALIZE_IMAGE )
# python
retval, corners = cv2.findChessboardCorners(image, patternSize, flags)
# C++
void cornerSubPix(InputArray image, InputOutputArray corners, Size winSize, Size zeroZone, TermCriteria criteria)
# python
cv2.cornerSubPix(image, corners, winSize, zeroZone, criteria)
Calibrate Camera
world 좌표계의 3D 점들과 그들의 이미지상의 2D 위치를 OpenCV의 CalibrateCamera에 적용합니다.
# C++
double calibrateCamera(InputArrayOfArrays objectPoints, InputArrayOfArrays imagePoints, Size imageSize, InputOutputArray cameraMatrix, InputOutputArray distCoeffs, OutputArrayOfArrays rvecs, OutputArrayOfArrays tvecs)
# python
retval, cameraMatrix, distCoeffs, rvecs, tvecs = cv2.calibrateCamera(objectPoints, imagePoints, imageSize)
참고자료
https://learnopencv.com/camera-calibration-using-opencv/
https://learnopencv.com/geometry-of-image-formation/
https://darkpgmr.tistory.com/32