Camera

World coordinate systems

OpenGL/MAYA       OpenCV/Colmap     Blender      Unity/DirectX     Unreal
Right-handed      Right-handed    Right-handed    Left-handed    Left-handed

     +y                +z           +z  +y         +y  +z          +z
     |                /             |  /           |  /             |
     |               /              | /            | /              |
     |______+x      /______+x       |/_____+x      |/_____+x        |______+x
    /               |                                              /
   /                |                                             /
  /                 |                                            /
 +z                 +y                                          +y

A common color code: x = red, y = green, z = blue (XYZ=RGB)

Left/right-handed notation: roll your left/right palm from x to y, and your thumb should point to z.

Camera pose coordinate systems

A Camera pose matrix (camera to world transformation) is in the form of:

[[Right_x, Up_x, Forward_x, Position_x],
 [Right_y, Up_y, Forward_y, Position_y],
 [Right_z, Up_z, Forward_z, Position_z],
 [0,       0,    0,         1         ]]

The xyz follows corresponding world coordinate system. However, the three directions (right, up, forward) can be defined differently:

  • forward can be camera --> target or target --> camera.

  • up can align with the world-up-axis (y) or world-down-axis (-y).

  • right can also be left, depending on it’s (up cross forward) or (forward cross up).

This leads to two common camera conventions:

   OpenGL                OpenCV
   Blender               Colmap

     up  target          forward & target
     |  /                /
     | /                /
     |/_____right      /______right
    /                  |
   /                   |
  /                    |
forward                up

A common color code: right = red., up = green, forward = blue (XYZ=RUF=RGB).

Our camera convention

  • world coordinate is OpenGL/right-handed, +x = right, +y = up, +z = forward

  • camera coordinate is OpenGL (forward is target --> campos).

  • elevation in (-90, 90), from +y (-90) --> -y (+90)

  • azimuth in (-180, 180), from +z (0/-360) --> +x (90/-270) --> -z (180/-180) --> -x (270/-90) --> +z (360/0)

API

Note

the camera API is designed to be numpy based and un-batched!

kiui.cam.convert(pose, target: Literal[‘unity’, ‘blender’, ‘opencv’, ‘colmap’, ‘opengl’] = 'unity', original: Literal[‘unity’, ‘blender’, ‘opencv’, ‘colmap’, ‘opengl’] = 'opengl')[source]

A method to convert between different world coordinate systems.

Parameters:
  • pose (np.ndarray) – camera pose, float [4, 4].

  • target (Literal['unity', 'blender', 'opencv', 'colmap', 'opengl'], optional) – from convention. Defaults to ‘unity’.

  • original (Literal['unity', 'blender', 'opencv', 'colmap', 'opengl'], optional) – to convention. Defaults to ‘opengl’.

Returns:

converted camera pose, float [4, 4].

Return type:

np.ndarray

kiui.cam.look_at(campos, target, opengl=True)[source]

construct pose rotation matrix by look-at.

Parameters:
  • campos (np.ndarray) – camera position, float [3]

  • target (np.ndarray) – look at target, float [3]

  • opengl (bool, optional) – whether use opengl camera convention (forward direction is target –> camera). Defaults to True.

Returns:

the camera pose rotation matrix, float [3, 3], normalized.

Return type:

np.ndarray

kiui.cam.orbit_camera(elevation, azimuth, radius=1, is_degree=True, target=None, opengl=True)[source]

construct a camera pose matrix orbiting a target with elevation & azimuth angle.

Parameters:
  • elevation (float) – elevation in (-90, 90), from +y to -y is (-90, 90)

  • azimuth (float) – azimuth in (-180, 180), from +z to +x is (0, 90)

  • radius (int, optional) – camera radius. Defaults to 1.

  • is_degree (bool, optional) – if the angles are in degree. Defaults to True.

  • target (np.ndarray, optional) – look at target position. Defaults to None.

  • opengl (bool, optional) – whether to use OpenGL camera convention. Defaults to True.

Returns:

the camera pose matrix, float [4, 4]

Return type:

np.ndarray

kiui.cam.undo_orbit_camera(T, is_degree=True)[source]

undo an orbital camera pose matrix to elevation & azimuth

Parameters:
  • T (np.ndarray) – camera pose matrix, float [4, 4], must be an orbital camera targeting at (0, 0, 0)!

  • is_degree (bool, optional) – whether to return angles in degree. Defaults to True.

Returns:

elevation, azimuth, and radius.

Return type:

Tuple[float]

kiui.cam.get_perspective(fovy, aspect=1, near=0.01, far=1000)[source]

construct a perspective matrix from fovy.

Parameters:
  • fovy (float) – field of view in degree along y-axis.

  • aspect (int, optional) – aspect ratio. Defaults to 1.

  • near (float, optional) – near clip plane. Defaults to 0.01.

  • far (int, optional) – far clip plane. Defaults to 1000.

Returns:

perspective matrix, float [4, 4]

Return type:

np.ndarray

kiui.cam.get_rays(pose, h, w, fovy, opengl=True, normalize_dir=True)[source]

construct rays origin and direction from a camera pose.

Parameters:
  • pose (np.ndarray) – camera pose, float [4, 4]

  • h (int) – image height

  • w (int) – image width

  • fovy (float) – field of view in degree along y-axis.

  • opengl (bool, optional) – whether to use the OpenGL camera convention. Defaults to True.

  • normalize_dir (bool, optional) – whether to normalize the ray directions. Defaults to True.

Returns:

rays_o and rays_d, both are float [h, w, 3]

Return type:

Tuple[np.ndarray]

class kiui.cam.OrbitCamera(W, H, r=2, fovy=60, near=0.01, far=100)[source]

An orbital camera class.

__init__(W, H, r=2, fovy=60, near=0.01, far=100)[source]

init function

Parameters:
  • W (int) – image width

  • H (int) – image height

  • r (int, optional) – camera radius. Defaults to 2.

  • fovy (int, optional) – camera field of view in degree along y-axis. Defaults to 60.

  • near (float, optional) – near clip plane. Defaults to 0.01.

  • far (int, optional) – far clip plane. Defaults to 100.

property fovx

get the field of view in radians along x-axis

Returns:

field of view in radians along x-axis

Return type:

float

property campos

get the camera position

Returns:

camera position, float [3]

Return type:

np.ndarray

property pose

get the camera pose matrix (cam2world)

Returns:

camera pose, float [4, 4]

Return type:

np.ndarray

property view

get the camera view matrix (world2cam, inverse of cam2world)

Returns:

camera view, float [4, 4]

Return type:

np.ndarray

property perspective

get the perspective matrix

Returns:

camera perspective, float [4, 4]

Return type:

np.ndarray

property intrinsics

get the camera intrinsics

Returns:

intrinsics (fx, fy, cx, cy), float [4]

Return type:

np.ndarray

property mvp

get the MVP (model-view-perspective) matrix.

Returns:

camera MVP, float [4, 4]

Return type:

np.ndarray

orbit(dx, dy)[source]

rotate along camera up/side axis!

Parameters:
  • dx (float) – delta step along x (up).

  • dy (float) – delta step along y (side).

scale(delta)[source]

scale the camera.

Parameters:

delta (float) – delta step.

pan(dx, dy, dz=0)[source]

pan the camera.

Parameters:
  • dx (float) – delta step along x.

  • dy (float) – delta step along y.

  • dz (float, optional) – delta step along x. Defaults to 0.

from_angle(elevation, azimuth, is_degree=True)[source]

set the camera pose from elevation & azimuth angle.

Parameters:
  • elevation (float) – elevation in (-90, 90), from +y to -y is (-90, 90)

  • azimuth (float) – azimuth in (-180, 180), from +z to +x is (0, 90)

  • is_degree (bool, optional) – whether the angles are in degree. Defaults to True.