가상 3D 영상 생성 프로그램

개발한 것들 2013.08.01 15:58

3차원 도형을 카메라로 봤을 때, 카메라의 위치 및 방향에 따라 어떤 영상이 얻어질지를 보여주는 프로그램입니다.


카메라의 시점에 따라서 이미지가 어떻게 바뀌는지 확인할 때 유용하게 활용될 수 있을 것이라 생각합니다. 또는 역으로 이미지로부터 카메라 시점을 알아낼 수 있는지 확인하는 용도로도 사용 가능합니다.


<실행 동영상 샘플>


기능 및 사용법


본 프로그램의 GUI(사용자 인터페이스) 및 샘플 화면은 다음과 같습니다.


<gui 화면>


<샘플 화면>



키보드의 화살표 키, Shift/Ctrl+화살표 키를 이용하여 카메라의 시점을 자유롭게 바꿀 수 있습니다. 화살표 키는 전진, 후진, 제자리 회전을 하고, shift 또는 ctrl 키를 같이 누르면 카메라 틸트(tilt) 조절, 옆으로 이동을 합니다.


카메라의 높낮이 조절은 PgUp, PgDown 키를 이용합니다.


총 4가지 종류의 도형(평행선, 사각형, 박스, 사다리)을 선택할 수 있으며 도형 꼭지점들의 3D 공간좌표 혹은 픽셀좌표를 볼 수 있습니다. 평행선의 경우에는 위 그림처럼 이미지에 투영된 두 선이 이루는 각을 부가적으로 보여줍니다.


<좌: 공간좌표를 출력한 경우, 우: 픽셀 좌표를 출력한 경우>


좌표계 설정 및 팬(pan), 틸트(tilt) 기준은 3D 좌표계 변환 방법 (예: 월드좌표계 - 카메라 좌표계) 글에서 설명한 내용과 동일합니다.


프로그램 다운로드


ImagingGeometry3D.zip (UI 부분을 제외한 소스코드 포함)



프로그램 용도


이 프로그램은 여러가지 목적을 가지고 구현한 것입니다.


한가지 목적은 최근 [컴퓨터 비전에서의 Geometry #1] 좌표계 ~ [컴퓨터 비전에서의 Geometry #7] Epipolar Geometry 시리즈 글을 올리면서 사용했던 카메라 기하 모델이 정말로 맞는지 확인할 목적이 있었는데 실제로 구현해 보니 잘 맞는 것 같습니다.


다른 목적은 카메라의 높이 및 각도에 따라서 영상이 어떤 특성을 가지고 변하는지 파악하기 위함입니다. 예를 들어, 차선인식 문제에 있어서 차선 영상만 가지고 촬영한 카메라의 위치, 높이, 팬, 틸트를 알아낼 수 있는지 여부를 확인하는 용도로도 사용할 수 있습니다.


마지막으로, 외부(extrinsic) 카메라 캘리브레이션 알고리즘 혹은 위치인식 알고리즘이 정상적으로 동작하는지 여부를 확인하는 용도로도 사용가능합니다. 프로그램에서 다양한 카메라 시점에 따라 영상좌표를 획득할 수 있기 때문에 이들 영상좌표를 입력으로 외부 캘리브레이션(extrinsic calibration) 혹은 위치인식 알고리즘을 적용하여 원래 카메라 시점이 복원되는지 확인해 볼 수 있습니다.


☞ 참고로 영상왜곡 모델도 반영은 됩니다만, 현재의 구현은 꼭지점들만 투영시킨 후 직선으로 연결하는 방식이라서 직선의 휘어짐이 표시되지는 않습니다.


by 다크 프로그래머


저작자 표시 비영리 변경 금지
신고

'개발한 것들' 카테고리의 다른 글

Ferns Detector  (17) 2013.08.28
가상 3D 영상 생성 프로그램  (16) 2013.08.01
화면캡쳐 녹화 프로그램 (DarkCap)  (29) 2013.06.26
Haar/Cascade Training 프로그램  (150) 2013.06.05
  • 펄그라스 2013.08.01 17:56 신고 ADDR 수정/삭제 답글

    제가 찾던 유틸 입니다^^; 잘 사용하겠습니다. 감사드립니다 꾸벅~~
    영상에서 카메라 각도등 촬영 조건을 유추해 보고자 많이 고민 하였습니다.
    제 능력으로는 한계가 있더군요...ㅠㅜ
    다크님은 문제해결능력, 수학적인능력, 코딩능력은 정말 최고이신 듯 합니다.
    글을 쓰는 순간..엔지니어로써...많은 생각들이 듭니다..
    추후에 기회가 된다면 오프라인에서 뵙는 기회를 주신 다면 영광으로 생각하겠습니다..
    항상 감사 드립니다.

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

      ^^ 사실 펄그라스님 메일에 대한 답변도 겸해서 구현한 프로그램입니다. 직접적인 답변은 아니지만 연구하시는데 도움이 되길 바랍니다.

  • 최환수 2013.12.05 18:14 신고 ADDR 수정/삭제 답글

    안녕하세요 CCTV NVR(network video recorder)개발자 최환수라고 합니다.
    현재 구현하려고 하는 기능은 PTZ on display라는 것인데요.
    카메라 화면에서 마우스로 어딘가를 클릭하면 해당 지점으로 카메라가 움직여서 그 지점이 센터로 맞추게 하는 기능입니다.
    구현은 카메라의 화각으로 이미지의 가로와 세로로 치환을 한다음 변화량 만큼 팬, 틸트를 동작시키려고 합니다. 물론 화각은 줌 값에 따라 변환을 주고요. 가로 세로 화각도 좀 틀리고요.
    그런데 틸트값이 0도일 경우에는 dx만큼 팬을 그리고 dy만큼 틸트를 움직이면 잘 동작합니다.
    그리고 틸트값이 90도일 경우에는 y축과 클릭한 좌표와의 각만큼 팬을 돌리고 sqrt(dx*dx + dy*dy)만큼 틸트를 움직이면 해당 좌표로 갑니다. 이 두가지를 잘 조합하면 여러 틸트각에 대한 팬, 틸트의 움직여야할 값을 찾을수 있을꺼 같은데요...
    이게 생각처럼 안되네요. 그래서 이렇게 조언을 부탁드리려 합니다.
    접근 방법이 맞는지도 사실 모르겠습니다. 도움 부탁드립니다. 약간의 힌트라도 부탁드려요.
    chs2000@dreamwiz.com 혹시 몰라 제 이메일도 남기겠습니다.

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

      안녕하세요. 말씀하신 내용에 비추어 보았을 때, 카메라가 천장에 매달려 있으며 바닥을 보면 틸트가 90도, 수평을 보면 틸트가 0도인 세팅으로 생각됩니다. 일단 전제조건은 현재 카메라의 절대적인 팬, 틸트를 알수 있어야 합니다. 현재의 팬,틸트 값을 알지 못한다면 해결 방법이 없습니다. 하지만, 만일 현재 카메라의 팬,틸트 값을 알수 있다면 다음과 같은 방식으로 해결하면 좋을 것 같습니다. 먼저, 현재 위치에서 카메라가 팬=0, 틸트=0인 지점으로 이동했을 때의 타겟 지점의 영상내 위치를 예측합니다. 이후 팬=0,틸트=0인 상황에서 타겟 지점으로 이동하기 위해 필요한 타겟 팬,틸트 위치를 계산합니다. 마지막으로 현재 팬,틸트 위치에서 타겟 팬,틸트 위치로 이동하기 위해 필요한 상대적인 차이만큼만 이동시키면 타겟 위치로 이동할 수 있을 것 같습니다.
      그리고, 절대적인 팬,틸트 값을 알 수 없을 때에는 영상만 보고 이동치를 계산하는 것은 불가능하기 때문에 일단은 임의로 카메라의 팬,틸트를 약간 움직여본 다음에 타겟 지점으로 이동하기 위한 상대적인 모션을 계산해 내는 방법밖에는 없을 것 같습니다.

  • 최환수 2013.12.06 12:31 신고 ADDR 수정/삭제 답글

    답변을 해 주셔서 정말 감사합니다.
    말씀하신데로 절대적인 팬,틸트값은 각도로 얻어올수있습니다.
    그리고 절대값(각도) 팬,틸트를 움직일 수도 있습니다.
    그 상태에서 카메라 좌표만을 이용해서 내가 원하는 위치로 카메라를 움직이는 것인데요.
    다크님의 프로그램이나 홈페이지 내용을 보면 3D좌표를 이용하잔아요.
    그런데 단순히 카메라 좌표만을 이용해서 팬,틸트를 움직이는게 가능한건지 그것도 의문이 들어요.
    일단 카메라 좌표를 화각으로 치환해서 틸트각이 0도일때는 카메라 좌표의 dx, dy만큼 팬, 틸트를 움직이면 거의 정확하게 가는걸로 봐서 z좌표, 즉 depth를 몰라도 움직이는게 가능한거 같긴 한데요.
    틸트각이 커질수록 계산식을 어떻게 해야할지 모르겠습니다.
    현재는 틸트각에 따라서 수동으로 더하고 빼고 하는 표를 만들어 대입을 하고있는데 너무 원시적인거 같아서 이렇게 도움을 청합니다.
    이렇게 답변해 주셔서 정말 감사합니다.

    • BlogIcon 다크pgmr 2013.12.06 18:26 신고 수정/삭제

      depth는 크게 상관 없는 것으로 보입니다 (원칙적으로는 depth와는 전혀 무관하지만 카메라의 팬,틸트 회전축이 카메라 초점이 아니라서 약간의 영향은 있겠습니다. 하지만 영향이 크진 않을 것으로 생각됩니다)
      이동 방법은 좀더 생각해 보니 앞서 제가 답변드린 방식은 잘 동작하지 않을 것 같고.. 말씀하신 데로 3D 공간에서 타겟 지점의 팬,틸트를 계산해야 할 것 같습니다 (depth는 관계없고, 카메라 초점과 타겟 지점을 잇는 직선의 방향이 중요). 좀 식을 세워봐야 할 것 같은데 저도 언뜻 쉽게는 생각나지 않습니다. 저도 한번 생각해 보고 다음주 정도에 시간이 되면 다시 답변을 드리도록 하겠습니다.

    • BlogIcon 다크pgmr 2013.12.10 13:24 신고 수정/삭제

      댓글로 적기에는 내용이 좀 있어서 별도 글로 포스팅을 올렸습니다. http://darkpgmr.tistory.com/113 글을 참고하시기 바랍니다.

  • 펄랑 2014.11.23 20:08 신고 ADDR 수정/삭제 답글

    안녕하세요 다크님
    재미있는 개인용 프로그램을 좀 만들어보고자 소스코드를 참고하여 코딩을 하고 있는데 한가지 문제가 생겨 여쭈어 봅니다.
    World Coordinate 좌표를 입력으로 주어 영상 픽셀 좌표와 depth 값을 반환 받는데 영상 내부에 표현이 안되는 점인 경우 depth 가 음수가 나오면서 올바르지 않은 영상 좌표가 반환돠는 경우가 발생하는 문제입니다.

    예를 들어 올려주신 프로그램의 설정을
    Ladder 패턴/ 카메라 포즈를 0.5 1.6 0.5 pan 0 tilt -21 정도로 주면 사다리를 바닥에 눞여놓고 약간 내려다보는 것 같은 결과가 나오는데 이 때 화면에 나오는 8개의 점 말고 나머지 점 4개는 함수가 반환하는 값을 살펴보니 완전 엉뚱한 값이 나오는 것 같습니다.(제 생각에는 화면에 표시는 안되더라도 대충 다른 점들을 이은 연장선 상에 있어야 할 것 같은데 그렇지 않네요)
    이때 이들의 depth 반환 값이 모두 음수라는 공통점이 있습니다.

    이를 어떻게 해석하면 좋은지... 또 어떤 방법으로 해결해야 할 지도 궁금합니다.

    • BlogIcon 다크pgmr 2014.11.24 10:44 신고 수정/삭제

      안녕하세요. 좋은 포인트에 대해 질문을 주신 것 같습니다.
      설명을 위해 먼저 depth에 대해 짚고 넘어가는게 좋겠습니다. depth란 카메라의 초점과 물체 사이의 수평거리를 의미합니다 (카메라의 광학축과 평행한 방향으로 측정한 거리). 자신의 눈이 카메라의 초점이고 눈앞 10cm 전방에 이미지 평면이 있다고 상상해 보겠습니다. 이때 이미지 평면에 맺히는 상은 자신의 눈과 물체를 잊는 선이 이미지 평면과 만나는 점들에 의해서 생성이 됩니다. 먼저, depth가 10cm 이상인 물체들은 카메라의 시야각에 따라서 이미지에 나타날 수도 있고 나타나지 않을 수도 있습니다. 하지만 depth가 10cm 이하인 물체들은 카메라의 시야각에 관계없이 실제로는 이미지에는 나타날 수 없는 위치에 존재하고 있습니다 (물리적으로 이미지에 상이 맺힐 수 없다는 의미). 물론 눈과 물체를 잊는 선을 연장하여 이미지 평면에 가상의 상을 투영할 수는 있을 것입니다.이 경우 depth가 점점 작아져서 0에 근접하면 초점과 물체를 잊는 선은 이미지 평면과 거의 수평이 되기 때문에 물체의 가상의 상은 이미지 테두리 쪽으로 무한대 떨어진 위치에 맺히게 될 것입니다. depth가 0을 넘어서서 음수가 된 경우는 가상의 상조차도 생각할 수 없는 경우로서 이러한 경우에는 영상좌표를 계산하는 것 자체가 의미가 없다고 생각합니다. 즉, 영상좌표에 대해서 기하학적인 의미를 두는 것은 물체의 위치가 이미지 평면 너머에 있을 경우로 한정하시면 좋겠습니다 (위 예의 경우에는 depth>=10cm). 말씀하신 depth 문제를 실제 구현하는 방법에 대해서는 좋은 방법을 직접 찾아 보시는게 좋겠습니다. 참고로 선분 형태로 구성된 도형을 투영할 때에는 선분의 직선 방정식과 이미지 평면의 교점을 직접 구하여 depth 문제를 처리하는 방법도 가능할 것으로 생각됩니다.

  • 안녕하세요 2015.04.01 19:14 신고 ADDR 수정/삭제 답글

    안녕하세요 Stereo Vision에 대해 공부 중인 석사생입니다.
    혹시 위의 프로그램은 OpenGL이나 다른 라이브러리를 사용하지 않고 만든신건가요?
    아니면 기본적으로 제공되는 라이브러 GDI와 같은 것을 사용해서 만드신건가요?
    요새 OpenGL 공부 중이라 뜬금없는 궁금증이 생기네요 ^^

    • BlogIcon 다크pgmr 2015.04.02 07:54 신고 수정/삭제

      안녕하세요. 따로 외부 라이브러리는 사용하지 않고 그냥 손으로 일일히 그렸습니다. 은선과 잘리는 부분을 판단하고 처리하는데 고생을 좀 했습니다 ^^ OpenGL을 사용한다면 좀더 손쉽게 처리할 수 있을 것이라 생각합니다.

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

    좋은 지식의 공유에 감사드립니다.
    첨부된 코드의 자료를 보니 카메라의 Yaw,Pitch는 사용되나 Roll 값은 고려가 안되었던데, 만약 Roll값을 적용하려면 Camera matrix는 어떤 형태로 구할 수 있는지 궁금합니다.

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

      일단 camera matrix라는 용어는 rotation matrix라고 표현해야 맞을 것 같습니다. pitch, roll, yaw로부터 대응되는 rotation matrix를 구하는 방법은 2가지가 있습니다. 회전변환 행렬을 조합하는 방법과 좌표축 단위벡터를 이용한 방법입니다.
      http://darkpgmr.tistory.com/84 글을 참조하시기 바랍니다.

  • BlogIcon DRAGONITE 2017.11.22 12:48 신고 ADDR 수정/삭제 답글

    안녕하세요!!
    opencv 를 주로 사용하면서 2D 이미지 처리에 대해서는 감을 잡아가고 있습니다.
    혹시 3D 데이터는 어떤 점이 가장 다른가요. 또한 입문자가 공부할 만한 자료 추천 부탁드려도 될까요? 막연하게 3D는 데이터 데이터 다루는 것이 어렵게 느껴지네요..

    • BlogIcon 다크pgmr 2017.11.22 15:52 신고 수정/삭제

      이미지는 3차원의 현실 공간을 2차원 평면에 투영시킨 것이라고 볼 수 있는데요, 2차원의 이미지 정보로부터 3차원의 원래 공간을 복원하고자 하는 것이 3D 비전입니다. 3D 비전 쪽은 보통 책을 보는데 "multiple view geometry in computer vision" 이라는 책을 많이 봅니다. 그런데, 영어이고 수식 등 체계적인 공부가 필요해서 보는게 쉽지는 않습니다. 한글 서적 등 간단하게 공부할 수 있는 자료는 제가 아는 한은 별로 없는 것 같습니다.

    • BlogIcon DRAGONITE 2017.11.22 17:20 신고 수정/삭제

      답변 감사합니다. 공부하다보니, 한글자료는 구하기 쉽지 않아서, 영어로도 차근차근 읽어보는 습관을 들여야겠습니다!!