정보공간_1

[2기 광주 박이근] 카메라 보정 본문

IT 놀이터/Elite Member Tech & Talk

[2기 광주 박이근] 카메라 보정

알 수 없는 사용자 2012. 10. 22. 13:11

안녕하세요 

광주멤버십 21-2기 박이근 입니다.

카메라 보정 에 대해서 알아보려고 합니다.



먼저 핀홀카메라 모델에 대해서 알아보자!
핀홀이란 종이에 핀으로 뚫은 구멍 같이 매우 작은 구멍을 뜻합니다.



핀홀카메라가 왜 중요한가요 ?
일반적으로 바늘구멍 사진기라 하며 
물체에 반사된 빛이 우리 수정체를 거쳐서 망막에 도달하는 구조를 가장 잘나타내기 때문에
핀홀 카메라 모델에 대해서 알아보려고 합니다. 




일반 카메라와 핀홀카메라는 무슨차이가 있죠?

핀홀카메라는 
빛이 아주 작은 구멍을 거쳐서 들어오기 때문에 빛을 모으기에는 부적합 하다..
하지만  정확한 영상을 얻을 수 있습니다.

일반적인 카메라는
핀홀 부분 즉 작은 구멍부분에 렌즈를 사용한다. 그래서 빛을 모으기 적합하다.
하지만 렌즈를 사용함으로써 렌즈 자체에 왜곡으로 인하여 영상이 손상된니다.

그래서 우리는 일반 카메라에서 이 렌즈의 왜곡을 줄여주는 작업이 필요한 것입니다.




아 그럼 핀홀카메라가 어떻게 생겼는지 알아야 겠네영 모델에 대해 설명해주세요 !

핀홀 카메라 모델은 아래 그림과 같다. 



 3차원 실세계 객체 위의 한 점에서 빛이 발산 되면 그 중 하나의 광선만이 핀홀을 통과하게 된다.
 이렇게 핀홀을 통과한 광선은 영상평면에 투영이 되어 
영상평면 또는 투영 평면이라 불리는 곳에 영상이 맺히게 되다. 

 여기서 객체가 영상에서 얼마만한 크기로 상이 맺히는 지는 
핀홀 카메라의 초점 거리에 의해 결정되게 된다. 
이상적인 핀홀 카메라일수록 핀홀구멍으로 부터 영상 평면까지의 거리가 초점거리가 되는 것이다.

핀홀카메라의 초점거리(f)
카메라와 물체 사이의 거리 (z)
실제 객체의 크기 (X)
영상 내의 객체크기 (x)

삼각형의 성질에 의해서  -x / f = X / z
위의 식인  -x  = f * (X / z) 를 구할수가 있다.




실제로는 구성할 수 없지만 수학적인 성질을 이용하여 핀홀과 영상 평면의 위치를 바꿔보자 !

럼 아래 그림과 같이 핀홀의 오른편에 상이 맺히게 되고 역상이 아닌 똑바로의 선형태의 영상이 형성된다.
바늘 구멍은 투영중심의 역할을 하게 된다.

 



그러면 삼각형의 관계를 이용하면 x/f = X /Z 의 수식을 얻을 수가 있다.
3차원 공간상의 한 점 Q = (X, Y, Z)에서 출발한 빛은 투영 중심을 향해 직진하면서 영상 평면을 만들어 낸다.
그때 이점을 q = (x, y, f)로 표현을 하게되며 영상의 평면이 핀홀 앞으로 이동하기 때문에 음수는 사라진다.


여기 그림에서 광축과 영상의 평면이 만나는 주점(Principle Point )가 항상 카메라 센서의 중심에 위치 할 수 없다.
실제적으로 이는 1/100만분 정도로 중심을 맞추기 어렵기 때문이다. 
그래서 투영 평면에서 좌표중심의 이동 변위를 표현하기위해서는 새로운 매개변수인 (Cx, Cy) 를 사용해야한다.
새로운 매겨변수를 추가하여 영상 평면에 맺히는 좌표는 다음을 통하여 표현을 할 수 있다. 

 여기서 두 개의  초점 거리(fx, fy)를 사용한 이유는 대다수의 영상 센서의 개별 픽셀들이 정사각형이 아니기 때문이다.



예를 들어보면
 초점 거리 fx 와 fy 는 렌즈의 실제 초점 거리에 영상 센서의 개별 요소의 크기인 Sx Sy를  각각 곱한 값이다.
여기서 Sx, Sy의 단위는 픽셀 / 밀리미터 이다
fx 와 fy 역시 F 는 밀리미터를 사용하기 때문에 픽셀단위를 가지게 된다.
Sx 가 카메라 보정과정에서 직접적으로 측정을 할 수 없다.

여기서 중요한건 Sx, Sy 가 카메라 보정 과정에서 직접적으로 구할수 없다는것
그리고 물리적 초점 거리 F 또한 직접적으로 측정할 수 없다는 것이다.





다음으로는 투영변환에 대해서 알아보겠습니다 

투영변환이 무엇인가요 ?

실세계의 한점 Q = (X, Y, Z)는 3차원의 점이다 
이 점이 앞시간에서 배웠던 투영 스크린 상의 한 점 (X, Y)로 2차원 점으로 
변환되는 관계를 투영 변환이라 한다.



이렇게 투영변환을 사용할 때는 동차 좌표계라고 알려진 좌표계를 사용하는게 편하다. 




그럼 동차좌표계가 그럼 무엇인가요?

3D에서는 기본적으로 3차원좌표계이지만 이것을 어떤 목적으로 4차원으로도 확장이 가능하다.
이렇게 어떤목적을 위하여 한 차원의 좌표(n) 을 한차원 추가된 좌표  (n+1)로 표현을 하는 것을 동차 좌표계라 한다.

예를 들자면 
3차원 좌표 (x, y, z)는 
4차원 좌표 (x, y, z, w)형태로 표현 한다는 것이다.
기본적인 성분 x y z 에 w가 추가된것으로 3D 상에서는 x/w y/w z/w로 나타낸다.





투영행렬에서 동차좌표를 사용하는 이유가 무엇인가요?

시점으로 보이는 점들의 위치가 중요한게 아니라 시점으로 부터 방향이 중요하기 때문이다.

그림을 보자

 

투영행렬에 대한 이론을 간략히 설명한 것이다.
우리가 원하는 것은 3차원의 점들이 
2차원 평면인 빨간 네모안에 다 모인다는 것이다.




다음 그림은 점들의 위치가 서로 다른 3차원 점이 2차원에 투영되는 점은 결국 하나가 되버린다느는 것이다.
그래서 시점으로부터 방향이 중요한 것이 무엇인지 이해할 수 있다.





3D에서도 동차좌표를 사용하던데 ?

동차좌표계가 있음으로 오브젝트의 이동을 행렬간의 곱셈으로 표현이 가능하다.
이동, 크기, 회전을 모두 담은 행렬은 최소 4X4 행렬일 수 밖에 없다.
이 행렬과 정산적인 연산을 하기 위해서는 벡터도 행렬이므로 1X4 또는 4X1의 행렬 형태를 맞춰야한드는 것이다.

포인트(w=1)과 벡터(w=0)을 가늠할 수 있는 기준이 되기도 한다.

동차좌표는 방향과 점의 구분시켜준다.
x,y,z의 3차원 좌표계 구조체는 이게 점인지 방향인지 구분이 모호하다.
그래서 동차 좌표계가 포함된 4차원 좌표계로 표현하면 (0은방향 1은 위치)로 표현할 수 있다.


0은 방향을 의미하는 벡터로  
위치,방향으로서 서로 다른 벡터인지 구분이 가능
(방향벡터가 방향이 같고 위치가 다르다라는 것은 확대 또는 축소인 상태)

1은 위치를 의미하는 벡터로
위치가 서로 다른 벡터인지 구분이 가능

0의 동차항을 가지는 벡터는 확대, 축소, 방향변경이 가능하다.
1의 동차항을 가지고 있는 벡터는 이동(위치변화)가 가능하다.

0의 동차를 가지는 벡터는 1~3행
1의 동차항을 가지는 벡터는 4행





그럼 동차좌표계를 어떻게 구하는 가요?

동차좌표계 상 변환된 좌표 = p * 월드행렬 * 뷰행렬 * 투영행렬
투영행렬에서 카메라공간상에 존재하는 점과 카메라 위치사이의 깊이 z를 최종 결과점 x y z 에 각각 곱해지고 w에 저장되는데 바로 이 과정이 동차좌표계를 위한 과정이다.

해당 좌표공간(카메라 공간, 투영공간, 월드 공간)에서 3D 좌표를 얻어내려면 w로 나눠댄면 된다.
여기서 월드공간과 카메라공간에서는 w값이 항상 1이기 때문에 변화가 없지만
투영공간에서는 w값이 카메라 공간에서의 카마레위치에서 부터 정점사이 거리이기 때문에 z값에 따라 정점의 위치와 크기가 변환되는 것임을 짐작할 수 있다.





그럼 우리가 사용하는 이미지카메라 모델의 경우?
 
영상 평면이 투영공간이 되고 이는 2차원 평면이다.
때문에 동차 좌표는 q = (q1, q2, q3)로 표현할 수 있다.
투영공간에서 비례하는 점은 모두 동일 하므로 q1과 q2를 q3로 나누어 줌으로 써 실제 2차원 픽셀 좌표를 얻을 수 있다.

동차 좌표계를 사용하면 fx fy cx cy 등의 카메라 파라메터를 3X3 크기의 행렬 하나로 표현 할 수 있다.
우리는 이 행렬을 카메라 내부행렬이라 부른다.

카메라 내부행렬을 표현하는 방법은 Heikkila 와 Silven의 논문을 참고해보면된다.
(A Four-step Camera Calibration Procedure with Implicit Image Correction)

이제 실세계의 한점이 카마레라로 투영되는 관계는
다음과 같은 간단한 행렬 연산으로 표현이 가능하다.



위행렬을 실제로 곱해보면 w = Z가 되고 
점 q는 동차 좌표계로 표현되어 있기 때문에 x와 y좌표값을 Z로 나누어야 원래 좌표를 얻을 수 있따.






그럼 OpenCV에서는 이를 제공해주는 함수는 없나요?

일반 좌표계를 동차 좌표계로 변환하는 cvConvertPointsHomogenious() 함수를 제공하고 있다.

void cvConvertPointsHomogenious(const CvMat* src, CvMat* dst)
일반좌표계를 동차 좌표계로 서로 호환이 가능하다.

입력 Scr 과 dst 의 행렬 차수가 서로 같은 경우 내부 데이터는 단순히 복사되며

행렬차수가 Scr > dst 이면
dst행렬의 원소들은 src 행렬에 저장된 벡터의 맨 마지막 원소로 나머지 원소값들을 나누어 계산된다.

행렬차수가 scr < dst 이면
점들이 모두 복사되면서 dst배려에 있는 모든 벡터의 마지막 원소에 1이 추가된다.


참고 문헌

[1] OpenCV 제대로 배우기 개리 로스트 브라드스키 저 / 황선규 역 / 한빛미디어