정보공간_1

[2기 강남 이인표] 증강현실의 이해 II 본문

IT 놀이터/Elite Member Tech & Talk

[2기 강남 이인표] 증강현실의 이해 II

알 수 없는 사용자 2012. 9. 16. 15:39

안녕하세요? 엘리트멤버십 2기 이인표 입니다.

이번에는 지난번 증강현실의 기초 I에 이어서 내용이 진행될 것입니다.

지난번 포스팅에서 이론에 대한 내용이 주였다면 이번에는 실제로 그것을 적용시키는 방법을 다뤄볼까 합니다.

자 그럼 이제 시작합니다.

우선 우리는 OpenCV와 OpenGL을 사용하여 구현을 해보도록 하겠습니다.

OpenCV 2.4 설치 : http://openshareit.tistory.com/category/OpenCV

(위의 블로그를 참조하세용~~~)

 

 

1. 마커에 대한 이해

마커는 평면기하를 표현하는 좋은 표식입니다. 보통 증강현실이라 하면, 아래와 같이 생긴 마커들을 사용하죠?

 [그림 1] 마커 예시

마커라는 것은 평면 기하의 정보를 함축하고 있죠... 스케일, 회전, 이동 등...

따라서 마커의 정의가 중요합니다. 위의 그림1에서 볼 수 있듯이 다양한 모양의 마커들이 사용되고 있으며,

모양이 좀 이상하더라도 모두 가지고 있는 뜻이 있습니다. 하지만 대부분의 마커는 4각형의 모양을 하고 있죠..

지난번에 배운 호모그래피와 관련이 있습니다.

자 그럼 마커를 찬찬히 뜯어 보도록 합니다.

 

1.1. 일반적인 마커

다음의 마커를 보도록 합시다.

 

 [그림 2] ARToolKit 마커

그림 2의 마커는 ARToolKit에서 주로 사용되는 마커입니다. 자세히 보면 검은색 두꺼운 사각형 테두리에

흰색 속을 가지고 있고, 그 안에는 Hiro라는 알파벳이 쓰여져 있습니다.

자, 저 마커의 모습을 잘 살펴보시길 바랍니다. Hiro라는 글자는 사각형의 아랫쪽 면에 붙어있죠..

저것은 회전에 관련된 파라미터를 담당하는 것입니다. 모든 마커가 그렇다는 것은 아니지만,

컴퓨터가 마커의 회전을 알기 위해서는 영상에서 정보가 필요합니다. 그래야 컴퓨터가 자동으로

마커를 인식할 수 있겠죠?

마커의 크기는 카메라와 마커(보통 마커의 중심을 실제 세계의 중심으로 놓습니다) 사이의 스케일을

담당합니다. 화면에 마커가 작게보이면, 그 마커는 카메라로부터 멀리 있는 것이겠죠? 다르게 말하면,

실제 세계의 중심에서 카메라가 얼마나 떨어져 있는지 그 정도를 나타냅니다. 지난번 포스팅을 상기하여

다시한번 생각을 해보면, 마커의 실제 세계에서의 크기를 알고있고, 카메라를 통해 입력된 영상에서

그 마커간의 대응관계를 알고있다면, 비례식에 의해 실제 카메라와의 거리를 구할 수가 있죠.

마커는 이와같이 회전과 크기에 대한 정보를 가지고 있습니다. 자, 그럼 우리만의 마커를 만들어 봅시다.

 

1.2. 실험에 사용할 마커

[그림 3] 컬러 기반의 마커

 

우리는 그림 3에 표시한 마커를 사용하겠습니다. 사각영역의 한쪽 모서리가 붉은색이죠? ㅋㅋ

저게 회전에 대한 정보를 담당하는 부분이 되겠습니다. 마커의 물리적 크기를 알고, 회전에 대한 정보를

포함하고 있으니, 마커의 조건을 충족하고 있습니다.

(사실 가장 중요한 조건인 유일하다는 조건은 만족시키지 않지만, 우리는 기초를 배우는 단계이므로.. 생!략!)

간단하게 마커를 인식하기 위해서 마커를 구성해 보았어요..

마음에 안드신다면.. 오늘의 내용을 바탕으로 다르게 만들어 보시면 되겠습니다. ^^

제가 오른쪽과 아랫부분에 명시를 해놓았죠? 저게 실제 세계에서 마커의 사이즈가 되겠습니다.

그럼 이제는 실제로 마커를 인식하는 방법을 살펴보도록 하겠습니다.

 

1.3. 마커와 영상평면의 대응관계

마커를 인식하는 방법은 몇가지가 존재합니다. 우리는 간단하게 Blob Labeling을 통해 잡영제거 및

마커영역을 검출하고 인식하는 방법을 보도록 하겠습니다.

우선 Blob Labeling은 http://martinblog.tistory.com/826 (존경하는 마틴님이시죠^^)를 참고하시면 되겠습니다.

간단하게 설명을 드리자면, 레이블링이란 자신이 원하는 영역을 분할하는데 쓰이는 기법으로 

영상공간내에서 어떤 특징을 가지는 덩어리들을 분류하는데 사용하는 기법입니다. 우리가 찾고자 하는 영상 내

영역이 색상이 될 수도있고, 특정 모양이 될 수도 있죠. 이런 것들은 찾고 분류하는데 보편적으로 사용되는

전처리 기법이 바로 레이블링입니다. 다시 우리의 테마로 돌아갑시다.

이쯤에서 처리 순서를 정리해 볼게요.

 

 [그림 4] 마커 인식 순서도

그림 4를 통해서 보실 수 있는 내용은 Blob labeling을 수행하고, 실제 세계의 마커와 매칭을 위한

4개의 코너 포인트를 찾고, 매칭, 그리고 그 관계를 이용하여 호모그래피를 계산합니다.

호모그래피는 최소 4개 포인트 이상의 대응관계가 존재해야 계산이 가능하므로 사각의 마커가 적합합니다.

코너 포인트도 찾기가 쉽고...

그리고 대응관계를 계산할때 마커에 붉은 영역을 넣은 이유를 알 수 있습니다. 그것은 대응관계에 있는

포인트들의 순서가 곧 회전을 의미하기 때문이죠.

아래의 그림을 볼까요?

 

 [그림 5] 코너의 대응관계

그림 5에서는 색깔별로 올바르게 매칭된 것을 나타내고 있습니다. 왼쪽이 실제 세계에서의 마커의 자세이고,

오른쪽의 그림은 카메라를 통해 마커가 영상 평면으로 투영된 것이라고 할 수 있습니다. 보시면, 왼쪽의 마커와

오른쪽의 마커와의 크기가 다르고, 회전각도가 다르죠. 즉, 카메라가 실제 마커의 위치로 부터 얼마만큼

회전하여 얼마만큼 이동해 있다는 것을 알 수 있습니다. 우리는 마커의 실제 사이즈를 알고 있으므로,

만약 마커의 중심이 실제 세계의 중심인 (0, 0, 0)이라고 할때, 붉은 코너가 있는 모서리부터 시계방향으로

P1(-40, -40, 0),P2(40, -40, 0), P3(40, 40, 0), P4(-40, 40, 0)이라고 할 수 있고, 이미지상에서 위의 과정을

통해서 마커의 네 꼭지점을 구했을때 프로그램 상으로 마커의 꼭지점이 입력된 순서대로 이미지의 입력순서를

넣고, 강력한 OpenCV Library의 힘을 빌려 호모그래피를 계산할 수 있습니다.

코드를 보겠습니다.

위에서 world_pt라는 변수가 실제 세계에서 마커가 가지고 있는 정보를 설정한 것이 되겠습니다.

그리고 image_pt가 카메라를 통해서 영상에 사영된 코너 포인트들의 좌표가 되겠습니다.

그리고 계산될 호모그래피를 담을 3 by 3 크기의 행렬인 MatHomography가 있지요..

(Vision 분야에서는 계산의 편의를 위해서 포인트들을 행렬에 담아서 계산을 합니다.)

그리고 맨 밑에는 cvFindHomography()라는 함수가 있습니다. 이 함수는 실제 세계와 영상평면의 대응관계를

이용하여 호모그래피를 계산해 주는 역할을 합니다. 여기서 실제 세계의 포인트와 이미지 포인트의 위치가

바뀌게 되면 이미지에 있는 점이 실제 세계로 사영되는 행렬을 구할 수 가 있고, 위와 같이 계산을 하게 되면

실제 세계에 있는 점이 이미지에 사영되는 행렬을 구할 수가 있습니다. 그리고 네번째 인자의 자리에

"CV_RANSAC"이라는 파라미터가 입력되어 있습니다. 이것은 호모그래피를 구하는 방법 중에서 재사영 에러

(Reprojection Error)를 줄이기 위한 알고리즘으로 여기서는 호모그래피 계산을 위해 사용되고 있습니다.

(호모그래피는 2차원 사영기하에서 매우 중요한 개념이기 때문에 많은 연구가 되었고, 계산하는 다양한 방법이

존재합니다.)

그리고 마지막 인자는 RANSAC 알고리즘이 수행되면서 허용할 수 있는 오차(error)를 나타내며 입력된

수치보다 작다면, inlier(계산에 포함해도 좋은 포인트)라고 판단할 수 있습니다.

지난번에 포스팅한 자료의 대부분이 바로 저 함수 하나로 간단하게 끝이 나는군요...(ㅜㅜ)

 

 

2. 카메라 외부 파라미터(Camera Extrinsic Parameters) 계산

자, 그럼 이번에는 지난번 포스팅의 내용을 기반으로 카메라의 외부 파라미터를 계산해 보도록 하겠습니다.

 

2.1. 호모그래피에서 카메라 외부 파라미터 계산

호모그래피는 2차원 평면사이의 사영관계를 나타내는 행렬입니다. 영상평면과 실제 세계의 평면사이의 관계가

호모그래피를 통해 정의될 수 있기 때문에 호모그래피는 2차원 사영행렬이라고 말할 수 있고, 우리는 이것을

이용하여 카메라의 위치를 알 수 있습니다(지난번 포스팅 '증강현실의 이해 I' 참조).

코드를 봅시다.

m_vecRotX, m_vecRotY는 각각 입력된 포인트의 X축, Y축에 곱해지는 호모그래피의 각 열을, m_vecTrans는

호모그래피에서 이동에 관련된 열을 따로 저장하고 있습니다. 그 이유는 호모그래피는 직교 정규 행렬이므로

Z축과 관련된 값을 복구하기 위해서는 X와 Y축 관련 열들을 외적해야 하기 때문입니다.

그리고 맨 밑에 있는 3줄의 코드는

위의 식에서 A(Camera Intrinsic Parameters)를 제거해주기 위해서 A의 역행렬을 곱해주고 있습니다.

여기까지 수행하면, 각 벡터들은 이동과 회전에 대한 값만을 가지게 되죠.

위의 코드를 보면 lamda라는 것을 계산하고 위에서 구한 각 벡터들에 그 값을 곱해주는 것을 볼 수 있습니다.

그리고 cvCrossProduct()함수를 통해 Z값과 관련된 벡터를 계산하고 있는 것이죠.

 

바로 증명된 위의 수식들의 내용에 근거하여 말이죠..

자, 이와 같은 단계를 통하여 우리는 카메라의 외부 파라미터(External Parameters)를 모두 구하게 되었습니다.

자 그럼 이것을 이용하여 우리는 OpenGL상에서 가상의 월드를 꾸미는 방법을 살펴보겠습니다.

 

 

3. 가상의 세계와 실제 세계의 관계

자, 증강현실의 개념이 들어가는 부분입니다. 우리는 마커와 카메라를 통해 투영된 영상 사이의 대응관계를

통해 카메라의 위치를 알 수 있게 되었습니다. 그렇다면, 실제 세계와 똑같은 가상의 세계를 우리가 임의로

만들어서 실제 세계에서 카메라의 움직임과 똑같이 움직이는 가상의 카메라가 그 세계를 떠돌며 입력되는

영상을 실제 카메라를 통해 입력되는 영상과 합성(Compose)시킨다면 사용자에게 더 많은 정보를 전달할 수

있지 않을까? 이것이 바로 증강현실의 주된 개념입니다.

그럼 지금부터는 이제까지 구한 파라미터를 이용하여 가상의 월드를 어떻게 구성하는지 설명하겠습니다.

 

3.1. 가상의 카메라

가상 세계는 실제 세계와 같은 비율의 스케일을 유지해야 합니다. 또한 가상의 카메라는 실제 카메라와 똑같은

파라미터를 유지해야 합니다. OpenGL에서 개념적으로 존재하는 카메라 역시 우리가 현재까지 이해하고 있는

카메라와 같습니다. 따라서 카메라의 내부, 외부 파라미터가 필요하고, 이것을 우리가 구한 파라미터로 입력해

주어야 합니다. 바로 다음의 함수들을 이용해서 말이죠.

glViewport() : OpenGL에서 가상의 카메라를 통해 입력되는 영상 평면에 대한 정보

gluPerspective() : 카메라의 focal length, 종횡비, Near 평면, Far평면에 대한 정보

glLoadMatrixd() : 카메라의 Extrinsic parameter에 대한 정보 입력

그럼 각각의 계산방법을 보도록 하겠습니다.

그렇게 어려운 계산이 없습니다.

Near, Far 평면은 절두체와 관련된 내용이죠.. OpenGL관련 내용을 참고하시길 바랍니다.

사실 위의 코드에서 설정하는 내용은 카메라 내부 파라미터와 관련이 있는 내용들이므로 프로그램 초기화 시

한번만 설정해 놓으면 되는 값들입니다. (참고하세용~~)

가장 중요한 카메라 외부 파라미터 설정 방법을 보도록 하겠습니다.

우선 OpenGL 카메라와 우리가 사용하는 실제 세계의 카메라의 Z축의 방향은 일치한다는 가정을 전제로

하겠습니다. (카메라의 Z축의 방향이 일치하지 않으면, 실제 카메라가 바라보고 있더라도, 가상의 카메라는 상이 카메라뒤에 맺히는 결과를 갖게 되니, 실제로 가상의 세계에서 보이는 값은 없겠지요?)

여기서 중점적으로 봐야 하는것은 우리가 알고 있는 것은 카메라 외부 파라미터는 3x4크기의 행렬이고,

OpenGL에서는 4x4크기의 행렬을 필요로 한다는 것 입니다.

 

 [그림 6] OpenGL의 모델뷰 행렬, 출처 : http://www.songho.ca/opengl/gl_transform.html

따라서 아래와 같이 코드를 작성할 수 있지요.

(OpenGL의 변환과정에 대해서는 설명하지 않도록 하겠습니다. 자세한 자료는 그림 6의 출처를 참조하시길 바랍니다.)

자...

긴 여정이 끝났습니다. 이제 여기까지 진행한 결과를 한번 볼까요? 

[그림 7] 증강된 결과

여기까지의 내용을 이해로 위와같은 증강현실 프로그램을 만드는 것이 가능합니다. 물론 안정적인

증강현실을 위해서는 추적, 에러 최소화, 필터 등 배워야 할 것들이 많지만, 항상 시작이 중요하다는 것,

아시죠?

그럼 이번달의 포스팅은 이것으로 마치고, 다음달에는 또 다른 즐거운 주제로 찾아오겠습니다.

감사합니다.^^

 

* 참고자료 *

- Emerging Topics in Computer Vision, Section 1. Chapter 2. Camera Calibration

- A Flexible New Technique for Camera Calibration, Zhengyou Zhang, 1998.

- Introductory Techniques for 3-D Computer Vision, Emanuele Trucco, Alessandro Verri 저