相機
相機座標系統
使用 3D 資料時,使用者需要了解 4 個座標系統
- 世界座標系這是物件/場景存在的系統 - 世界。
- 相機視角座標系這是有其原點在影像平面的系統,且
Z
軸垂直於影像平面。在 PyTorch3D 中,我們假設+X
指向左,+Y
指向上,+Z
指向出影像平面。從世界座標轉換到視角座標會在應用旋轉 (R
) 和平移 (T
) 後進行。 - NDC 座標系這是將物件/場景渲染部分限制在一個體積內的正規化座標系。也被稱為視角體積。對於方形影像,根據 PyTorch3D 公約,
(+1, +1, znear)
是左上角的近角,(-1, -1, zfar)
是體積中的右下遠角。對於非方形影像,XY
中較小邊的體積側從[-1, 1]
延伸,較大邊則從[-s, s]
延伸,此處s
是長寬比,且s > 1
(較大邊除以較小邊)。從視角座標轉換到 NDC 座標會在應用相機投影矩陣 (P
) 後進行。 - 畫面座標系這是視角體積的另一個表示,其中
XY
座標定義在畫素空間中,而不是正規化的空間中。(0,0)是左上角頂點的左上角,而(W,H)是右下角頂點的右下角。
以下為 4 個座標系統的圖示
與 PyTorch3D 渲染器介接
網格和點雲的 PyTorch3D 渲染器假設相機轉換後的點 (表示傳遞至光柵器作為輸入的點) 在 PyTorch3D 的 NDC 空間中。因此,為了取得預期的渲染成果,使用者必須確保他們的 3D 輸入資料和相機遵守這些 PyTorch3D 座標系統假設。PyTorch3D 座標系統假設 +X:左邊
、+Y:上邊
和 +Z:由我們指向場景
(右手)。對於座標系統的混淆是很常見的,因此我們建議您花點時間了解您的資料以及它們所處的座標系統,並且在使用 PyTorch3D 渲染器之前適當地進行轉換。
相機範例以及它們如何與 PyTorch3D 渲染器介接可以在我們的教學課程中找到。
相機類型
所有相機都繼承自 CamerasBase
,它是所有相機的基本類別。PyTorch3D 提供四種不同的相機類型。CamerasBase
定義了所有相機模型共用的方法
get_camera_center
,返回世界座標中相機的光學中心get_world_to_view_transform
,返回從世界座標到相機視圖座標的 3D 轉換(R, T)
get_full_projection_transform
,將投影轉換 (K
) 與世界到視圖的轉換(R, T)
組合起來transform_points
,採用一套輸入點在世界座標中,並投影到範圍從 [-1, -1, znear] 到 [+1, +1, zfar] 的 NDC 座標。get_ndc_camera_transform
,定義轉換到 PyTorch3D 的 NDC 空間,在與 PyTorch3D 渲染器建立連接介面時使用。如果相機定義在 NDC 空間,就會傳回單位轉換。如果相機定義在螢幕空間,會傳回由螢幕轉換到 NDC 的轉換。如果使用者在螢幕空間定義自己的相機,就需要考慮螢幕到 NDC 的轉換。我們提供PerspectiveCameras
和OrthographicCameras
的範例。transform_points_ndc
,接收一組在世界座標的點,並將其投影到 PyTorch3D 的 NDC 空間transform_points_screen
,接收一組在世界座標的輸入點,並將其投影到從 [0, 0, znear] 到 [W, H, zfar] 的螢幕座標
使用者可以輕鬆自訂自己的相機。對於每個新相機,使用者應實作 get_projection_transform
常式程序,傳回從相機檢視座標到 NDC 座標的對應 P
。
FoVPerspectiveCameras、FoVOrthographicCameras
這兩個相機分別遵循 OpenGL 慣例,針對透視和正交相機。使用者提供定義檢視體積在 Z 軸的近場 znear
和遠場 zfar
。在 XY
平面上的檢視體積由視角 (fov
) 定義,如果是 FoVPerspectiveCameras
,則由 min_x, min_y, max_x, max_y
定義,如果是 FoVOrthographicCameras
。預設情況下,這些相機位於 NDC 空間。
PerspectiveCameras、OrthographicCameras
這兩個相機遵循多視圖幾何慣例,針對相機。使用者提供焦距 (fx
、fy
) 和主點 (px
、py
)。例如,camera = PerspectiveCameras(focal_length=((fx, fy),), principal_point=((px, py),))
相機投影 3D 點 ((X, Y, Z)
) 在檢視座標到投影空間 (NDC 或螢幕) 的點 ((x, y, z)
)
# for perspective camera
x = fx * X / Z + px
y = fy * Y / Z + py
z = 1 / Z
# for orthographic camera
x = fx * X + px
y = fy * Y + py
z = Z
使用者可以在 NDC 或螢幕空間定義相機參數。螢幕空間相機參數很常見,對於這種情況,使用者需要將 in_ndc
設為 False
,並提供螢幕 (也稱為影像) 的 image_size=(height, width)
。
get_ndc_camera_transform
提供從螢幕空間到 PyTorch3D 內 NDC 空間的轉換。請注意,螢幕空間假設主點提供在空間中,其中 +X 左
,+Y 下
,原點位於影像左上角。要轉換到 NDC,我們需要考量標準化空間的縮放,以及 XY
方向的改變。
以下是 PerspectiveCameras
設定在 NDC 和螢幕空間的等效範例。
# NDC space camera
fcl_ndc = (1.2,)
prp_ndc = ((0.2, 0.5),)
cameras_ndc = PerspectiveCameras(focal_length=fcl_ndc, principal_point=prp_ndc)
# Screen space camera
image_size = ((128, 256),) # (h, w)
fcl_screen = (76.8,) # fcl_ndc * min(image_size) / 2
prp_screen = ((115.2, 32), ) # w / 2 - px_ndc * min(image_size) / 2, h / 2 - py_ndc * min(image_size) / 2
cameras_screen = PerspectiveCameras(focal_length=fcl_screen, principal_point=prp_screen, in_ndc=False, image_size=image_size)
相機 focal_length
及 principal_point
的視窗與 NDC 規範之間的關係由以下等式給出,其中 s = min(image_width, image_height)
。視窗與 NDC 之間 x 和 y 座標的轉換與 px 和 py 完全相同。
fx_ndc = fx_screen * 2.0 / s
fy_ndc = fy_screen * 2.0 / s
px_ndc = - (px_screen - image_width / 2.0) * 2.0 / s
py_ndc = - (py_screen - image_height / 2.0) * 2.0 / s