카메라 캘리브레이션 (Camera Calibration)

영상처리 2013.02.01 16:59

카메라 캘리브레이션 (camera calibration)은 영상처리, 컴퓨터 비전 분야에서 번거롭지만 꼭 필요한 과정중의 하나입니다. 본 포스팅에서는 카메라 캘리브레이션의 개념, 카메라 내부 파라미터, 외부 파라미터, 카메라 핀홀 모델, 카메라 캘리브레이션 도구에 대해 관련된 개념이나 이론적 배경들을 전반적으로 정리해 보았습니다.


그림1. 카메라 캘리브레이션


0. 카메라 캘리브레이션이란?

1. 캘리브레이션 개요

2. 카메라 내부 파라미터(intrinsic parameters)

3. 카메라 외부 파라미터(extrinsic parameters)

4. 핀홀(pinhole) 카메라 모델

5. 캘리브레이션과 영상해상도 그리고 자동초점조절(auto focusing)

6. 캘리브레이션 도구(tool) 및 사용법

7. 캘리브레이션 결과가 달라지는 이유

8. 카메라 캘리브레이션 팁



0. 카메라 캘리브레이션이란?


우리가 실제 눈으로 보는 세상은 3차원입니다. 하지만 이것을 카메라로 찍으면 2차원의 이미지로 변하게 됩니다. 이 때, 3차원의 점들이 이미지 상에서 어디에 맺히는지는 기하학적으로 생각하면 영상을 찍을 당시의 카메라의 위치 및 방향에 의해 결정됩니다. 하지만 실제 이미지는 사용된 렌즈, 렌즈와 이미지 센서와의 거리, 렌즈와 이미지 센서가 이루는 각 등 카메라 내부의 기구적인 부분에 의해서 크게 영향을 받습니다. 따라서, 3차원 점들이 영상에 투영된 위치를 구하거나 역으로 영상좌표로부터 3차원 공간좌표를 복원할 때에는 이러한 내부 요인을 제거해야만 정확한 계산이 가능해집니다. 그리고 이러한 내부 요인의 파라미터 값을 구하는 과정을 카메라 캘리브레이션이라 부릅니다.



1. 캘리브레이션 개요


카메라 영상은 3차원 공간상의 점들을 2차원 이미지 평면에 투사(perspective projection)함으로써 얻어집니다. 핀홀(pinhole) 카메라 모델에서 이러한 변환 관계는 다음과 같이 모델링됩니다.


(1)


여기서, (X,Y,Z)는 월드 좌표계(world coordinate system) 상의 3D 점의 좌표, [R|t]는 월드 좌표계를 카메라 좌표계로 변환시키기 위한 회전/이동변환 행렬이며 A는 intrinsic camera matrix입니다.


그림 2. 카메라 좌표계


수식적으로 보면 카메라 캘리브레이션(camera calibration)은 위와 같은 3D 공간좌표와 2D 영상좌표 사이의 변환관계 또는 이 변환관계를 설명하는 파라미터를 찾는 과정입니다.


식(1)에서 [R|t]를 카메라 외부 파라미터(extrinsic parameter), A를 내부 파라미터(intrinsic parameter)라고 부릅니다. 그리고 A와 [R|t]를 합쳐서 camera matrix 또는 projection matrix라 부릅니다.


카메라 외부 파라미터는 카메라의 설치 높이, 방향(팬, 틸트) 등 카메라와 외부 공간과의 기하학적 관계에 관련된 파라미터이며 내부 파라미터는 카메라의 초점 거리, aspect ratio, 중심점 등 카메라 자체의 내부적인 파라미터를 의미합니다.



2. 카메라 내부 파라미터(intrinsic parameters)


카메라의 내부 파라미터로는 다음과 같은 것들이 있습니다.

  1. 초점거리(focal length): fx, fy
  2. 주점(principal point): cx, cy
  3. 비대칭계수(skew coefficient): skew_c = tanα



A. 초점거리(focal length)


흔히 초점거리라 하면 볼록렌즈의 초점을 생각하기 쉬운데, 여기서(카메라 모델) 말하는 초점거리는 렌즈중심과 이미지센서(CCD, CMOS 등)와의 거리를 말합니다.


그림 3. 카메라 모델


디지털 카메라 등에서 초점거리는 mm 단위로 표현되지만 카메라 모델에서 말하는 초점거리(f)는 픽셀(pixel) 단위로 표현됩니다. 즉, f의 단위로 픽셀이라는 의미입니다.


이미지의 픽셀(pixel)은 이미지 센서의 셀(cell)에 대응되기 때문에, 초점거리(f)가 픽셀(pixel) 단위라는 의미는 초점거리가 이미지 센서의 셀(cell) 크기에 대한 상대적인 값으로 표현된다는 의미입니다. 예를 들어, 이미지 센서의 셀(cell)의 크기가 0.1 mm이고 카메라의 초점거리가 f = 500 pixel이라고 하면 이 카메라의 렌즈 중심에서 이미지 센서까지의 거리는 이미지 센서 셀(cell) 크기의 500배 즉, 50 mm라는 의미입니다.


컴퓨터 비전 분야에서 카메라 초점거리를 물리단위(m, cm, mm, ...)가 아닌 픽셀단위로 표현하는 이유는 (이미지 픽셀과 동일한 단위로 초점거리를 표현함으로써) 영상에서의 기하학적 해석을 용이하게 하기 위함입니다.


그런데, 카메라 모델에서 초점거리를 하나의 값으로 f라 표현하지 않고 fx, fy로 구분하여 표현하는 경우가 있는데(실제로 카메라 캘리브레이션을 수행하면 fx, fy를 구분하여 반환한다) 이는 이미지 센서의 물리적인 셀 간격이 가로 방향과 세로 방향이 서로 다를 수 있음을 모델링하기 위함입니다. 이 경우 fx는 초점거리(렌즈중심에서 이미지 센서까지의 거리)가 가로 방향 셀 크기(간격)의 몇 배인지를 나타내고 fy는 초점거리가 세로 방향 센서 셀 크기(간격)의 몇 배인지를 나타냅니다. fx와 fy 모두 단위는 픽셀(pixel)이며 현대의 일반적인 카메라는 가로방향 셀 간격과 세로방향 셀 간격의 차이가 없기 때문에 f = fx = fy라 놓아도 무방합니다.


참고로, 동일한 카메라로 캘리브레이션을 수행했을 때, 이미지 해상도를 1/2로 낮추면 캘리브레이션 결과의 초점거리도 1/2로 작아집니다. 실제 물리적 초점거리가 변하는 것은 아니지만 카메라 모델에서의 초점거리는 상대적인 개념이기 때문에 해상도를 바꾸면 한 픽셀(pixel)에 대응하는 물리크기가 변하고 따라서 초점거리도 변하게 됩니다. 예컨데, 이미지 해상도를 1/2로 낮추면 이미지 센서의 2 x 2 셀(cell)들이 합쳐서 하나의 이미지 픽셀이 되기 때문에 한 픽셀에 대응하는 물리크기가 2배가 됩니다. 따라서 초점거리는 1/2이 되어야 합니다.


카메라 모델의 렌즈중심(초점)은 핀홀 카메라 모델(그림 6)에서 핀홀(pinhole)에 해당됩니다. 핀홀 카메라 모델은 모든 빛은 한 점(초점)을 직선으로 통과하여 이미지 평면(센서)에 투영된다는 모델입니다. 이러한 핀홀 모델은 3D 공간과 2D 이미지 평면 사이의 기하학적 투영(projection) 관계를 매우 단순화시켜 줍니다.


초점으로부터 거리가 1(unit distance)인 평면을 normalized image plane이라고 부르며 이 평면상의 좌표를 보통 normalized image coordinate라고 부릅니다. 물론 이것은 실제는 존재하지 않는 가상의(상상의) 이미지 평면입니다. 카메라 좌표계 상의 한 점 (Xc, Yc, Zc)를 영상좌표계로 변환할 때 먼저 Xc, Yc를 Zc(카메라 초점에서의 거리)로 나누는 것은 이 normalized image plane 상의 좌표로 변환하는 것이며, 여기에 다시 초점거리 f를 곱하면 우리가 원하는 이미지 평면에서의 영상좌표(pixel)가 나옵니다 (그림 4 참조). 그런데, 이미지에서 픽셀좌표는 이미지의 중심이 아닌 이미지의 좌상단 모서리를 기준(원점)으로 하기 때문에 실제 최종적인 영상좌표는 여기에 (cx, cy)를 더한 값이 됩니다. 즉, x = fxX/Z+cx, y = fyY/Z+cy. 카메라 모델에서 사용하는 좌표계 표현 및 변환에 대한 보다 자세한 내용에 대해서는 [영상처리] - [영상 Geometry #1] 좌표계 글을 참조하기 바랍니다.



그림 4. 카메라 투영(projection) 모델


=> 초점거리에 대한 보다 자세한 내용에 대해서는 [영상처리] - 카메라의 초점거리(focal length) 글을 참조하기 바랍니다 (2013.10.23).



B. 주점(principal point)


주점 cx, cy는 카메라 렌즈의 중심 즉, 핀홀에서 이미지 센서에 내린 수선의 발의 영상좌표(단위는 픽셀)로서 일반적으로 말하는 영상 중심점(image center)과는 다른 의미입니다. 예를 들어서, 카메라 조립과정에서 오차로 인해 렌즈와 이미지 센서가 수평이 어긋나면 주점과 영상중심은 다른 값을 가질 것입니다.


영상기하학에서는 단순한 이미지 센터보다는 principal point가 훨씬 중요하며  영상의 모든 기하학적 해석은 이 주점을 이용하여 이루어집니다.



C. 비대칭 계수(skew coefficient)


비대칭 계수 skew_c는 이미지 센서의 cell array의 y축이 기울어진 정도를 나타냅니다 (skew_c = tanα).

그림 5. 카메라 비대칭 계수


요즘 카메라들은 이러한 skew 에러가 거의 없기 때문에 카메라 모델에서 보통 비대칭 계수까지는 고려하지 않는다고 합니다 (즉, skew_c = 0).


이러한 카메라 내부 파라미터들은 공개된 캘리브레이션 툴 등을 이용하면 비교적 쉽게 계산할 수 있습니다. 공개 캘리브레이션 툴 소개 및 사용법은 본 포스팅 하단을 참조하시기 바랍니다.



3. 카메라 외부 파라미터(extrinsic parameters)


카메라 외부 파라미터는 카메라 좌표계와 월드 좌표계 사이의 변환 관계를 설명하는 파라미터로서, 두 좌표계 사이의 회전(rotation) 및 평행이동(translation) 변환으로 표현됩니다.


카메라 외부 파라미터는 카메라 고유의 파라미터가 아니기 때문에 카메라를 어떤 위치에 어떤 방향으로 설치했는지에 따라 달라지고 또한 월드 좌표계를 어떻게 정의했느냐에 따라서 달라집니다.


카메라 외부 파라미터를 구하기 위해서는 먼저 캘리브레이션 툴 등을 이용하여 카메라 고유의 내부 파라미터들을 구합니다. 다음으로는 미리 알고 있는 또는 샘플로 뽑은 3D월드좌표–2D영상좌표 매칭 쌍들을 이용하여 식(1)에서 변환행렬을 구하면 됩니다. OpenCV에 있는 solvePnP함수를 이용하면 이러한 계산을 손쉽게 할 수 있습니다.


☞ 카메라 외부 파라미터 캘리브레이션 및 영상 기하학에 대한 전반적인 내용에 대해서는 [영상처리] - Extrinsic Camera Calibration - 카메라의 위치 및 자세 파악 글을 참고하기 바랍니다.



4. 핀홀(pinhole) 카메라 모델


핀홀 카메라 모델은 아래 그림과 같이 하나의 바늘구멍(pinhole)을 통해 외부의 상이 이미지로 투영된다는 모델입니다. 이 때, 이 바늘구멍(pinhole)이 렌즈 중심에 해당되며 이곳에서 뒷면의 상이 맺히는 곳까지의 거리가 카메라 초점거리입니다 (광학적으로 렌즈의 중심을 투과하는 빛은 굴절되지 않고 그대로 직선으로 투과한다고 합니다).


그림 6. 핀홀 카메라 모델

(그림출처: http://en.wikipedia.org/wiki/Pinhole_camera_model)


영상처리 분야에서 영상에 대한 모든 기하학적 해석은 이 핀홀 카메라 모델을 바탕으로 이루어집니다. 하지만, 사실 핀홀 카메라 모델은 매우 이상적인 카메라 모델이며 실제로는 렌즈계의 특성에 따른 영상 왜곡 등도 같이 고려되어야 합니다. 영상 왜곡에 대한 내용은 [영상처리] - 카메라 왜곡보정을 참조해 주시기 바랍니다.



5. 캘리브레이션과 영상 해상도 그리고 자동초점조절(auto focusing)


카메라에 있는 오토 포커싱(auto focusing) 기능을 켜면 계속 초점거리가 바뀔 수 있기 때문에 캘리브레이션 목적에는 적합하지 않습니다. 카메라에 대해 캘리브레이션을 수행하고 캘리브레이션 결과를 다른 계산 목적에 사용하고자 한다면 오토 포커싱 기능은 꺼 놓고 사용하는게 좋습니다.


카메라에는 보통 영상 해상도를 QVGA(320x240), VGA(640x480), 960x480, ... 등 다양하게 설정할 수 있습니다. 그런데, 영상 해상도를 바꾸면 카메라 캘리브레이션 결과도 바뀌는 것을 확인 할 수 있을 것입니다. 카메라 내부 파라미터중 초점거리 fx, fy, 주점 cx, cy는 픽셀 단위를 사용하는데, 카메라의 물리적인 초점거리나 이미지 센서의 크기는 변하지 않지만 한 픽셀이 나타내는 물리적 크기가 변하기 때문입니다. 그래서 만일 영상해상도를 VGA로 놓고 캘리브레이션 한 결과과 QVGA로 놓고 캘리브레이션 한 결과를 비교해 보면 QVGA의 경우가 fx, fy, cx ,cy의 값이 1/2씩 줄어들게 됩니다. 반면에 렌즈왜곡계수(k1, k2, p1, p2)는 normalized 좌표계에서 수행되기 때문에 영상 해상도와 관계없이 항상 동일합니다. 따라서, 한 해상도에서만 캘리브레이션을 수행해도 다른 모든 해상도에 대한 파라미터 값을 구할 수 있게 됩니다. 렌즈왜곡계수는 동일하며, fx,fy,cx,cy만 영상 해상도에 비례해서 조정해 주면 됩니다.



6. 캘리브레이션 도구(tool) 및 사용법


A. Dark Cam Calibrator


최근에 직접 구현한 것인데 필요하시면 한번 사용해 보시기 바랍니다 ([개발한 것들] - 카메라 캘리브레이션 프로그램 (DarkCamCalibrator)). 카메라에서 직접 영상을 획득할 수 있으며 Fisheye 왜곡모델에 대한 캘리브레이션도 가능하다는 특징이 있습니다. OpenCV를 이용하여 구현한 것으로서 캘리브레이션 성능 자체는 OpenCV 성능과 같습니다.



B. GML C++ Camera Calibration Toolbox


가장 손쉽게 이용할 수 있는 공개 캘리브레이션 툴로는 GML C++ Camera Calibration Toolbox가 있습니다. 현재 0.73버전이 가장 최신버전이며 소소코드도 같이 공개되어 있습니다.


사이트 링크: http://graphics.cs.msu.ru/en/node/909

직접 다운로드: GML_CameraCalibrationInstall_0.73.exe



그림 7. GML 카메라 캘리브레이션 툴


기본적인 사용법은 캘리브레이션 패턴(chess board)이 인쇄된 종이를 다양한 위치 및 각도에서 카메라로 촬영한 후 영상으로 저장하고 위 툴(tool)로 캘리브레이션을 수행하면 됩니다. 자세한 사용법 및 최적의 영상획득 방법 등은 프로그램 자체에 포함된 설명문(Help)을 참조하시기 바랍니다.


이 툴의 특징은 위 그림과 같이 여러 개의 캘리브레이션 패턴을 동시에 사용하여 캘리브레이션을 수행할 수 있다는 점입니다. 툴의 설명문에 보면 2개 이상의 패턴을 사용했을 때 캘리브레이션 효과가 좀더 좋다고 나와 있습니다. 물론 1개의 패턴만을 사용하는 것도 가능합니다.


위 툴을 사용하여 캘리브레이션을 수행하면 다음과 같은 형태로 결과를 볼 수 있습니다.


그림 8. GML 카메라 캘리브레이션 툴 실행 예시


캘리브레이션 결과는 위 예와 같이 추정치 ± 추정오차(3*sigma) 형태로 출력되며 각각의 항목의 의미는 다음과 같습니다.

  • Focal length: fx = 3497.576, fy = 3501.038
  • Principal point: cx = 1058.429, cy = 797.136
  • Distortion: k1 = -0.041196, k2 = -0.203893, p1 = 0.006114, p2 = 0.002318 (k1,k2: radial distortion 계수, p1,p2: tangential distortion 계수)



C. Camera Calibration Toolbox for Matlab


아마도 카메라 캘리브레이션 분야에 있어서 가장 대표적인 툴로 생각됩니다. Matlab으로 구현되어 있으며 다소 사용법이 복잡하지만 캘리브레이션 과정의 세세한 부분을 직접 설정할 수 있으며 보다 정밀한 캘리브레이션이 가능합니다.


사이트 링크: http://www.vision.caltech.edu/bouguetj/calib_doc/


그림 9. Caltech 카메라 캘리브레이션 툴


위 사이트는 또한 카메라 캘리브레이션 분야에 있어서 가장 대표적인 사이트로서 캘리브레이션 툴 뿐만 아니라 캘리브레이션에 대한 전반적인 이론 및 정보가 잘 정리되어 있습니다. 캘리브레이션을 연구하는 (영어권) 사람들은 주로 이 사이트를 통해 필요한 정보를 얻는 것으로 알고 있습니다.



7. 캘리브레이션 결과가 달라지는 이유 (2015.5.12 추가)


댓글로 문의를 많이 주시는 내용인데 본문에 내용을 추가하는 것도 좋을 것 같아서 추가합니다.


카메라 캘리브레이션 결과가 달라지는 것은 먼저 카메라의 auto focus 기능이 켜져 있는지 확인해야 합니다. 물론 auto focus 기능이 꺼져 있음에도 불구하고 결과가 달라질 수 있지만 그 편차는 auto focus 기능이 켜져 있는 경우에 비해 훨씬 줄어들 것입니다. 하지만, auto focusing 여부와 관계없이 근본적으로 동일한 카메라에 대해 캘리브레이션 결과가 달라질 수 있는 이유는 몇 가지 원인이 있는데 적어보면 다음과 같습니다.

  • 캘리브레이션은 완벽한 핀홀 카메라 모델을 가정하고 파라미터를 찾지만 실제 카메라는 핀홀 카메라 모델이 아닐 수 있습니다.
  • 카메라 캘리브레이션 과정에 렌즈계 왜곡모델이 들어가는데, 일반적으로 사용되는 렌즈계 왜곡모델은 왜곡 특성을 저차의 다항함수로 근사하는 것이기 때문에 실제의 렌즈계 왜곡과는 차이가 발생할 수 있습니다.
  • 마지막으로 카메라 캘리브레이션은 어떤 방정식을 풀어서 딱 떨어지게 해를 찾는 것이 아니라 해에 대한 초기 추정치부터 시작해서 최적화 기법을 적용하여 반복적인 탐색 과정을 거쳐 근사적인 해를 찾는 것이기 때문에 매번 해가 달라질 수 있습니다.

결국 카메라의 내부 파라미터 자체는 고유값이지만 캘리브레이션 모델 자체가 근사적인 모델이기 때문에 사용한 이미지에 따라 최적 근사해가 달라질 수 있습니다.



8. 카메라 캘리브레이션 팁 (2015.5.12 추가)


카메라 캘리브레이션 팁도 간단하게 같이 적어봅니다. 카메라와 패턴과의 거리에 대해 문의를 많이 주시는데 패턴과의 거리는 최대한 가까울수록 좋습니다. 그 이유는 캘리브레이션 자체는 패턴과의 거리와 관계없지만 패턴과의 거리가 가까우면 영상에서 좀더 정밀하게 코너점의 위치를 찾을 수 있기 때문입니다. (경험적으로) 패턴 영상의 개수는 4개 이상이면 어느정도 캘리브레이션이 가능하지만 많을수록 좋으며 20장 이상 정도면 무난하다고 생각됩니다. 마지막으로 패턴 영상을 획득할 때에는 되도록 다양한 각도에서 영상을 획득하면 좋습니다.



관련 포스팅


by 다크 프로그래머

  • 이전 댓글 더보기
  • landing 2017.04.12 09:46 신고 ADDR 수정/삭제 답글

    안녕하세요.

    Dancingwith님 댓글에서 3D좌표를 얻기 위해 카메라 2대 사용해야하는 이유는 무엇인가요?

    제가 위 포스팅을 읽고 물체의 3D좌표를 얻는 과정에 대하여 이해한 바로는,
    =====
    1. calibration tool을 통해 카메라 매트릭스 A를 구한다.
    2. 월드좌표[X,Y,Z]-영상좌표[x,y] 쌍을 통해 [R|T] 매트릭스를 구한다.
    3. 이를 수식(1)에 적용해 (x,y)로부터 (X,Y,Z)를 구해 3D의 물체와 카메라 간 거리 혹은 물체 크기 등을 얻는다.
    =====

    포스팅 [영상의 기하학적 해석 - 영상의 지면 투영(ground projection)]에서 보면 카메라 1대로는 물체의 2D좌표인 지면좌표만(?) 찾을 수 있는 것 같은데요..

    수식(1)에서 월드좌표계는 3D이기 때문에 물체의 3D좌표를 찾을 수 있다고 생각한거랑 상반되어 혼란이 옵니다.

    2대 사용하여 3D좌표를 구하는것은 어느 포스팅에서 도움을 받을 수 있을까요? 그리고 혹시 카메라 2대 대신 카메라와 레이더를 1대씩 이용하는 것도 가능한지요.

    질문이 많은데 미리 감사드립니다.

    • BlogIcon 다크pgmr 2017.04.12 19:31 신고 수정/삭제

      아시겠지만 빛이 카메라에 맺혀서 이미지가 생성됩니다. 그리고 그 빛(ray)을 따라서 존재하는 모든 점들은 모두 같은 한 점으로 투영됩니다. 따라서 이미지 점을 가지고 원래의 3차원 점을 복원하는 것은 불가능합니다. 이미지 점에서 3D 점을 복원하기 위해서는 부가적인 정보가 필요합니다. 예를 들어 거리(depth) 정보 등이 필요합니다. 만일 카메라가 2대라면 삼각법을 이용해서 3D점까지의 거리(depth)를 구할 수 있습니다. 이러한 카메라를 스테레오 카메라라고 부릅니다. 본 블로그에는 삼각법 계산하는 구체적인 수식에 대한 글은 아직
      없습니다. 그리고 레이더는 카메라 없이도 그 자체로 3d 좌표가 나오는 것 아닌지요?

  • wk 2017.06.20 14:08 신고 ADDR 수정/삭제 답글

    안녕하세요 한가지 질문이 있어 댓글 남깁니다.
    현재 depth 카메라 캘리브레이션을 하고있습니다.
    우선 RGB 영상 캘리브레이션을 통해 intrinsic 과 coefficient 를 구하였고
    depth 영상 또한 구하였습니다.

    여기까지 완료가 되었다 하더라도, RGB와 depth 간의 extrinsic (R|t) 정보가 없다면,
    RGB의 (u,v) 좌표와 depth의 (u,v) 좌표가 같지 않을것 같은데, 맞나요..?

    • BlogIcon 다크pgmr 2017.06.20 16:05 신고 수정/삭제

      저는 depth는 안써봐서.. 아마 다를 것 같은데요, 둘 사이를 어떻게 캘리브레이션을 하는지는 잘 모르겠네요.

  • spector 2017.07.23 23:36 신고 ADDR 수정/삭제 답글

    안녕하세요.
    image plane 2d 좌표에서 world 좌표로 컨버팅하는 부분에대해 질문이 있습니다.

    월드좌표 Pw=[X,Y,Z]라고 했을때 이걸 camera coordinate system 으로 바꾸려면
    Pc=R*Pw+T 이고 이걸 카메라 intrinsic matrix를 이용해서 image plane으로 바꿀때
    Pc=[Xc,Yc,Zc] ->Pc'=[Xc/Zc, Yc/Zc, 1]=[Xc',Yc',1](식 a) 로 바꿔서 normalized image plane
    으로 보낸 후 Pi=[u,v]=K*Pc' 을 이용해서 이미지 좌표로 보내시잖아요?
    여기까지는 이해 했는데
    제가 영상의 이미지 좌표 Pi=[u,v]를 world cooridnate system으로 바꾸고 싶은데
    단안 카메라로 영상을 취득후 제가 알수 있는건 영상 좌표 Pi=[u,v]이고
    이걸 camera coordinate 으로 보내려면
    Pc'=inverse(K)*Pi where Pi =[u,v,1]
    이렇게 하면 된다고 이해했습니다.
    그런데 world coordinate 을 camera cooridnate으로 바꿀때 저는 위식(식 a)에서 Pc ->Pc'으로 바꾸는 과정에서 Pc=[Xc,Yc,Zc] 으로 Zc으로 나눈후에 intrinsic을 곱했는데 역으로 갈때는
    inverse(K)*Pi=Pc'는 구했는데 Pc'->Pc으로 어떻게 바꿔야 할지 모르겟습니다.
    월드에서 이미지로 올때는 Zc로 나눠줬는데 카메라 영상좌표만 가지고 Zc를 어떻게 복원해서
    Pc'->Pc로 바꿀수 있나요?

    • BlogIcon 다크pgmr 2017.07.24 08:26 신고 수정/삭제

      안녕하세요. 많이들 혼동스러워 하는 부분인데 결론은 '복원할 수 없다'입니다. 3차원의 점을 이미지에 투영는 것은 이 점과 카메라 원점을 잊는 직선이 이미지 평면과 만나는 교점을 구하는 것입니다. 그런데, 이 직선 위에 있는 모든 점들은 모두 동일한 이미지 좌표로 투영됩니다. 따라서, 이미지 좌표로부터 3차원 좌표를 복원하는 것은 수학적으로는 불가능합니다. 따라서, 이미지로부터 3차원 정보를 복원하기 위해서는 스테레오 카메라 등과 같은 삼각 측량법의 원리가 필요합니다.

  • BlogIcon DRAGONITE 2017.08.02 18:20 신고 ADDR 수정/삭제 답글

    안녕하세요 좋은 글 정말 감사합니다^^! 모든 카메라가 캘리브레이션 작업이 필요한 것인가요? 현재 노트북 웹캠으로 실험을 진행해보려합니다.. 올려주신 자료에는 보정전과 후의 동영상 파일이 많이 다른 것이 느껴집니다만, 대부분의 카메라가 보정전에 왜곡이 심한가요?

    • BlogIcon 다크pgmr 2017.08.03 15:13 신고 수정/삭제

      대부분의 웹 카메라는 굳이 왜곡 보정은 필요없다고 생각됩니다. 그런데, 카메라 캘리브레이션의 목적은 왜곡 보정보다는 대부분 영상을 기하학적으로 해석하기 위해서입니다. 예를 들어, 카메라 영상으로부터 물체의 3차원 정보를 복원하기 위해서는 카메라 파라미터(초점거리, 주점, 왜곡계수 등...)가 필요하고 이러한 파라미터를 구하기 위해 캘리브레이션을 수행합니다.

    • BlogIcon DRAGONITE 2017.08.03 16:00 신고 수정/삭제

      목적이 왜곡 보정보다는 대부분 영상을 기하학적으로 해석하기 위함이군요! 도움 주셔서 감사드립니다^^!

  • sampard 2017.08.10 13:09 신고 ADDR 수정/삭제 답글

    안녕하세요. 카메라 캘리브레이션 관련하여 행렬 연산에서 헷갈리는게 있어서 댓글 남깁니다..! LM = 0 행렬 연산에서 L은 12x12 이고 M은 12x1 행렬입니다. 이때, M이 0 이외의 다른 값을 가질 수가 있나요?

    • BlogIcon 다크pgmr 2017.08.10 13:38 신고 수정/삭제

      네 가질 수 있습니다. 식 Ax = 0가 있다고 했을 때, A의 역행렬이 존재하지 않으면 Ax = 0을 만족하는 0이 아닌 x가 존재합니다. 이러한 x는 A를 특이분해(singular value decomposition)했을 때, 0인 특이값(singular value)에 대응하는 특이벡터(singular vector)가 존재합니다. 특이값 분해에 대해서는 http://darkpgmr.tistory.com/106 글을, Ax = 0의 0이 아닌 해를 구하는 방법에 대해서는 http://darkpgmr.tistory.com/108 글을 참조하시기 바랍니다.

  • minx 2017.08.17 18:44 신고 ADDR 수정/삭제 답글

    영상 정보를 바탕으로 촬영한 피사체의 azimuth angle과 elevation angle을 계산해보려하는데, 다크프로그래머님의 글을 정말 많이 참고하고있습니다.

    현재 Gopro Hero4를 사용하고 있고, FoV를 Linear로 설정하여 캘리브레이션을 진행했습니다.
    일단 다른거 사용하지 않고 매트랩에 내장되어있는 어플리케이션을 사용했는데요,
    Optical Center를 표시할 때 픽셀좌표계의 원점을 어디에 두는가가 좀 중요하더군요.
    이미지의 픽셀좌표계의 원점을 좌상단으로 많이 두는것 같던데, 매트랩 내장 어플은 이부분에 대한 언급이 없네요...
    혹시 다크프로그래머님께서 직접 만드신 프로그램은 위에 이미지에 있는 좌표계들을 사용하여 만드셨는지요?

    • BlogIcon 다크pgmr 2017.08.18 11:48 신고 수정/삭제

      네, 픽셀좌표계의 원점은 항상 이미지의 좌상단 모서리로 잡습니다.

  • 쏘쏘 2017.08.21 13:11 신고 ADDR 수정/삭제 답글

    변환 관계 모델링식에서 필요한 내용인 내부파라미터(A), 회전/이동변환 행렬, 월드좌표계를 아는데 식대로 곱하였을때 스케일 값이 곱해진 이미지좌표가 나와야하는 것 같은데 왜 이상한 값이 나올까요?
    제가 뭔가 잘못 이해한 것인지.. 계산에 실수가 있었던 것인지 궁금합니다.

    • BlogIcon 다크pgmr 2017.08.21 13:30 신고 수정/삭제

      만일 약간의 오차가 난 정도라면 렌즈 왜곡보정이 포함되지 않아서이고, 오차가 전혀 엉뚱한 값으로 나온다면 계산에 실수가 있었거나 R, t 행렬의 값이 잘못 계산되었을 것으로 생각됩니다. 계산 과정에 문제가 없는지 하나씩 확인해 보시면 좋을 것 같습니다. 그리고 식 (1)은 렌즈 왜곡이 고려되어 있지 않습니다. 따라서, 광각카메라 등 영상왜곡이 심한 경우에는 왜곡 보정도 해야 합니다. 왜곡 보정에 대해서는 http://darkpgmr.tistory.com/31 글과 http://darkpgmr.tistory.com/77 글을 참고하시면 좋습니다.

    • 쏘쏘 2017.08.22 21:09 신고 수정/삭제

      감사합니다 매칭 값을 잘못넣어서 외부파라미터에 문제가 생긴 것 같더라구요.
      도로 탑뷰를 만들고 싶은데 식 1에서 s값이 스케일(배율)이라고 알고 있었는데 월드좌표를 입력해서 s가 곱해진 값을 받으면 s값이 매번 일정해야하는거 아닌가요? s값이 정확히 어떤 것을 의미하나요? 검색을 해보니까 다른 식에서는 s 자체를 생략했더라구요..

    • BlogIcon 다크pgmr 2017.08.22 22:49 신고 수정/삭제

      식 1에서 s는 그냥 스케일 상수이긴 한데, 굳이 해석을 하자면 s = 1/depth (depth는 카메라와 물체와의 z 거리)입니다. 따라서, 카메라로부터 멀리 떨어진(depth가 깊은) 점들에 대해서는 s가 작은 값이 나오고, 가까운 점들은 s가 높은 값이 나옵니다.

  • 질문있습니다. 2017.09.27 10:33 신고 ADDR 수정/삭제 답글

    내부파라미터는 카메라의 고유값이고 외부파라미터는 고유값이 아니라고 했는데 그럼 카메라의 위치 변화에 따라 발생하는 내부파라미터 변화는 최적화과정에서의 변화로 크게 신경쓰지 않고 고정된 값으로 사용해도 무방한가요??

    • BlogIcon 다크pgmr 2017.09.27 13:11 신고 수정/삭제

      카메라의 오토 포커싱 기능이 켜져 있을 경우는 파라미터가 변하지만 그렇지 않은 경우는 고정값을 사용하면 됩니다.

  • 자연산흑곰 2017.11.16 19:19 신고 ADDR 수정/삭제 답글

    '초점거리를 하나의 값으로 f라 표현하지 않고 fx, fy로 구분한 이유는 이미지 센서의 물리적인 셀 간격이 가로 방향과 세로 방향이 다를 수 있음을 모델링 하기 위함입니다' 라고 하셨는데
    여기서 나오는 '셀'이 어떤건지 이해가 안갑니다 ㅠㅠ

    질문 1) 이미지 센서에 대하여 구글링 해보니 CMOS에 나오는 셀인것 같은데 이것이 세로방향으로 많으면 이미지도 세로방향으로 더 정밀하게 받아들일수 있다고 이해하면 될까요??

    질문 2) 질문을 어떻게 해야할까 생각해보다가 그냥 직관적으로 적어보겠습니다.
    응?fx, fy는 뭐지? -> 그렇다면 일반적인 포컬렝스는 fz가 되겠지? ->
    포컬렝스 fz는 이미지 센서와 렌즈까지의 거리니깐 z축에 따라 움직이는 값 ->
    그럼 fx, fy는 x축 y축으로 움직이는건가? -> 읭? fx,fy는 셀에 따라 다르게 적용된다고? ->
    그러면 fz는 셀의 두께를 나타내는건가? -> 그럼 내가 아는 fz는 다른 의미였나?? -> 셀의 두께에 따라 렌즈 거리가 달라지는건가?? ->!@#@~$~@$$

    제가 이해한대로라면 영상좌표계의 x좌표는
    Xcam = (Fx*Xw) + Cx(밑첨자를 구분하기 위해 위해 대문자를 섞었습니다)인지
    아니면 Xcam = (F*Xw) + Cx 인지 잘 모르겠습니다. Fx와 Fy의 존재를 어떻게 받아들여야 할지 잘 모르겠습니다

    • BlogIcon 다크pgmr 2017.11.16 22:12 신고 수정/삭제

      혹시 카메라 내부를 본 적이 있으신지요? 안에 이미지 센서가 있는데 이미지 센서는 격자 형태의 셀의 배열로 이루어져 있습니다. http://titerced.blog.me/100043573606 에 있는 동영상을 보신 후 http://darkpgmr.tistory.com/97 글도 같이 읽어보시면 이해에 도움이 될 것 같습니다.
      질문 1) -> 네 그렇습니다.
      질문 2) -> 초점거리(f)는 물리적으로 이미지 센서와 렌즈 중심까지의 거리입니다. 이 거리를 픽셀단위로 바꾸기 위해 이미지 센서의 가로 방향 셀 간격(물리적 간격)으로 나눈 값이 fx입니다. 그리고 세로 방향 셀 간격으로 나눈 값이 fy 입니다. fz라는 것은 따로 없습니다. ^^
      일단 여기까지 보시고 또 추가적으로 궁금한 사항이 있으면 질문 주세요.

    • 자연산흑곰 2017.11.17 18:21 신고 수정/삭제

      자주 느끼는것중 하나가 '이해했던 내용을 두가지로 나누는것은 정말 어렵다' 입니다. 여태 카메라 캘리브레이션은 곧 lens distortion을 제거한 영상이라고 생각했었는데 다른것이였네요....
      나름 서칭해가며 공부를 해본 결과 링크(https://kr.mathworks.com/help/vision/ug/camera-calibration.html?s_tid=gn_loc_drop)에서 나온것같이 캘리브레이션을 진행하려면 3D좌표와 이에 대응하는 2D 좌표를 알고 있어야 합니다. 저도 그렇게 생각하는것이 실제 영상 좌표와 월드 좌표가 변환행렬을 통하여 계산되었을때 어느정도 수긍할만한 범위 안에서 결과값이 같아야 할테니깐요. 여기서 궁금한것이 3D월드 좌표는 어떻게 알아내야 하는것입니다. 실제로 자를 가지고 거리를 재야하는지, 아니면 다른 방법이 있는지 궁금합니다!

    • BlogIcon 다크pgmr 2017.11.18 15:26 신고 수정/삭제

      네, 그래서 캘리브레이션을 할 때에는 미리 크기를 알고 있는 체스판 등을 사용합니다. 체스판의 평면을 z = 0인 평면, 한쪽 꼭지점을 원점, 그리고 체스 격자 크기를 미리 알고 있으면 격자 꼭지점들의 월드 좌표를 계산할 수 있습니다.

  • 비숍 2017.11.23 20:10 신고 ADDR 수정/삭제 답글

    안녕하세요.
    저는 비젼 분야는 아니지만 RS/GIS 분야에서 일을 하면서 어렵게 알게 되었던 내용을 이렇게 쉽게 정리해 주시니 존경스럽네요. 아직도 모르는 것이 많아 이곳에서 큰 도움을 받고 있습니다. 오랜기간 동안 꾸준히 블로그를 관리하시는 것도 대단하시고요. 감사합니다.^^

  • 나사 2017.12.08 16:15 신고 ADDR 수정/삭제 답글

    안녕하세요
    처음 수식인 카메라 모델 행렬에서 궁금한게
    s가 즉 스케일로 표시하셨는데 s는 Z와 같나요?
    비례식으로 보면 x/f = X/Z 이고 이는 xZ = fX 가 되므로, s가 Z인거같은데 맞는지요?
    https://en.wikipedia.org/wiki/Camera_resectioning
    위키에서는 s가 카메라 좌표의 Z_c 로 되있는데, 이부분때문에 헷갈립니다.

    • BlogIcon 다크pgmr 2017.12.08 18:20 신고 수정/삭제

      네, 저도 계산을 해 보니 위키에 있는 수식대로 s는 Z_c가 맞습니다. 월드좌표 (X, Y, Z)를 [R|t]에 의해 회전, 평행이동시키면 카메라 좌표(Xc, Yc, Zc)가 나오고, 이후 비례관계에 의해 s = Zc가 됩니다.

  • 항상 감사합니다 2017.12.31 20:18 신고 ADDR 수정/삭제 답글

    안녕하세요 다크프로그래머님 항상 좋은 내용들 정말로 감사드리고 많은 공부가 되고있습니다

    제가 이해한게 맞는지 한번 여쭙고자 이렇게 댓글을 남기게 되었습니다.
    Calibration 이라는것이 내부 파라미터를 구하는 것이고,
    이렇게 구한 파라미터들을 가지고 Backward Warping을 해서 왜곡 보정된 영상을 구하는 것이라고
    생각을 하는데 이게 맞게 이해한건지 궁금합니다 !!
    제가 캡스톤 당시 카메라 담당이 아니어서 잘은 모르는데,
    저희가 Pi camera I(아이)를 사용했는데 이게 어안렌즈가 장착된 카메라입니다.
    카메라 담당 친구가 GML툴을 사용해 파라미터를 얻은뒤 Open CV내의 fisheye 어쩌구 함수에 인자를 넣으니 왜곡 보정된 사진이 나왔다고 하는데,
    다크님께서 직접 툴을 만든 이유가 어안렌즈는 GML이나 Open CV에서 지원이 안된다고 해서 만드셨다고 했는데 그러면 저희가 한 방식이 잘못된거인걸까요 .. ? 결과는 잘 나왔었습니다 !!
    한번 제가 알고 있는 내용들을 점검해주시면 정말 감사하겠습니다 !!

    • BlogIcon 다크pgmr 2018.01.02 08:48 신고 수정/삭제

      잘못된 것 없고 잘 하셨습니다. 서울까지 가는 길이 한 가지 길이 아니듯이 카메라 왜곡 모델(수식)도 여러 가지 모델이 있습니다. opencv에 있는 카메라 모델도 그 중 한 가지이구요. opencv에 있는 모델로도 어안렌즈 모델링 잘 되니 지금처럼 사용하시면 됩니다.

  • 항상 감사합니다 2018.01.02 11:18 신고 ADDR 수정/삭제 답글

    확인해주셔서 감사합니다 !!
    정말 많은 도움이 되는것 같습니다 ㅜㅜ

    그렇다면 그 내부의 파라미터를 구하는 과정은 찾아봐도 잘 안나오는거 같은데 ..
    혹시 내부파라미터를 구하는 과정은 따로 어떤식으로 진행되는지 알 수 있을까요 ?
    추측을 해보자면 영상에서 키포인트들을 얻어내 매칭을해서 그 값을 계산하는게 아닐까 싶은데 ..
    혹시 어떤식으로 하는지 알 수 있을까요 ..!?

    • BlogIcon 다크pgmr 2018.01.02 12:12 신고 수정/삭제

      opencv나 gml에 있는 캘리브레이션 방법은 Z. Zhang. “A Flexible New Technique for Camera Calibration”, IEEE Trans. Pattern Analysis and Machine Intelligence, 22(11):1330-1334, 2000 논문의 방법을 구현한 것입니다. 자세한 내용은 논문을 보셔야 합니다. 간단한 것은 없습니다..

  • 항상 감사합니다 2018.01.02 13:42 신고 ADDR 수정/삭제 답글

    오 .. 확인해주셔서 감사합니다 !!
    알려주신 논문 참조해보도록 하겠습니다 !!
    다크님의 말처럼 요행을 바라지 않고 정도를 걷겠습니다 !!

    친절하게 답변해주셔서 내용을 정리하는데 큰 도움이 되었습니다 !!
    정말 다시한번 진심으로 감사드립니다 !!
    새해복 많이 받으시고 항상 좋은일만 가득하시길 바라겠습니다 !!

  • 333 2018.02.05 15:32 신고 ADDR 수정/삭제 답글

    여기서, (X,Y,Z)는 월드 좌표계(world coordinate system) 상의 3D 점의 좌표, [R|t]는 월드 좌표계를 카메라 좌표계로 변환시키기 위한 회전/이동변환 행렬이며 A는 camera matrix입니다.
    ---------------------
    라고 하셨는데
    https://kr.mathworks.com/help/vision/ug/camera-calibration.html
    https://en.wikipedia.org/wiki/Camera_resectioning
    이 링크에서는 내부행렬과외부행렬을 합쳐서 camera matrix라고 하는 것 같습니다...?
    어떻게 정리를 하면 좋을까 고민되어 질문드립니다.

    • BlogIcon 다크pgmr 2018.02.06 23:29 신고 수정/삭제

      답변이 늦었습니다. 말씀하신 내용이 맞습니다. 용어를 잘못 사용해서 혼동을 드린 것 같습니다. 그리고 제가 잘못 인지하고 있던 부분을 알려주셔서 정말 감사합니다. 덕분에 배움이 하나 더 늘었습니다 ^^ (본문은 수정토록 하겠습니다)

  • wjd 2018.02.12 21:16 신고 ADDR 수정/삭제 답글

    안녕하세요. 이 쪽 분야를 새롭게 공부중인데 궁금한게 있어서 질문드립니다.
    camera calibration toolbox를 이용해 나온 결과값에서 focal length의 단위는 무엇인지 알 수 있을까요..? 1000단위여서 크다고 생각해서 질문드립니다~~!^^

    • BlogIcon 다크pgmr 2018.02.13 17:34 신고 수정/삭제

      focal length의 단위는 픽셀(pixel)입니다. 이미지의 한 픽셀은 이미지 센서의 한 셀(cell)에 대응됩니다. 초점거리가 1,000 픽셀이라고 하면 물리적인 의미로는 이미지 센서에서 1,000 셀 정도의 길이에 대응되는 값이라고 해석하면 됩니다.

  • dancing 2018.03.16 14:03 신고 ADDR 수정/삭제 답글

    안녕하세요 다크님 항상 글 잘보고있습니다.
    초점거리에서 fx 와 fy , f 에 대해서 궁금한점이 있습니다.
    f : 초점거리로 pixel로 표현된다고 하셨고,
    fx, fy 는 image cell(mm) / pixel 각각 x 축 y 축을 기준으로 계산하는데,
    calibration 결과에서 나오는 fx, fy 나오는 값이 초점거리 f 값과어떤 상관이 있나요?
    잘이해가 안가서 질문드립니다.

    • BlogIcon 다크pgmr 2018.03.17 19:30 신고 수정/삭제

      안녕하세요. 초점거리에 대한 설명을 일부 보완하여 본문에 추가했습니다. 지금보니 이전의 설명이 부족한 면이 많아서 이해하기 어려웠을 것 같습니다. 새로 수정된 내용을 한번 보시고 의문이 남는 부분에 대해서는 다시 댓글을 남겨주시기 바랍니다. ^^

  • 나그네 2018.03.28 20:19 신고 ADDR 수정/삭제 답글

    좋은글 잘보고 갑니다.

    일반적인 프로그램으로 나타나는 초점거리는 전부 픽셀이였군요.. 잘못알고있었네요.
    그리고 캘리브레이션 결과로 나오는 Rt 는 월드좌표계에서 카메라좌표계로의 변환인건가요?

    • BlogIcon 다크pgmr 2018.03.28 20:46 신고 수정/삭제

      네, 그렇습니다. 카메라좌표 = R*월드좌표 + t

  • SUPERSAM 2018.04.05 17:32 신고 ADDR 수정/삭제 답글

    안녕하세요~~ 카메라 관련 글 잘 보고 있스니다.
    스테레오 카메라의 경우, CenterX, CenterY, Height, Tilt 값은 용어가 무엇을 의미하나요?
    Baseline 은 두 렌즈사이의 거리라는 것이 인터넷에서 쉽게 찾을 수 있는데, 나머지 용어는 찾기 어렵네요..

    • BlogIcon 다크pgmr 2018.04.06 01:15 신고 수정/삭제

      스테레오 카메라에 그런 용어가 따로 있는지는 저도 잘 모르겠습니다. height는 카메라의 높이, tilt는 카메라의 틸트(수직 방향으로 회전한 각도)를 말하는 것이 아닐까요?

  • hyemin 2018.04.23 17:58 신고 ADDR 수정/삭제 답글

    안녕하세요 캡스톤 수업을 위해 카메라 캘리브레이션에 관하여 조사를 해보다가 다크님의 블로그를 보게되었습니다. 이 본문글을 읽다가 의문이 생겨 댓글 남깁니다. 일단 전공분야가 아니여서 배경지식이 부족해 글을 이해하는데 도움이 필요해 질문하게되었습니다.
    프로그램을 사용해 rms,fx,fy,cx,cy,w 를 구하였는데 결국 이 값들은 무엇이며 무엇을 하려고 구한건지,어떻게 보정을 해야하는건지 궁금해서 댓글 납김니다ㅠㅠ

    • BlogIcon 다크pgmr 2018.04.23 22:38 신고 수정/삭제

      카메라 파라미터(fx, fy, ...)들은 영상에서 기하학적 정보를 추출하기 위해 필요한 카메라의 기구적 특성값들입니다 (예: http://darkpgmr.tistory.com/153). 만일 기하학적 해석이 필요치 않다면 굳이 카메라 캘리브레이션을 할 필요는 없습니다.