구가 2D Image에 프로젝션 됬을때 반지름 픽셀.
조회수 537회
3차원 구가 2D Image에서는 원으로 투영되는 것으로 알고 있습니다. 물론 완전한 원은 아니고 카메라의 성능에 따라 원에 가까워지는 것으로 알고 있습니다.
그래서 원의 반지름 픽셀을 가지고 카메라와 상대적인 Z좌표를 구할수 있지 않을까라는 생각이 들어 확인해보고 있었는데 실제 실행해본 결과가 이론과 대치되서 질문드립니다.
ios Scenekit에서 Sphere와 Camera를 만들어 Test 하였습니다.
- Sphere World Coordinate : (0, 0, 0)
- Sphere Radius : 0.1
- Camera World Position : (0, 0, 0.3)
- Camera Fovy : 45 degree
- 2D Image 해상도 : 2224 * 1668
기준이고 공식은 stack overflow를 참고하였습니다.
// Z : Camera Coordinate Z Distance
// Clip Space 기준 아마 Pixel = clip radius * Resolution.y
approximate radius on screen[CLIP SPACE] = world radius * cot(fov / 2) / Z
그런데 계산한 픽셀과 실제 이미지에서의 원의 픽셀이 다른 현상이 있습니다.
계산한 픽셀은 약 671 pixel이나오고 실제 이미지에서의 원 반지름 픽셀은 약 712 pixel 정도 나오고 있습니다. 이 상황에서 Z 값을 0.3이라고 생각하고 계산하였는데 그게 잘못인건지 아니면 뭔가 놓치고 있는 부분이 있는건지 모르겠습니다.
카메라쪽 수학 전문가이신분들이 보기에 제가 뭔가 빠뜨린 부분이 있나요??
심지어 저는 Scenekit에서 제공하는 3d point가 image에 어느 2d point에 맻히는지 계산해주는 함수를 사용하여 (0, 0, 0) 그리고 보이는 원의 끝 (0, 0.1, 0)이 2d의 어느 점에 맻히는지 두 차이를 계산한 픽셀수가 저 위에 계산식으로 계산한 픽셀수와 같은 것을 확인하였습니다. 하지만 실제 이미지에서의 원의 픽셀수와 차이가 나니 너무 의문입니다...
1 답변
-
일단 fov가 있다는건 원근 투영인거고, view frustum이 어떤지, viewport와 near z값 혹은 focal length 등등이 있어야 정확한 계산이 가능할듯 싶지만... 일단 기본값을 대충 유추해 보고 오류를 잡아 보자면,
현재 구한 671은 뷰포트에 맺힌 상(원)의 반지름이 아닙니다.
링크주신 스택오버플로의 답변중에 나와 있는 그림에서
빨간 선에 해당하는 부분(구의 반지름에 해당)의 길이를 구한것처럼 보입니다.
(정확한건 아닙니다만, 그래 보입니다.)
실제로 상은 z가 0인 평면에 맺힌다고 가정했을 때,
위의 그림 처럼 평면에 맺힌 상의 길이를 구해야 합니다.
카메라와 뷰포트의 모든 factor를 알 수 없고 뭔가 애매하게 알려주신 부분이 있기에 처음부터 구할 수는 없지만,
671이란 값이 첫 번째 그림의 길이를 구한게 맞다는 가정 하에 검증을 해 볼 수 있습니다.
계산의 편의를 위해 아래 그림처럼 기호를 매겨볼게요.
상의 반지름의 길이는 삼각형의 닮음과 위대한 피타고라스 정리 및 삼각함수를 통해 구할 수 있습니다.
OC = 0.3 OH = 0.1 CH = (0.3 ^ 2 - 0.1 ^ 2) ^ 0.5 = 0.282842712 angle = OCH cos(angle) = CH / OC = 0.94280904
닮음에 의해서
OH / OR' = cos(angle) OR' = 0.1 / 0.94280904 = 0.106066017
월드 좌표계상으로 0.106066017 위치의 점에 있는 값을 구해야 합니다.
위에서 말한 Scenekit의 함수를 적용하려면 (0, 0.1, 0) 이 아닌 (0, 0.106066017, 0)을 넣어야 하는 것이죠.
아무튼 검증을 위해서 계속 계산을 해보면,
위의 값에 비례식을 적용할 수 있습니다.
0.1 위치인 경우의 반지름 값이 671이라면, 0.106066017 위치인 경우의 반지름 값 X는?
0.1: 671 = 0.106066017: X X = 671 * 0.106066017 / 0.1 = 711.70297407 = 약 712
대략 712가 나옵니다. 이게 계산으로 구한 값이고 실제 보이는 원의 반지름과 거의 맞아 떨어지죠.
이걸로 잘못된 값을 지정하여 구했다는 것이 확인 되었습니다.
투영에 의해 2차원에 맺히는 상은 3차원 세계의 물체에 생기는 그림자를 생각해 보시면 됩니다. 점광원으로 부터 나온 빛이 구의 그림자를 어떻게 만들지 상상해 보시면 이해하기 좀 더 수월할거에요.
- https://stackoverflow.com/questions/21648630/radius-of-projected-sphere-in-screen-space 안그래도 이 문제 고민하다가 관련해서 stack overflow의 다른 글이 있었습니다. 2d image에서 원의 끝이 (0, 0.1, 0)이 아니라는 사실을 한참 뒤에 알게되고나서 이해하니 그렇게 나오네요... 감사합니다 ^^ 은원기 2020.5.6 23:14
댓글 입력