타겟 추적을 위한 카메라의 팬,틸트 제어

영상처리 2013.12.10 13:22

팬/틸트 카메라에서 카메라 영상위에 임의의 한 점이 영상 중심에 오도록 카메라를 제어할 때 필요한 팬, 틸트 제어량을 계산하는 방법에 관한 글입니다.


참고로, 이 글은 [개발한 것들] - 가상 3D 영상 생성 프로그램(http://darkpgmr.tistory.com/85) 글에 대해 댓글로 문의주신 내용에 대한 답변으로 작성된 글입니다.


풀고자 하는 문제는 아래 그림과 같이 영상위에 특정 대상을 화면 중심에 오도록 하려면 카메라의 팬과 틸트를 얼마나 움직여야 하는가 입니다.



얼핏 쉽게 떠오르는 방법은 dy만큼 틸트(tilt)를 시키고, dx만큼 팬(pan)을 시키는 것이겠지만 실제로는 이렇게 하면 원하는 결과를 얻을 수 없습니다. 그 이유는 i) 카메라를 틸트시켰을 때 영상에서 점의 위치가 포물선 형태를 그리며 변한다는 점 그리고 ii) 팬을 시킬 때 회전축이 현재의 틸트값에 따라서 바뀐다는 점 때문입니다.


아래 그림과 같이 영상 위에 한 점 p가 있을 때, 카메라를 상하방향으로 틸트시키면 점 p가 파란색 선을 따라서 일직선으로 움직이는게 아니라 실제로는 붉은색 선을 따라 포물선 형태로 움직입니다.



언뜻 이해가 안갈수도 있는데, 그 이유를 설명해 보면 이렇습니다. 위 그림의 왼쪽 삼각형처럼 카메라의 초점(projection 중점)과 물체(p)와의 관계는 틸트와 관계없이 항상 고정되어 있습니다. 그런데 틸트가 변함에 따라서 이미지 평면에 의해 잘리는 부분만이 변하게 됩니다. 이 잘리는 부분의 길이가 x좌표를 결정하며 카메라의 틸트가 이 물체를 정면으로 바라볼 때 그 값은 최소가 됩니다. 또한 카메라가 다른 방향을 볼수록 그 값은 커집니다. 사각뿔을 상상하면서 사각뿔의 꼭지점이 카메라 초점, 밑면이 이미지 평면이라고 생각하고 사각뿔의 꼭지점을 고정시킨 상태에서 사각뿔을 위 아래로 회전시켜 보면 이해가 좀더 쉬울 것입니다. 이러한 성질은 틸트 뿐만 아니라 패닝(panning)에 대해서도 동일하게 적용됩니다.


이를 수식적으로 계산할 수도 있는데, 점 p가 상하 방향으로 화면 가운데 오도록 틸트를 맞추었을 때의 p의 x좌표를 dx라 한다면 해당 위치에서 카메라를 dt만큼 틸트시켰을 때의 x 좌표는 dx/cos(dt)가 됩니다.


다음으로 틸트에 따른 패닝의 효과를 살펴보면 틸트가 전혀 없는 상태에서 패닝(panning)이 일어나면 카메라 화면이 좌우로 이동하겠지만, 만일 틸트가 90도인 경우(천장을 바라보거나 바닥을 바라보는 경우)에 패닝을 시키면 영상 중심을 중심으로 원을 그리며 회전이 일어납니다. 이와 같이 카메라의 패닝은 현재 틸트값에 따라 전혀 다른 결과를 가져오기 때문에 항상 틸트값을 고려하여 계산해야 합니다.


팬, 틸트 카메라의 특성에 대한 내용은 이 정도로 하고 다시 원래의 문제로 돌아가서 영상위의 임의의 지점으로 카메라 중심을 이동시키기 위한 방법을 생각해 보겠습니다.



1. 카메라의 절대적인 팬, 틸트 값을 모르는 경우


기본적으로 현재의 틸트 값을 모르면 해당 위치로 가기 위해 필요한 이동량을 한번에 계산하는 것은 불가능합니다. 그 이유는 실제 팬/틸트 카메라에서 팬과 틸트의 물리적인 회전축이 각각 하나로 고정되어 있기 때문입니다. 현재 영상에서 상대적인 좌우 회전각과 상하 회전각을 계산하는 것은 가능하지만 실제 물리적인 회전축이 현재 영상의 좌우방향이 아니기 때문에 틸트를 모르면 이동량을 계산할 수 없습니다. 만일 임의의 방향으로 회전이 가능한 카메라가 있다면 이러한 문제가 발생하지 않을 것입니다.


만일 현재의 틸트 값을 모르는 경우에는 일단은 dx만큼 패닝을 시키거나 dy만큼 틸트를 시킨 후에 영상 추적 기술을 접목하여 오차를 계산하고 이를 바탕으로 틸트를 추정하여 이후 다시 한번 이동을 하는 방식으로 중점을 맞추는 방법 등이 가능할 것입니다.



2. 카메라의 절대적인 팬, 틸트 값을 알수 있는 경우


수식 도출을 위해 먼저 좌표계 정의가 필요하며 편의상 월드좌표계, 카메라좌표계, 팬, 틸트를 다음과 같이 정의합니다 (다른 식으로 정의해도 관계없으며 정의하기에 따라서 수식 등이 조금씩 달리질 수 있음)


<그림 1>


<그림 1>과 같이 월드좌표계와 카메라 좌표계를 정의합니다.

  • 월드 좌표계: 지면이 XY 평면, 위쪽이 Z축
  • 카메라 좌표계: 카메라 광학축 방향이 Zc, 오른쪽이 Xc, 아래쪽이 Yc

이 때, 카메라 좌표계의 원점과 월드좌표계 원점은 일치하는 것으로 설정합니다.


또한 월드 좌표계 내에서 카메라의 pan 및 tilt를 다음과 같이 정의합니다.

  • pan(팬): 카메라의 좌우 회전각. 광학축이 월드좌표계 Y축과 평행할때 0도, 왼쪽이 +, 오른쪽이 -
  • tilt(틸트): 카메라의 상하 회전각. 광학축이 월드좌표계 Y축과 평행할때 0도, 위쪽이 +, 아래쪽이 -


즉, 카메라의 pan, tilt는 카메라 광학축(Zc)이 Y축 방향일 때 0이고 카메라를 위로 들면 tilt가 증가, 왼쪽으로 돌리면 pan이 증가합니다.


현재 카메라의 팬 값을 p, 틸트 값을 t라 하고 이동하고자 하는 목표점의 영상좌표를 q(x, y) 라 하면 q를 영상 중심에 맞추기 위한 팬 값 p', 틸트 값 t'은 다음과 같이 계산합니다.


1. 영상좌표 (x, y)에 대한 정규 이미지 좌표 (u, v)를 계산한다.

u = (x-cx)/fx

v = (y-cy)/fy

=> 보다 정밀한 결과를 위해서는 여기에 추가적으로 렌즈왜곡보정까지 해 주어야 함(렌즈왜곡보정에 대해서는 카메라 왜곡보정 - 이론 및 실제 글 참조)


2. (u, v)에 대한 카메라 좌표 Xc를 구한다.

Xc = (u, v, 1)


3. Xc를 월드좌표 Xw로 변환한다. 

=> 3D 좌표계 변환 방법 (예: 월드좌표계 - 카메라 좌표계) 글의 수식 (2) 참조


4. Xw의 팬 각 p', 틸트 각 t'을 계산한다.

Xw = (a, b, c)로 가정하면,

p' = -atan2(a, b)

t' = atan2(c, sqrt(a*a+b*b))


5. 계산된 p', t' 위치로 카메라를 이동시키면 OK.

현재의 팬, 틸트가 p, t이므로 p'-p, t'-t 만큼 이동시키면 원하는 위치로 이동하게 됨


계산 원리는 카메라 초점(프로젝션 중심)과 목표점을 잊는 선을 월드 좌표계 상에서 구한 후, 이 선 방향의 팬과 틸트 값을 계산하는 방식입니다.


※ 위 방법은 카메라의 초점 위치가 팬, 틸트에 관계없이 고정된다는 가정하에 수식을 세운 것입니다. 그런데, 실제 팬/틸트 카메라는 카메라 초점 위치도 같이 변하기 때문에 이에 따른 오차가 있을 수 있으니 참고하시기 바랍니다. 만일 초점의 위치변화까지 고려한다면 좀더 복잡한 수식 도출이 필요합니다..


by 다크 프로그래머


저작자 표시 비영리 변경 금지
신고
  • 최환수 2013.12.10 17:16 신고 ADDR 수정/삭제 답글

    자세한 답변 정말 감사드립니다.
    좌표변환에 대한 공부를 더 해보고 다크님의 공식을 적용해 보도록 노력하겠습니다.
    다시한번 감사드립니다.

  • 최빡꾸 2014.01.28 15:07 신고 ADDR 수정/삭제 답글

    안녕하세요.
    CCTV의 Privacy기능을 찾다가 위 글을 보게 되었는데요..
    혹시 위 수식들로 Privacy기능 구현이 가능한가요??

    (Privacy 기능 : 사용자가 원하는 사물에 Mask처리를 하고, pan/tilt를 돌렸을때 mask는 설정한 사물에만 있도록하는것)

    • BlogIcon 다크pgmr 2014.01.28 15:42 신고 수정/삭제

      안녕하세요.
      가능은 합니다만 실제 수식을 세우기 위해서는 카메라 영상 기하학에 대한 이해가 필요합니다. 과정만 간략히 말씀드리면 "privacy 영역에 대한 월드좌표 -> 현재 카메라의 팬,틸트값을 이용하여 카메라좌표로 변환 -> 정규이미지 좌표로 변환 -> (렌즈계 왜곡 반영) -> 픽셀 좌표로 변환" 과정이 필요합니다. 이러한 과정을 거치면 현재의 카메라 팬, 틸트 값으로부터 privacy 영역의 영상좌표를 알수 있습니다. 세부적인 관련 수식 및 이론에 대해서는 본 블로그의 [영상 geometry #] 시리즈 글들과 http://darkpgmr.tistory.com/31, 32, 84 글들을 참조하시기 바랍니다.

  • 최빡꾸 2014.01.28 16:13 신고 ADDR 수정/삭제 답글

    답변 정말 감사드립니다.
    알려주신 과정들에 대해서 공부를 한다음에 기능구현을 해야할꺼 같습니다.

    지금까지 수식을 사용하지 않고 각 상황에 맞게 기능을 코딩하다보니... 실패를하였습니다.
    약간의 흉내는 가능하지만, 위 글에서 말씀하신거 처럼 pan을 돌릴때 tilt각도에 따라 타겟이
    포물선을 그리며 움직이는 등 여러가지 변수들이 있다는걸 알게되어 더이상 수식없이는 안되겠다는걸 깨닫게 되었습니다. 알려주신 과정을 공부하여 다시 적용해봐야 겠습니다. 답변 진심으로 감사드립니다.

  • 최빡꾸 2014.01.29 11:02 신고 ADDR 수정/삭제 답글

    안녕하세요
    다름이 아니라, 현재 privacy영역에 대한 월드좌표를 구하려면,
    (Privacy영역 2D를 전체영역인 월드좌표로 변환)
    위 포스팅 내용과 같이 영상좌표(x,y)를 정규이미지로 바꾼 후 카메라좌표로 변환하여 월드좌표로 변환 하는게 맞나요??

  • 최빡꾸 2014.01.29 11:39 신고 ADDR 수정/삭제 답글

    빠른 답변 감사드립니다.
    위 포스팅내용의 수식들을 좀 더 공부한뒤 PTZ카메라에 적용을 해봐야 될꺼같습니다
    다시한번 감사드립니다.

    • BlogIcon 다크pgmr 2014.02.02 06:54 신고 수정/삭제

      최근에 쓴 http://darkpgmr.tistory.com/122 글도 참고하시면 공부하시는데 도움이 될 것 같습니다

  • 최빡꾸 2014.02.04 18:19 신고 ADDR 수정/삭제 답글

    와~
    좋은 정보 감사합니다.
    열심히 공부하겠습니다~

  • 최빡꾸 2014.02.14 17:56 신고 ADDR 수정/삭제 답글

    안녕하세요 위 내용을 공부하다가 궁금한점이 있어서요..
    위 내용중에 fx (초점거리) 가 없이두 수식 적용이 가능한가요?? (AF카메라사용으로 자동으로 초점을 잡아줌)
    그리고 정규좌표 (u,v) 를 카메라좌표 Xc(u,v,1)로 변환하는 수식이 따로 있나요?? 아니면,
    ex) u=1, v=2;
    Xc[0]=u, Xc[1]=v, X[2]=1;
    R*Xc;
    위와 같이 하면 되는건가요??
    제가 이해력이 많이 부족한듯 싶습니다. ㅠㅠ

    • BlogIcon 다크pgmr 2014.02.15 07:31 신고 수정/삭제

      f는 반드시 알아야 합니다. 카메라의 AF 기능을 끄고 사용하시거나 아니면 AF 기능을 꼭 써야 한다면 대표적인 f를 하나 구해서 약간의 오차를 감수하고 공통적으로 사용해야 할 듯 싶습니다.
      카메라좌표 변환은 말씀하신데로 하면 됩니다. 카메라 좌표계란 카메라를 기준으로 설정한 가상의 좌표계로서 카메라의 렌즈 센터를 원점으로 하고 카메라의 방향을 Z축 방향으로 하는 좌표계입니다. 이 때, 카메라의 렌즈로부터 이미지 센서(CCD, CMOS 등) 표면까지의 거리를 초점거리(focal length)라고 하는데, 이 거리에서 이미지 센서 평면을 이미지로 해석한 것이 영상좌표입니다. 그런데 이미지 센서(CMOS)를 렌즈로부터 거리가 1만큼 떨어진 가상의 위치로 이동시켰다고 가정하면 물체의 이미지 좌표가 변하게 될 터인데 이 때의 좌표를 정규좌표라 정의한 것입니다. 즉, 정규좌표란 원점(렌즈중심)으로부터 거리(Z)가 1인 지점에서의 가상의 이미지좌표이므로 3D로 해석하면 말씀하신 것처럼 Z좌표에 1만 붙이면 됩니다.

  • 최빡꾸 2014.02.17 10:05 신고 ADDR 수정/삭제 답글

    답변 진심으로 감사드립니다.
    아무래도 f값은 임의값을 구하여 적용해야 될거 같습니다.
    그리고 카메라좌표,영상좌표,정규좌표에 대해 상세히 설명해주셔서 너무 감사드립니다.
    그런데 만약에 카메라가 Zoom In/out(확대/축소) 기능이 있다고하면, Z축 값이 변할 수 있는건가요??

    그리고 위 포스팅내용은 영상좌표 x,y점을 중앙위치인 x',y'점으로 움직이려면 pan/tilt각도가 얼마인가를 구하는거라, 목표점x',y'가 필요하지만, 저 같은경우는 Privacy영역에 x,y점을 pan/tilt만큼 움직였을때 점이 얼만큼 움직였는지 구하려고합니다.
    그렇다면 위 수식 u= (x-cx)/fx이 적용이 안되지 않나요??

    • BlogIcon 다크pgmr 2014.02.17 10:04 신고 수정/삭제

      카메라의 줌이 바뀌면 focal length도 같이 바꿔주면 됩니다. 만일 2배 줌(확대)이 되었다면 f 값도 2배로 해 주시면 됩니다.

  • 배우자 2014.06.15 23:39 신고 ADDR 수정/삭제 답글

    안녕하세요.
    여쭈어 볼것이 있어 이렇게 댓글을 올렸습니다.
    현재 뷰어에서 제가 원하는 곳을 클릭하면 틸트와 팬이 동시에 움직임과 줌인이 동시에 되면서 그 클릭한 곳이 중점으로 되는 것인데 초기화면에서 양끝을 클릭하면 오차값이 많이 발생되네요....
    이 수식을 사용하면 오차값을 조금이나마 줄일 수 있을까요?

    • BlogIcon 다크pgmr 2014.06.16 09:08 신고 수정/삭제

      오차는 수식 때문일수도 있고 기구적 제어오차 때문일 수도 있으니 둘다 확인해 보시면 좋을 듯 싶습니다.

  • 질문 2014.07.24 15:16 신고 ADDR 수정/삭제 답글

    안녕하세요,
    질문 하나만 드릴께요..
    영상 A와 카메라의 위치오차 없이 자세오차만 주어 pan, tilt를 변화시켜서 얻은 영상 B가 있을 때, 영상 A와 B는 homography (projective transformation) 관계를 가지나요?

    • BlogIcon 다크pgmr 2014.07.24 18:56 신고 수정/삭제

      네. 그렇다고 생각합니다. 혹시 가지고 계신 웹캠이 있으면 옆으로 이동시켰을 때와 제자리에서 회전시켰을 때 영상 변화를 보면 확실히 그 차이를 느끼실 수 있을 것입니다.

  • 질문 2014.10.14 10:49 신고 ADDR 수정/삭제 답글

    안녕하세요, 항상 작성자분 홈페이지에서 많은 것을 공부해가네요~
    혹시 위와 같이 카메라의 pan, tilt, roll에 대해서 더 자세하게 공부하고 싶은데
    추천해주실만한 자료나 책이 있는지 궁금합니다.
    제가 관심있는 쪽은 GPS의 부정확성으로 인한 카메라의 pan, tilt, roll의 오차를 3D digital model을 기반으로 추정하는 것입니다.
    답변부탁드리겠습니다.!

    • BlogIcon 다크pgmr 2014.10.14 11:04 신고 수정/삭제

      안녕하세요. 카메라의 자세(방향)에 대해 딱히 떠오르는 자료나 책은 잘 모릅니다. Euler angle, quaternion, rodrigues 등으로 관련 자료를 검색해 보시기 바랍니다.
      그리고 GPS는 위도,경도,고도 즉 x,y,z를 측정할 수 있는 센서인데 카메라의 방향(pitch, roll, yaw)을 측정하는 것과 어떤 관계가 있는지 잘 이해가 안가네요. 그리고 3d digital model이란 어떤 것을 의미하는 건가요?

  • 강강품 2015.09.01 16:22 신고 ADDR 수정/삭제 답글

    님의 자료로 많은 도움을 받고 있습니다.
    단계로별 진행중인데 제가 이해하고 있는것이 많는지 문의 드립니다.
    글중에
    0. 화면에서 표출되는 영상(bmp,320x240) : catpure_img
    이동한 객체의 위치는(100,100) : img_pos
    카메라에서 수신 받은 pan, tilt 값 : p(pan),t(tilt)
    캐리브레이션 결과 값을 아래와 같이 구했습니다 :
    fx = 477.040; fy = 635.687;
    cx = 321.402; cy = 256.140;
    k1 = -0.383; k2 = 0.224;
    p1 = -0.002676; p2 = -0.001953;
    라고 정의함

    1. 영상좌표(x,y)은 image plane 위치을 말하는건가요.
    그러면 image plane위치는 x = (img_pos.x * fx) / catpure_img.x
    위와 같은 식으로 구하면 되는지요.
    2. 정규 좌표값을 구하고
    u = (img_pos.x.x - cx) / fx;
    v = (img_pos.x.y - cy) / fy;
    3. 월드좌표값을 구했는데
    a = cos(p)*u - sin(p)*sin(t)*v - sin(p)*cos(t);
    b = sin(p)*u + cos(p)*sin(t)*v + cos(p)*cos(t);
    c = 0 - cos(t)*v + sin(t);
    4. 아래의 pan,tile값을 구했는데
    new_p = -atan2(a, b);
    new_t = -atan2(c, sqrt(a*a + b*b));
    너무 어쩌구이 없는 값이 나왔습니다.
    무엇가를 잘못 이해하고 있는것 같은데 도움 부탁드립니다.



  • 뻐꾹 2016.09.05 01:20 신고 ADDR 수정/삭제 답글

    안녕하세요
    다름이 아니라 월드좌표계를 구할때 약간 헷갈리는 부분과 관련하여 질문이 있어 글을 씁니다.
    "카메라 위치 및 자세파악" 챕터에서는 월드좌표를 구할때 "정규이미지 평면에서의 좌표 ((x-cx)/fx, (y-cy)/fy)로 바꿉니다. 다음으로 실제 물체와의 거리 Z를 반영해 주면 ((x-cx)/fx*Z, (y-cy)/fy*Z, Z)가 구하고자 하는 3차원 공간좌표가 됩니다. "라고 하시며 물체와의 거리가 고려가 되었는데,
    이번 챕터에서는 카메라좌표에서 월드좌표를 구할때 카메라좌표(u,v,1)에서 변환행렬을 곱하여 월드좌표를 구하셨습니다. 이때 물체와의 거리(Z)가 고려된 것인지 알고 싶습니다. 또한 위에서 5번에서 구하신 pan과 tilt의 각이 실제 월드좌표계에서의 각도인지도 알고 싶습니다.
    감사합니다. :)

    • BlogIcon 다크pgmr 2016.09.05 09:16 신고 수정/삭제

      안녕하세요. 여기서 구한 월드좌표는 물체의 월드좌표가 아니라 물체를 정규이미지평면에 투영시킨 점의 월드좌표입니다. 즉, 물체와 카메라 초점을 잊는 ray가 정규이미지 평면과 만나는 교점인 (u, v, 1)에 대한 월드좌표입니다. Pan/Tilt 제어가 목적이기 때문에 여기서는 방향만 알면 됩니다. 카메라좌표(pc)를 월드좌표(pw)로 변환시키는 관계식은 pw = R*pc + t로 주어지는데 여기서 평행이동 t에 물체와의 거리 Z가 반영되어 있습니다. 즉, 좌표계 변환을 하면 Z까지 고려되어서 변환이 이루어집니다. 하지만 여기 문제에서는 본문에 적었듯이 카메라좌표계 원점과 월드좌표계 원점을 같게 놓고 문제를 풀었기 때문에 평행이동 성분 t는 고려되지 않았습니다. 그리고 질문(5번 과정에서 구한 pan/tilt가 월드좌표계인가)은 본문에 언급했듯이 이 풀이는 "카메라의 절대적인 팬, 틸트 값을 알수 있는 경우"에 대한 풀이이며 이 절대적인 값의 기준을 월드좌표계라고 가정하고 도출한 값입니다.