3D 좌표계 변환 방법 (예: 월드좌표계 - 카메라 좌표계)

영상처리 2013.07.25 14:02

3차원 공간에서 좌표축 또는 좌표계를 변환하는 방법입니다.


3D 월드 좌표계를 카메라 좌표계로 변환하는 것을 예로 들어 설명하겠습니다.


즉, 월드 좌표계(world coordinate system)에서의 점 (X, Y, Z)로부터 카메라 좌표계에서 봤을 때의 좌표 (Xc, Yc, Zc)를 구하는게 목적입니다.


<그림 1>


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

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


또한 월드 좌표계 내에서 카메라의 위치 및 방향을 다음과 같이 정의하겠습니다.

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


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


이제 풀고자 하는 문제를 정리하면 다음과 같습니다.

카메라의 위치를 (X1, Y1, Z1), 카메라의 팬(pan) 각을 p 라디안, 틸트(tilt)를 t 라디안이라 할 때, 월드좌표계 상의 임의의 점 (X, Y, Z)를 카메라 좌표계 상의 좌표 (Xc, Yc, Zc)로 변환시키는 관계식을 구하라.


좌표계 변환관계는 2가지 방법으로 구할 수 있습니다. 하나는 일련의 회전변환 행렬을 조합하는 것이고, 다른 한 방법은 단위벡터를 이용해 직접 변환행렬을 구하는 방법입니다.



방법 1: 회전변환을 조합하는 방법


월드 좌표축을 카메라 좌표축 방향과 일치되도록 하는 회전변환 행렬을 R이라 하면, R은


 --- (1)


과 같이 구해집니다 (3D 회전변환 행렬에 대해서는 [컴퓨터 비전에서의 Geometry #5] 3D 변환 참조)


따라서, 월드좌표를 카메라 좌표로 변환시키는 변환식은 다음과 같이 구해집니다.


 --- (2)


좌표축 변환은 일반적인 변환과정을 역으로 적용함에 주의해야 합니다.


식 (2)에서 회전변환은 RRT = I를 만족하기 때문에 R-1 = RT로 구할 수 있습니다. 즉, 식 (2)는 다음과 같이 됩니다.


 --- (3)


☞ 여기서 R은 월드좌표를 카메라좌표로 변환시키는 행렬이 아니라 좌표축을 변환시키는 행렬임에 주의해야 합니다. 즉, R은 월드좌표축->카메라좌표축 변환 행렬입니다. 즉, 좌표로 보면 R은 카메라좌표->월드좌표로 변환시키는 행렬입니다 (좌표축 변환과 좌표변환은 서로 역변환 관계). 이 글에서 정의한 R과 opencv의 solvePnP에서 반환되는 R이 표기가 같아서 서로 혼동스러울 수 있겠지만 solvePnP에서 반환되는 R은 월드좌표->카메라좌표 변환행렬이고, 여기서 정의한 R은 카메라좌표->월드좌표 변환행렬입니다. 즉, 서로 반대입니다. 표기를 통일하는게 좋았겠지만 이 글에서는 설명의 흐름상 어쩔 수 없이 R을 다른 글들과는 다르게(반대로) 정의했습니다..


방법 2: 변환행렬을 직접 구하는 방법


어떤 선형변환 행렬 T가 있을 때, 각각의 좌표축 단위벡터들이 변환 T에 의해서 어디로 가는지만 알면 T를 손쉽게 구할 수 있습니다.


만일, T에 의해 X축 단위벡터 (1, 0, 0)이 (a1,a2,a3)로 가고, Y축 단위벡터 (0, 1, 0)이 (b1, b2, b3), Z축 단위벡터 (0, 0, 1)이 (c1, c2, c3)가 된다면, 변환행렬 T는 다음과 같습니다.


 --- (4)


이제, 이 방법를 이용하여 X축을 Xc, Y축을 Yc, Z축을 Zc로 보내는 변환행렬 R을 구해보겠습니다.


<그림 2>


<그림 2>를 참조하여 각각의 단위벡터가 어디로 이동해야 하는지를 구해보면 다음과 같습니다.


 --- (5)


따라서, 변환행렬 R은 다음과 같이 구해집니다.


 --- (6)


식 (1)과 동일한 결과가 나옴을 확인할 수 있습니다.


나머지 과정은 방법 1과 마찬가지이기에 생략합니다 (최종적으로는 식 (3)과 동일한 변환식이 나옵니다).


☞ 식 (3)은 벽에 고정된 CCTV, 자동차에 고정된 카메라 등에서 좌표계 변환을 할 때 유용하게 활용될 수 있으리라 생각합니다.


by 다크 프로그래머


  • 대학원생 2013.10.24 17:07 신고 ADDR 수정/삭제 답글

    안녕하세요?
    귀한 포스팅 잘 보았습니다.
    제가 요즘 Camera Calibration에 대해 공부중인데 올려주신 포스팅들이 많이 도움이 되었습니다^^
    올려주신 글들을 몇번이고 보았는데, 현재 지금 감이 잘 오지않는게..
    Intrinsic의 경우 뭔가 명확하여서 이해가 쉬웠는데
    Extrinsic의 경우 무엇인지는 알겠으나 감이 잘 오지 않는다고할까요..

    현재 제가 Laser Scanner와 Camera를 같이 쓰는 방법에 대해서 공부중인데요..
    Camera의 Extrinsic Parameter와 Laser에서 구해주는 거리와 각도 정보를 이용하면
    어떻게 되지 않을까..하는 막연한 생각이 있는데 뭔가 감이 확 오질 않네요.

    지금 올리신 글도 제가 읽어보았는데..결국 글의 요지는 좌표축, 원점을 이동시킨다는 의미이신가요?
    Extrinsic을 구하게 되면 사영을 통해서 R, T 행렬을 구할 수 있는데
    그 정보를 가지고 Laser와 어떻게 같이 쓰는건지..ㅜㅜ
    말이 조금 정리가 안되는데요..

    결국 Laser에서 전방에 20m떨어져 있는 물체를 이미지 영상에 표시를 하고싶은데..
    20m가 떨어져있다는 것을 어떻게 계산하면 좋을까요..?

    • BlogIcon 다크pgmr 2013.10.28 07:50 신고 수정/삭제

      laser 센서는 거리와 방향각을 주기 때문에 이로부터 물체의 3D 월드좌표를 알 수 있습니다. 이후, 월드좌표계 -> 카메라좌표계 -> 영상좌표계 과정을 거쳐 물체의 영상좌표를 얻을 수 있습니다. 월드->카메라는 본문 내용을, 카메라->영상은 [영상 geometry #6] 글을 참조하기 바랍니다. 물론, 이러한 계산은 레이져 센서와 카메라의 물리적 위치관계를 미리 알고 있을 때 가능합니다. 만일 레이져 센서값과 획득된 이미지로부터 역으로 매핑(mapping) 관계를 파악하고자 하는 것이라면 얘기가 완전히 다릅니다. 지면의 고저차, 레이져 센서의 수평문제 등으로 인해 레이져 센서값만으로는 물체의 어떤 부위(높이)에 대한 거리값인지를 알 수 없기 때문입니다. 이 주제에 대해서는 레이져-카메라 정렬/매핑 등의 키워드로 별도 검색해 보시기 바랍니다.

    • 대학원생 2013.10.29 14:31 신고 수정/삭제

      안녕하세요?

      답변 감사합니다^^
      말씀해주신거에서 조금 헷갈리는게 있는데요..
      월드->카메라에서 변환은 결국 R,T를 이용하여 투영하는것이 맞는거죠?
      이 포스팅에 써주신 행렬식도 Rotation에 관한 행렬식인거같은데..
      그렇다면 결국 영상 geometry #6에서 7번식이 월드->카메라->영상좌표계 사이의 변환을 나타내는것이 맞는건가요?
      제가 현재까지 공부한바로는 K[R|T]가 결국 호모그래피로서 영상과 월드 좌표사이의 투영을 설명한다고 이해가 되었거든요..

      위에서 이해한것을 테스트하기위해 먼저 체스보드판을 카메라 정면에서 찍고 검출된 체스보드의 각 코너의 위치를 (0,0), (0,1),...(width-1, height-1)로 월드 좌표로 정해놓고 다음 체스보드판을 오른쪽으로 기울여서 각 코너의 픽셀 좌표를 구한 뒤 R,T 행렬을 구하였습니다.
      그 후 R,T행렬을 이용하여 Projection을 한 뒤 픽셀 좌표를 구하니 조금 오차가 있지만 이미지 상의 각 코너의 위치를 나타내었습니다.
      결국 calibration은 조금 오차가 있지만 정상적으로 동작하는건데..

      제가 또 궁금한것은 월드 좌표를 제가 원하는 곳으로 원점을 옮겨보고싶은데..포스팅에 쓰인 것 같이 카메라의 위치를 (0,0,0)으로 하여 월드 좌표를 설정해서 위와 한 것 같이 R,T 행렬을 구하고 싶은데..
      이게 잘 이해가 안됩니다..

      카메라의 위치에서 z축 방향으로 20cm앞의 점을 (0,0,20)이라 했을때
      이 점의 위치를 픽셀 평변에 투영시키기 위한 Rt행렬은 무엇을 기준으로 구하는 것인가요..??
      체스 보드의 경우 코너를 기준으로해서 Rt행렬을 구하는 것이라고 이해를 하였는데, 체스 보드가 없을 경우 Rt행렬을 어떻게 구하는 것인기 감이 안잡히네요..ㅜㅜㅜㅜ
      아직 좌표계에 대해서 이해가 부족한것인가요?ㅜㅜㅜ

    • BlogIcon 다크pgmr 2013.10.29 18:14 신고 수정/삭제

      어떤 부분이 혼동스러운지 제가 정확히 추측키는 어렵습니다만 일단 각 좌표계에 대해서 개념을 확실히 잡는게 중요한 것 같습니다. 좌표계에 대한 내용은 [영상 geometry #1]글을 참조해 주세요.
      질문하신 내용에 대해 하나씩 짚어보면,
      먼저 투영이라는 용어는 3D->2D로 projection하는 것이므로 월드->카메라가 R,T를 이용한 투영이라는 표현은 적당치 않습니다. 월드->카메라는 어떤 동일한 물체에 대해 이를 월드좌표계에서 봤을 때의 좌표 X와, 카메라 좌표계에서 봤을 때의 좌표 Xc가 서로 다를 것인데, 이들 사이의 변환관계 Xc = [R|t]X 를 구하는 것입니다. 이렇게 카메라 좌표계에서의 좌표 Xc를 구한 후 K를 곱하면 KXc가 이미지 좌표로 투영됩니다.
      카메라 좌표계에서의 전방 20cm 점을 이미지에 투영시키기 위해서는 [R|t] 행렬이 필요치 않습니다. [R|t]는 월드좌표계와 카메라좌표계 사이의 회전, 평행이동 관계입니다. 카메라 좌표를 이미지로 투영시키기 위해서는 단순한 비례식을 풀면 됩니다. (0,0,20cm)는 거리 관계없이 이미지 중심으로 투영될 것이고, 만일 (a, 0, 20cm)는 20:a = fx(focal length):? 식을 풀어서 영상에서의 x좌표가 정해질 것입니다.

      카메라 모델에 대한 전반적인 이해가 좀더 필요하다고 생각됩니다. darkpgmr.tistory.com/32 글과 영상 geometry 시리즈 글들을 보면 도움이 되리라 생각합니다.

    • 대학원생 2013.10.29 18:26 신고 수정/삭제

      빠른 답변 감사합니다^^

      확실히 모든 글들을 깊이 이해하지않고 빠르게 넘겨봐서 그런지..
      이해가 확실히 안되고있다는 느낌이 확확드네요..

      카메라 좌표계와 월드 좌표계가 계속해서 헷갈리는 것 같습니다..
      결국 카메라의 위치를 월드 좌표계의 원점(0,0,0)으로 잡으면 두 좌표계는 따로 R,t를 곱해줄 필요가 없이 똑같이 되는 것인가요??

    • BlogIcon 다크pgmr 2013.10.29 18:44 신고 수정/삭제

      네 그렇습니다. 그러나 대부분 실제 문제에 있어서 월드좌표계는 고정이지만 카메라는 계속 움직이기 때문에 카메라를 원점으로 잡는 경우는 매우 드뭅니다..

    • 대학원생 2013.10.29 19:13 신고 수정/삭제

      그렇군요!
      이제야 조금 이해가 되는거 같습니다!
      3차원의 월드상의 하나의 점은 결국 회전, 이동만으로 카메라 좌표계의 하나의 점으로 표현될 수 있고 그 바뀌어진 점의 위치를 알기 위해 R,t 행렬이 필요한 거군요!
      제가 이해한 것이 맞나요?

      제가 지금 무인차 관련 공부를 하고있는데
      무인차에서는 카메라의 위치가 자동차에 고정이 되어있거든요
      그렇다면 카메라를 항상 원점으로하게 되면 R,t행렬은 고려하지 않아도 되니..상당히 문제가 간단해 질거같습니다! 감사합니다!

      사실 위에 쓰신 글 중에서 식 3번의 경우 차량에 고정된 카메라에서 좌표계 변환등을 할때 유용할거같다고 써주셔서 계속해서 고민을 했었거든요..R,t 행렬을 어떤식으로 사용해야 하는건가..하고^^; 제가 이해를 잘 못했던거 같습니다!

      이제서야 조금 이해가 된듯하니 처음부터 다시 글을 읽어보며 리뷰를 해봐야겠습니다^^ 기분좋게 저녁먹고 다시 공부할 수 있을거같네요

      감사합니다!
      좋은 저녁되세요!

  • 영상초보자 2014.04.30 10:50 신고 ADDR 수정/삭제 답글

    안녕하세요. 레이저 스캐너에 대해서 공부하고 있는데 블로그의 자료가 너무 좋습니다.

    다만 이해가 안되는 부분이, 레이저와 카메라를 X,Z 축 선상으로 동일한 위치에 두었을 때, 즉 월드좌표계와 카메라 좌표계의 차이는 Y축 거리에 의한 차이만 생기는데요. 물론 카메라의 자세가 다르긴 합니다. 이럴 경우에, 어떤 임의의 P점을 측정하려고 할때, 앞서 설명해주신 기준을 카메라 좌표계로 설정해서 R;T를 구해야하는 건지, 기존 임의의 P점을 기준으로 R;T를 구해야하는 건지 확실한 개념이 안서네요. 알려주시면 감사하겠습니다.

    • BlogIcon 다크pgmr 2014.04.30 16:54 신고 수정/삭제

      안녕하세요. 질문 내용을 이해하는데 조금 애를 먹었습니다..
      아마도 레이져로 측정된 3차원 좌표 P에 대응되는 카메라 좌표를 구하는 것이 목적이라 생각됩니다. 물론 레이져에서의 3차원 좌표를 카메라 좌표로 변환해주는 [R|t]를 구해야 할 것입니다 (카메라좌표 = R*레이져좌표 + t). 이러한 R, t는 카메라 좌표축을 레이져 좌표축과 일치시키기 위해 필요한 R, t를 구하시면 됩니다 (왜냐하면, 좌표변환은 좌표축 변환의 역변환이기 때문).

  • 카메라어려워ㅠㅠ 2014.07.14 21:02 신고 ADDR 수정/삭제 답글

    안녕하세요? 진작부터 많은 도움을 받았는데 이제야 인사를 드리네요~
    자세한 설명을 해주신 덕분에 많은 도움이 되었습니다.
    다름이 아니라 식 1에서 틸트각에 대해 -90도 회전시켜 준것은 전방 카메라이기 때문인가요?
    저는 천장카메라를 이용하고 있는데 그부분에 대해 의문이 생겨서 질문드립니다.
    감사합니다.

    • BlogIcon 다크pgmr 2014.07.14 21:30 신고 수정/삭제

      안녕하세요. 3d는 저도 볼 때마다 햇갈리고 어렵습니다. ^^;
      -90도 회전시킨 것은 그림 1과 같이 카메라 및 월드 좌표축을 잡았을 경우에 월드축을 카메라축을 맞춰주기 위해서입니다. 좌표축을 어떻게 정의하느냐, 그리고 팬,틸트 방향을 어떻게 정의하느냐에 따라 구체적인 수식은 조금씩 달라질 수 있을 것입니다.

    • 카메라어려워ㅠㅠ 2014.07.15 16:15 신고 수정/삭제

      답변 감사합니다.
      한가지만 더 질문하겠습니다~
      식 1에서는 roll 회전에 대한 변환이 고려되어 있지 않은데,
      이는 roll회전은 없다고 가정했기 때문인가요?

    • BlogIcon 다크pgmr 2014.07.15 16:25 신고 수정/삭제

      네 그렇습니다.

  • 질문 2014.07.25 14:48 신고 ADDR 수정/삭제 답글

    안녕하세요 3D rotation matrix를 공부하던중 의문사항이 있어 질문드립니다.
    위 변환행렬 매트릭스를 이용하면 p=0이고 t=45도라고 가정하고
    임의의 global 좌표가 x는 증가 y,z는 일정하게 0이라고 할때

    어느 점에서나 Yc가 일정하게 되는데요 사실 1차원 그래프를 보았을때 x증가하면 변환축대비
    yc의 값은 증가 혹은 감소해야 하는데 매트릭스상으로는 변화가 없네요.
    이동하는 물체가 y,z,축 상으로 일정할때 카메라 angle이 tilt되어 있다면
    카메라 aixs상의 Yc(높이축)값이 바뀌어야 하는데 이 매트릭스 상으로는 그렇지 않은거 같아 질문 드립니다.

    • BlogIcon 다크pgmr 2014.07.25 15:54 신고 수정/삭제

      p=0이라면 yc가 일정한게 정상이라고 생각됩니다만...

  • 학생 2014.08.02 15:35 신고 ADDR 수정/삭제 답글

    안녕하세요. 매우 유용한 자료를 잘 정리해 주셔서 항상 감사한 마음으로 블로그를 방문하는 학생입니다. 좌표계 변환에서 질문드리고 싶은게 있습니다.
    위 글에서 좌표계변환은 일반적인 변환과정을 역으로 적용해야 한다고 하셨고 이러한 성질때문에 회전변환 행렬 (R)의 역행렬을 곱한걸로 보입니다. 그런데 월드좌표계를 카메라좌표계로 옮겨주는 행렬이 회전변환 행렬 (R)이고 R 행렬을 곱해주면 월드좌표계와 카메라좌표계가 동일한 좌표계가 되는데 왜 역행렬을 곱해야 하는 것인가요??(일반적인 변환과정을 역으로 적용해야 한다는 말씀이 잘 이해가 가지 않네요ㅠ)

    • BlogIcon 다크pgmr 2014.08.03 07:14 신고 수정/삭제

      안녕하세요. 지금보니 제가 용어를 잘못 쓴 것 같습니다. '좌표계 변환'이 아니라 '좌표축 변환'이란 용어가 좀더 적절한 것 같습니다.
      좌표축변환이 일반적인 좌표변환의 역변환 관계임은 예를들어 xy 좌표축을 90도 회전시켜서 얻은 새로운 좌표축을 기준으로 한 좌표는 원래의 좌표들을 -90도 회전시킨 것과 동일함을 생각하시면 되겠습니다.

  • 학생 2014.08.04 11:34 신고 ADDR 수정/삭제 답글

    안녕하세요. 답변감사합니다. 추가적으로 질문이 있는데요..
    말씀해주신 답변은 결국 실제로는 카메라가 이동하는 것이지만 실제 계산할때는 월드좌표계가 이동한것처럼 계산을하기 때문이라고 이해했는데 맞는것인가요??
    그리고 이내용을 3D 그래픽스에 적용해보면 3D 그래픽스에서도 월드좌표계를 카메라좌표계로 변경하는 과정이 필요한데 이 과정을 담당하는 것이 Rotation 행렬과 Translation 행렬인것으로 알고 있습니다. 그럼 3D 그래픽스에서의 Rotation 행렬과 Translation 행렬도 위의 방식으로 결정이되는 것인가요??(결국 제 질문은 저희가 OpenGL에서 사용하는 Rotation 행렬과 Translation 행렬이 결국에는 역행렬로 곱해지는 것인가가 궁급합니다.)

    • BlogIcon 다크pgmr 2014.08.04 20:31 신고 수정/삭제

      글에 적은 것은 그냥 제 방식데로 풀어본 것이라서.. opengl에서 어떤 방식을 사용하는지는 저도 잘 모릅니다. 어쨌든 문제를 푸는 방식은 조금씩 다를 수 있다고 생각합니다. 저는 월드좌표계를 카메라 좌표계로 일치시키는 행렬을 구해서 변환행렬을 구했지만 반대로 카메라 좌표계를 월드좌표계로 일치시키는 행렬을 구할 수도 있을 것 같습니다. 아니면 제가 글에 적어놓은 방법2처럼 단위벡터를 이용해서 변환행렬을 직접 구할수도 있습니다.

  • 학생2 2015.05.12 17:10 신고 ADDR 수정/삭제 답글

    질문있습니다!. 위 식과 이미지에서 각각 p와 t가 의미하는게 어느 각도인가요?

    p는 X cosp = X_c 혹은 X_c cosp = X로 되는 것 같은데 t가 의미하는것을 모르겠습니다. (카메라, 월드좌표계의 어떤 좌표축들을 활용해 내적으로 구해야 하는 것인가요?

    • 학생2 2015.05.12 18:05 신고 수정/삭제

      각도 p는 X와 Xc의 내적 / (X크기*Xc크기) 로 구해지는 것을 알겠는데,
      Y와 Yc, Z와 Zc를 통해 t를 구하는것을 이해하지 못하겠다는 의미입니다!

    • BlogIcon 다크pgmr 2015.05.12 19:45 신고 수정/삭제

      p는 pan, t는 tilt를 의미하며 구하는 과정에 대해서는 http://darkpgmr.tistory.com/122 글을 참조하시기 바랍니다.

  • 학생3 2016.01.07 00:28 신고 ADDR 수정/삭제 답글

    안녕하십니까
    영상처리를 공부하고 있는 학생입니다.
    현재 저는 이상적인 핀홀카메라를 가진다는 가정으로
    하나의 핀홀카메라에서 찍은 영상으로 얼굴인식을 한 후
    이것을 안면만 3d로 변환할 생각입니다. 일단은 2d인 원본이미지에서 2차원 좌표를 추출하고
    다크님께서 올려주신 글중에서 2차원좌표를 3차원 좌표로 변경하는 간단한 수식으로 취하고 난 뒤
    그 좌표를 이용하여 행렬을 만들어서 3차원으로 표현을 하고싶습니다.

    여기서
    첫번째로 3차원으로 어떻게 표현할것이냐라는 것에 많은 고민을 했었습니다. 아직 코딩으로 옴기진 않았지만 머리속으로는 정말 간단하게 될지안될지 모르겠지만 2d 영상에서 2x2 또는 3x3의 행렬로 마스크단위를 이용하여 affine 변환을 시키면 3d 처럼 보이지 않을까라는 생각입니다. affine 변환은 크게보면 영상전체를 변환점만큼 회전을 주는것인데 여기서 마스크단위로 접근하면 3d 처럼보이지 않을까 하는 막연한 생각입니다. 이것은 혹시라도 가능성이라도 있지는 없지만이라도 조언을 듣고 싶습니다.

    두번째로는 OpenGL을 이용하여 gluUnProject() 라는 함수를 이용하여 좌표계를 3차원으로 변경후 변경된 좌표를 기반으로 3차원 영상으로 변경하는 것입니다. 아직 OpenGL은 익숙하지 않아서 필요한 매개변수 또한 구하는방법을 공부하고있는데 이것이 가능한지만 여쭙고 싶습니다.

    아직 프로그램 설계단계라 머리속에서만 맴도는 생각으로 질문을 하는거라 두리뭉술한것에 대해 죄송스럽습니다. 하지만 가능성정도라도 아니면 힌트 또는 조언을 부탁하고 싶습니다.
    꼭 답변 부탁드립니다. 감사합니다.

    • BlogIcon 다크pgmr 2016.01.07 16:10 신고 수정/삭제

      하나의 이미지만 가지고 2d에서 3d를 추출하는 것을 불가능합니다.. 잘은 모르겠습니다만 일단은 사람 안면에 대한 별도의 3차원 모델이 존재해야 하고, 원본 이미지에서 안면에 대한 특징점들(눈, 코, 입, ...)을 뽑아서 모델과 매팽시킨후 그 사이의 점들은 보간해서 매핑시키는 형태로 진행해야 하지 않나 싶습니다.

    • 학생3 2016.01.09 21:47 신고 수정/삭제

      답변 감사드립니다.
      하나의 이미지에서 3d의 정보를 추출하는 것은 불가능한것은 알겠습니다.
      음 생각을 바꾸어 2d 이미지에서 wolrd 좌표계가 아닌
      화면상 2d 좌표를 내부 3d 좌표로 하는건 잘못된건지요?
      참고 소스입니다.
      http://gamepro.tistory.com/481

      http://developer.tonvolt.com/10

      http://blog.naver.com/kukuta14/60018178510

      http://gear4001.tistory.com/entry/opengl-%ED%99%94%EB%A9%B4%EC%83%81-2d-%EC%A2%8C%ED%91%9C%EB%A5%BC-%EB%82%B4%EB%B6%80-3D-%EC%A2%8C%ED%91%9C%EB%A1%9C-%EB%B3%80%ED%99%98%ED%95%98%EA%B8%B0

      위 사이트에서 나오는 소스코드들은 2d 좌표를 3d 좌표로 변경해준다는 소스들입니다. 이 소스들은 제가 할려고 하는 변환관계에 전혀 도움이 되지않는것들인지요? 현재 이러한 소스들을 분석중에 있습니다.
      좌표계만 구해진다면 opengl을 이용하여 폴라곤형식으로 구성해볼생각입니다. 꼭 답변부탁드립니다.

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

      2d 이미지에서 3d 정보를 복원하기 위해서는 스테레오 카메라나 키넥트 등과 같이 거리 정보를 반환해 주는 depth 센서를 사용하거나 또는 동일한 장면을 여러 각도에서 촬영한 후 structure from motion, epipolar geometry 기법을 이용해서 3차원 정보를 복원하는 방법이 있습니다.
      올려주신 소스는 제가 보지는 않았습니다만 말씀드렸다시피 2d 이미지에서 곧바로 3d 정보를 얻을 수는 없습니다. 아마도 거리(depth) 정보 등의 부가적인 정보를 이용한 것으로 생각됩니다.

  • BlogIcon 로봇 2016.04.26 20:04 신고 ADDR 수정/삭제 답글

    안녕하세요 블로그를 통해 얻고있는 정보가 많습니다. 글을 읽고 코딩하는 중 pan과 tilt가 모두 0일때는 항상 변환후 Zc의 값이 0인데 원래라면 기준점과 카메라 사이의 거리값이 나와야되지않나요. 이해가 쉽지 않습니다. 도와주세요...

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

      안녕하세요. 무언가 좀 이해를 잘못 하고 계신것 같은데요, 일단 카메라좌표계, 월드좌표계의 의미에 대해 http://darkpgmr.tistory.com/77 글을 참조하시면 좋을듯 싶습니다. 그리고 pan = tilt = 0일 때, R^-1 = [1 0 0; 0 0 -1; 0 1 0]이기 때문에 (Xc, Yc, Zc) = (X - X1, -Z + Z1, Y - Y1)이 됩니다. 즉, Zc = Y - Y1이 됩니다. 따라서 Y = Y1일 때만 0이고, 그 외에는 0이 아닌 값이 나옵니다. 어떻게 해서 항상 0의 값이 나오게 됬는지 모르겠네요..

    • BlogIcon 로봇 2016.04.26 20:23 신고 수정/삭제

      제가 실수했습니다. 감사합니다^^

  • 초보자 2016.08.11 18:06 신고 ADDR 수정/삭제 답글

    글을 보다 계속 머리속에 헷깔리는 것이
    카메라 회전행렬 R과 R_inv (R의 역행렬 표기)의 표현에 관한 것입니다.
    보통 월드좌표계에서 카메라좌표계로 변환시 적용되는 회전 행렬을 R로 표현하는지.. 아니면 R_inv로 표현하는건지요?
    여기 식(2)에서는 R_inv로 표현되어 있지만, 다른 게시글에서 solvePnP와 Rodriques로 산출된 변환 행렬을 R로 표현하고 있는데요.
    실제 적용해보니 여기 식(2)의 R_inv와 solvePnP에서 산출된 R이 같은 값을 가지는 것으로 확인되었습니다...그러면 solvePnP의 산출된 R을 R_inv로 봐야 할지....아니면 기준에 따라 달리 해석해야 할 지... 정리가 덜되어서 헷깔립니다.ㅠㅠ.


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

      네.. 제가 표기를 혼용하다 보니 혼동을 드린 것 같습니다. 본문의 식 (3) 밑에 해당 설명을 추가하였습니다. 일반적으로 R은 항상 월드좌표->카메라좌표 변환행렬입니다. 즉, 카메라좌표 = R*월드좌표 + t입니다(단, 이 글에서는 R이 반대의 의미로 사용되었습니다). solvePnP에서 반환하는 R도 월드좌표->카메라좌표 변환행렬입니다.

    • 초보자 2016.08.12 09:16 신고 수정/삭제

      시원한 답변 감사합니다.^^;
      잘 정리가 될 것 같습니다.

  • 초보자 2016.08.12 12:05 신고 ADDR 수정/삭제 답글

    다시 궁금한 사항이 있어 문의드려봅니다.
    식(1)에서 X축 회전에 대해서는 그냥 tilt값을 적용하지 않고 (-pi/2 + tilt)를 추가된 의미가 무엇인지 궁금합니다.
    "[영상 Geometry #5] 3D 변환"쪽 게시글의 X축 회전에 대한 행렬식과 다르게 표현되어 있어서...제가 뭔가 이해하지 못한 부분이 있는 것 같은데....설명이 가능하시면 좀 알려주세요.^^

    • BlogIcon 다크pgmr 2016.08.12 14:53 신고 수정/삭제

      그건 tilt의 정의를 확인하시면 됩니다.

    • 초보자 2016.08.12 15:32 신고 수정/삭제

      <그림1>에서 카메라 좌표계와 월드 좌표계의 각 축의 기준이 다르기 때문에 그런건가요?
      월드 좌표계 기준으로 봤을때 카메라 좌표계가 X축에 대해 -90도 회전되어 있는데 이것 때문에 tilt에 대해서만 -pi/2가 적용된 것인지요?

  • CG메인으로CV도하는사람 2018.06.06 11:46 신고 ADDR 수정/삭제 답글

    어쩌다보니 이쪽 계통 기술을 오래 잡고 있게 되어버린 사람입니다만, 이 내용은 연구하는 사람들과 한분야만 파고드는 사람들이이 흔히 범하는 "it's just an implementation issue"라고 줄여버리기에는 너무 복잡하고 심각한 문제가 얽혀있는데다, 쓸데없는 기술장벽조차 만들어 내고 있는 심각한 문제입니다. 따지고 들어가다 보면 결국 구현문제로 귀결될지 몰라도 (소프트웨어 분야에 안 그런 문제가 어딨는가? 싶긴 합니다만), 적어도 이 포스팅에서 설명하는 정도로 간략하게 요약될 성질의 것은 아니라 생각하는데, 어디에서도 이 문제의 심각성을 지적하는 분들은 잘 없더군요.

    경험상, 이러한 혼란의 원인은 크게 3가지정도 있는 듯 합니다.
    1. 3차원 그 자체의 복잡성,
    2. '그래픽스' 와 '비전' 이라는 분야가 독립적으로 발달되어 왔지만 용어가 비슷해서 서로 오해를 부르는 문제,
    3. 다양한 라이브러리와 통일되지 않은 좌표계 설정,

    흔히 1의 내용만 그 문제의 원인으로 생각들 하는 경우가 많은데, 저는 2와 3의 문제가 더 크다고 봅니다. 2의 문제에 대해, 당장 이 포스팅 질문글에도 CG 쪽을 메인으로 하시는 분들의 질문이 자주 보이는데요, 답변 하시는 분도 자신의 분야에서는 맞는 이야기지만 저쪽에서는 의미가 없거나 논점에 어긋난... 이렇듯 비슷한 듯 하면서도 질문과 대답방향이 완전히 어긋나있는 것이 당장 눈에 띄네요.

    분야가 다르다는 것에서 당장 크게 떠오르는게 "프로젝션 행렬"이라는 용어가 있네요, 이게 여러모로 오해를 부르기 딱 좋은게, 이름도 동일하고, 역할도 비슷한데 CG와 CV에서의 정의가 아예 다른 물건이 있습니다. 단적으로 일단 CV의 프로젝션 행렬은 3x4인데, CG는 4x4죠... 설명하자면 길어지므로 생략합니다만, 단순히 행 하나가 준 것이 아니라, 함의가 아예 다릅니다. 생각방식의 차이(CG: 2차원 이미지는 3차원 데이터를 렌더링 한 결과 / CV: 2차원 이미지로부터 3차원 데이터를 재구성)에 기인하는 문제인데. 부르는 이름이 같으니 여러모로 오해를 부르지요.

    3 또한 심각한 문제인데요, 마치 언어와 사고에 대한 사피어-워프 가설처럼 흔히 사용하는 라이브러리가 그 사람의 사고방식(좌표계설정)에도 영향을 미치기 때문입니다. 단적으로, classic 한 컴퓨터 비전하는 분들이 그리도 신성시 하는 Hartley & Zisserman 의 MVG 의 핀홀카메라 부분 확인해 보시면 카메라 좌표계가 Y가 up 으로 설정되어 있는데 반해, 이 포스팅에서는 아무렇지도 않게 카메라 좌표계는 Y를 down 으로 잡고 있지요. 아마 OpenCV 를 늘상 사용하셔서 그것이 포스팅 하신 분 사고에도 영향을 끼쳤다 보입니다.

    그게 뭐가 심각한 문제냐? AR, CG 분야 같이 단순히 비전계통 알고리즘만으로 끝나는 문제가 아닌 것을 하시다 보면 조금 더 와닿을 수 있겠습니다만. CV 주로 하시는 분들은 본인들 역할은 카메라 자세만 잘 뽑으면 된다 생각하시는 분들이 많고, 심하게 말하자면 3축 OpenCV 같은데서 제공하는 라인 드로잉으로 띡 그려놓고 "되지? 그러니까 너네가 잘 갖다 써." 로 끝인 경우를 보게 됩니다. 그런데, 이정도 수준의 모듈은 toy example 에나 통용되지, 제대로 된 물건을 만들기에는 여기저기 어려운 문제가 닥칩니다.

    일단 CG쪽에서 사용하는 라이브러리 보시면 좌표계 설정이 완전히 다른데요, 같은 우수계인 GL 좌표계조차도 기본 up 의 방향이 다르고 따라서 Z 축도 반대방향이 되지요. (CG에서 말하는) 프로젝션 행렬도 이 좌표계 설정에 따르므로, 카메라 행렬 혹은 (CV에서 말하는) 프로젝션 행렬도 여기에 맞춰야 합니다. DX 같은 좌수계로 가면 문제가 더욱 심각해 지지요.

    가끔 해결이랍시고 프로젝션 행렬을 아예 CV 식으로 고쳐버리는 경우가 왕왕 있습니다만, 단순 drawing 명령에는 그것으로 충분할 경우가 많지만, 셰이더나 기타 복잡한 기능을 사용할 때 문제를 안 일으켰던 경우가 별로 기억에 없네요. 특히 물리엔진 같이 설정 조금만 건드렸다가 다 개판되는 경우, 카메라 및 월드 좌표계는 함부로 고치기도 문제가 있기에, up 과 카메라는 라이브러리 설정에서 벗어나지 않도록 해야 하는데, 비전'만' 하는 분들은 이런 부분을 과소평가 하더라고요. 애초에 본인들 좌표설정만 고치면 되는 문제인데 말이지요.

    • BlogIcon 다크pgmr 2018.06.07 13:27 신고 수정/삭제

      이런 댓글을 받다니 한편으로 생소하고 또 재미가 느껴집니다. 사람은 아는 만큼만 보고 이해할 수 있다 보니 저로서는 머리만 긁적이고 있네요.
      그런데, 카메라 Y축을 down으로 잡은 것은 어디서 보고 한 것은 아닙니다. 사실 처음에는 up 방향으로 Y축을 잡고 나름 식들을 세웠었는데요, 이게 이렇게 해서 만든 식들이 뭔가 자연스럽지 않고 자꾸 꼬이는 겁니다. 그러다 나중에 Y축을 down 방향으로 바꾸게 되었는데 모든 식들이 정말 딱딱 맞아 떨어지고 만족스러웠습니다. 그런데, 이게 이미지 좌표 방향과 밀접한 관련이 있는 문제였네요..
      저도 일전에 ar 때문에 그래픽스 함수를 몇번 사용해 본 적이 있는데요, 카메라 자세를 그래픽스 모델에 맞게 변환하는 것이 보통 어려운 일이 아니었습니다. 결국은 카메라의 회전각 성분(오일러 앵글)들을 추출한 후 다시 프로젝션 행렬을 구성하는 방법으로 어찌 어찌 해결은 했습니다만.. 그 좌표축의 차이로 cv와 그래픽스의 접점에서 얼마나 많은 문제가 발생할지 미루어 짐작이 갑니다. 어쨌든 분야마다 나름 체계와 이유가 있다 보니 일정 부분은 이해해야 하지 않나 싶습니다.

    • CG메인으로CV도하는사람 2018.06.07 23:13 신고 수정/삭제

      네, 이미지'만' 생각하면 Y-down 이 참 자연스러운데 말이지요. 하다못해 윈도우 좌표계도 Y-down 이니까요.
      사실 그래픽스 라이브러리를 처음 만질 때도 위-아래 문제는 당혹스럽습니다. 그래픽스 라이브러리는 Y-up이 기본이라 카메라 좌표를 Y-up 에 맞추다 보니 캡처나 인터랙션 프로그램 등에서 생각없이 하다가는 위아래 뒤집히는 문제가 왕왕 나옵니다.

      그런데, 참 모순적인데요, 이미지는 그냥 내가 관찰하기 위한 수단일 뿐이고 그 내부(?)의 3차원 물체를 메인으로 생각하기 시작하면, 그건 또 Y-up 이 굉장히 자연스럽다 느껴집니다. 핀홀카메라가 원리상으로는 상이 뒤집어지지만 아무도 그런것을 고려하지 않듯, 중간의 디테일은 쓸데없고 결과만 보고 싶어하는게 인간이라는 생물의 본성인가 봅니다.

      여튼, 이 두가지의 중간 절충지점과 좌-우수계 변환의 수단으로 world를 Z-up으로 두는 경우가 있긴 한데, 이게 또 모든 라이브러리가 그렇게 짜여진 것은 아니라서, 결국 어딘가에서는 누군가가 삽질을 하지 않을 수 없는 구조가 만들어집니다 (적어도 제가 경험한 한에서는 모두 그랬던 듯). 그냥 대~충 돌아가게 보이는 수준이라면 문제 없게 속이고 넘어갈 수도 있는데, pixel-by-pixel 로 따질 필요가 있는 성질의 일을 하면 이렇게는 못 넘어가지요.

      저도 이런저런 관계로 CG-CV 라이브러리 간의 변환을 많이 경험해 봤지만 할 때마다 새롭고, 결국 삽질은 필요불가결하게 반복하게 되는 것은 정말 어쩔수 없는 문제인가 봅니다...

  • BlogIcon DRAGONITE 2018.06.10 17:06 신고 ADDR 수정/삭제 답글

    안녕하세요. ^^ 좋은 글 감사합니다.!!
    제가 다크님 정보를 통해서 3D to 2D를 해본 경험이 있는데요.
    최근 관련 연구(Slam)에서 2D를 3D로 변환해야하는 과정이 필요합니다....
    모노카메라를 사용해서 2D를 3D로 변환할 수 있나요...?

    • BlogIcon 다크pgmr 2018.06.10 19:46 신고 수정/삭제

      이미지 한장으로는 안되고요, 이미지 여러 장이 있으면 가능합니다.

  • 안녕하세요! 2018.09.11 00:56 신고 ADDR 수정/삭제 답글

    안녕하세요. 다크프로그래머님. 항상 잘 보고 있습니다.

    다름이 아니라 두개의 카메라 간의 R / T 를 구하고 싶은데 머리가 너무 복잡하네요 ㅠㅠ
    하루종일 혼자 생각해봤는데 방도가 잘 떠오르지 않아 댓글 남깁니다.

    두개의 카메라를 한개의 월드좌표계에 대하여 보정을 완료하였고요.

    Camera1 : RC1, TC1
    Camera2 : RC2, TC2

    그렇다면 Camera1, Camera2 간의 R, T 는 어떻게 표현될까요?

    Camera1 좌표계 상의 좌표를 Camera2로 옮기는 것 까진 가능한데
    이 두개의 좌표계 간의 R / T 를 표현하는 방법을 모르겠네요.

    Camera1 좌표계상의 좌표 > World 좌표계
    inv(RC1)*(Camera1 Point - TC1).

    이렇게 나온 월드 좌표계 기준 좌표를 다시

    RC2 * (World Point) + TC2

    이렇게 계산하면, 카메라1 좌표계 상의 좌표를 카메라2 좌표계 상의 좌표로 옮기는것 까지는 이해가 가는데 ㅠㅠ

    Camera1 - Camera2 간의 R / T 를 RC1, TC1, RC2, TC2를 이용해서 나타낼 수 있을까요?

    • BlogIcon 다크pgmr 2018.09.11 09:25 신고 수정/삭제

      문제를 직접 풀으시려는 것이 보기 좋습니다. 제가 보기에는 이미 문제를 다 풀으셨는데요, w = inv(R1)(c1-t1), c2 = R2w+t2 를 연립하면 c2 = R2(inv(R1)(c1-t1))+t2 = R2inv(R1)c1 - R2inv(R1)t1 + t2 이네요. 그러니, c1->c2의 R = R2inv(R1), t = - R2inv(R1)t1 + t2 입니다.

  • 캘린이 2018.10.22 11:34 신고 ADDR 수정/삭제 답글

    안녕하세요 다크프로그래머님 좋은 글 감사합니다.

    좌표계 변환에서 질문이 있습니다. 위에 올려주신 내용은 월드 좌표계를 R 행렬을 구해서 카메라 좌표계로 변환하는 방법을 작성해주셨는데,

    그러면 반대로 카메라 좌표계를 월드 좌표계로 변환하는 과정은 저 (3)번 식에서 [Xc, Yc, Zc] 를 [X, Y, Z] 로 서로 바꾸는 즉, 서로 위치만 바꾸고 R행렬도 역행렬이 아닌 (1)의 R식을 사용하여 구하면 되는것일까요?

    그리고 혹시 그 식에서 X1,Y1,Z1 이 카메라 원점이라고 하셨는데 그게 월드기준에서의 카메라의 실제 X,Y,Z를 뜻하는것인가요??

    • BlogIcon 다크pgmr 2018.10.22 20:52 신고 수정/삭제

      질문1) 식을 다시 정리하면 됩니다. Xc = R^-1(Xw - X1)을 다시 정리하면, Xw - X1 = RXc 에서 Xw = RXc + X1와 같이 변환됩니다.
      질문2) 네 그렇습니다.

  • miso77 2018.11.28 15:39 신고 ADDR 수정/삭제 답글

    안녕하세요. 관련 작업을 하면서 다크프로그래머님 블로그 도움을 너무나 많이 받고 있어 늦었지만 감사 드립니다. 그 동안은 블로그 참조하여 구현을 하는쪽에 초첨을 맞춰다면 이해를 하고 싶어 다시금 보고 있는데요. 궁금한 부분이 있어 문의를 드립니다.

    http://darkpgmr.tistory.com/122 이 글을 보면(카메라의 위치 및 자세 파악)
    solvePnP로 구한 R, T를 이용하여 월드좌표에서 카메라좌표 또는 그 반대 변환을 할 수 있습니다.
    실제로 solvePnP로 구한 R의 성분을 보면 모든 성분이 0이 아닌 값을 가집니다.
    (R, T를 갖고 카메라 위치를 구하거나, triangulation등을 수행하면 맞게 나오는 걸로 봐서는 잘 구한 것 같습니다.)

    그런데, 여기 글을 보면 R 성분 중 하나가 0([2][0])이 됩니다. (Rinv도 마찬가지)
    solvePnP로 구한 R과 위에서 언급하신 pan, tilt로 얻은 R이 동일한 회전행렬을 의미하는거 같은데요.

    회전행렬이 다를 수가 있는 것인지 아니면 제가 착각을 하고 있는 것인지 궁금합니다.


    • BlogIcon 다크pgmr 2018.11.28 18:54 신고 수정/삭제

      그건 제가 카메라의 roll을 0으로 놓고 식을 세웠기 때문입니다. roll이 0이 아니라면 임의의 행렬이 가능합니다.

  • 휴... 어렵다 2018.11.30 14:44 신고 ADDR 수정/삭제 답글

    안녕하세요 블로그 글 많이 참고하여 도움이 됐습니다. 여쭤보고싶은게 있는데요
    일단 제가 하는 작업은 카메라에서 보이는 물체에 달려있는 가속도센서 값을 추정하는 작업입니다.
    여기서 제가 어려워하는 포인트는 가속도센서는 자기의 센서 축을 가지고 가속도값을 산출할텐데( 제생각에는 이부분이 월드 좌표계라고 생각합니다) 그거를 카메라가 보는시점은 카메라 좌표계이기때문에 카메라좌표계를 월드 좌표계로 바꿔야 한다고 생각하는데요 이 포스팅 내용과 연관시키면 쉬울거같은데 관련지식이 부족해서 잘 연관이안되네요 ㅜㅜ 혹시 도움받을수잇을까요

    • BlogIcon 다크pgmr 2018.11.30 18:09 신고 수정/삭제

      카메라가 움직인다면 거의 불가능할 것 같구요, 카메라 위치가 고정인 경우라면 카메라좌표계를 월드좌표계로 설정하면 될 것 같습니다.
      그런데, 카메라로 가속도를 측정하는 것보다는 가속도 센서에서 나오는 값을 사용하는 것이 좀더 간단하고 정확할 것 같은데요, 어떤 이유에서 카메라가 필요한지 궁금하네요.

  • miniont 2018.11.30 16:30 신고 ADDR 수정/삭제 답글

    비젼만 15년 넘게 했는데, 항상 수식 계산에서 막힐 때 해결책을 주는게 다크님 페이지입니다. 늘 고맙게 생각됩니다. 공부를 제대로 안하고 먹고사는게 창피하네요.

    • 곰돌이만세 2018.11.30 17:49 신고 수정/삭제

      저도 그렇습니다. 막히면 다크님에게로...
      부끄럽지만 또 노력계속하면 좋은 결과가 올겁니다.

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

      저도 수식만 나오면 머리가 멍해지고, 이건가 저건가 따지다 보면 몇 시간이 훌쩍 지나가곤 합니다. ^^