Skip to content

Commit

Permalink
cache CubemapSampler
Browse files Browse the repository at this point in the history
  • Loading branch information
BrianPugh committed Jan 2, 2025
1 parent 1382e98 commit d278d1b
Show file tree
Hide file tree
Showing 4 changed files with 54 additions and 44 deletions.
39 changes: 1 addition & 38 deletions py360convert/c2e.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,10 @@
CubeFaceSampler,
CubeFormat,
DType,
Face,
InterpolationMode,
cube_dice2list,
cube_dict2list,
cube_h2list,
equirect_facetype,
equirect_uvgrid,
mode_to_order,
)

Expand Down Expand Up @@ -127,43 +124,9 @@ def c2e(
raise ValueError("Cubemap faces must be square.")
face_w = cube_faces.shape[2]

u, v = equirect_uvgrid(h, w)

# Get face id to each pixel: 0F 1R 2B 3L 4U 5D
tp = equirect_facetype(h, w)

coor_x = np.empty((h, w), dtype=np.float32)
coor_y = np.empty((h, w), dtype=np.float32)
face_w2 = face_w / 2

# Middle band (front/right/back/left)
mask = tp < Face.UP
angles = u[mask] - (np.pi / 2 * tp[mask])
tan_angles = np.tan(angles)
cos_angles = np.cos(angles)
tan_v = np.tan(v[mask])

coor_x[mask] = face_w2 * tan_angles
coor_y[mask] = -face_w2 * tan_v / cos_angles

mask = tp == Face.UP
c = face_w2 * np.tan(np.pi / 2 - v[mask])
coor_x[mask] = c * np.sin(u[mask])
coor_y[mask] = c * np.cos(u[mask])

mask = tp == Face.DOWN
c = face_w2 * np.tan(np.pi / 2 - np.abs(v[mask]))
coor_x[mask] = c * np.sin(u[mask])
coor_y[mask] = -c * np.cos(u[mask])

# Final renormalize
coor_x += face_w2
coor_y += face_w2
coor_x.clip(0, face_w, out=coor_x)
coor_y.clip(0, face_w, out=coor_y)
sampler = CubeFaceSampler.from_equirec(face_w, h, w, order)

equirec = np.empty((h, w, cube_faces.shape[3]), dtype=cube_faces[0].dtype)
sampler = CubeFaceSampler(tp, coor_x, coor_y, order, face_w, face_w)
for i in range(cube_faces.shape[3]):
equirec[..., i] = sampler(cube_faces[..., i])

Expand Down
3 changes: 0 additions & 3 deletions py360convert/e2c.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,6 @@
cube_h2dict,
cube_h2list,
mode_to_order,
uv2coor,
xyz2uv,
xyzcube,
)


Expand Down
3 changes: 0 additions & 3 deletions py360convert/e2p.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,6 @@
EquirecSampler,
InterpolationMode,
mode_to_order,
uv2coor,
xyz2uv,
xyzpers,
)


Expand Down
53 changes: 53 additions & 0 deletions py360convert/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -577,6 +577,59 @@ def _pad(self, cube_faces: NDArray[DType]) -> NDArray[DType]:

return padded

@classmethod
@lru_cache(_CACHE_SIZE)
def from_equirec(cls, face_w: int, h: int, w: int, order: int):
"""Construct a CubemapSampler from equirectangular specs.
Parameters
----------
face_w: int
Length of each face of the input cubemap.
h: int
Output equirectangular image height.
w: int
Output equirectangular image width.
order: int
The order of the spline interpolation. See ``scipy.ndimage.map_coordinates``.
"""
u, v = equirect_uvgrid(h, w)

# Get face id to each pixel: 0F 1R 2B 3L 4U 5D
tp = equirect_facetype(h, w)

coor_x = np.empty((h, w), dtype=np.float32)
coor_y = np.empty((h, w), dtype=np.float32)
face_w2 = face_w / 2

# Middle band (front/right/back/left)
mask = tp < Face.UP
angles = u[mask] - (np.pi / 2 * tp[mask])
tan_angles = np.tan(angles)
cos_angles = np.cos(angles)
tan_v = np.tan(v[mask])

coor_x[mask] = face_w2 * tan_angles
coor_y[mask] = -face_w2 * tan_v / cos_angles

mask = tp == Face.UP
c = face_w2 * np.tan(np.pi / 2 - v[mask])
coor_x[mask] = c * np.sin(u[mask])
coor_y[mask] = c * np.cos(u[mask])

mask = tp == Face.DOWN
c = face_w2 * np.tan(np.pi / 2 - np.abs(v[mask]))
coor_x[mask] = c * np.sin(u[mask])
coor_y[mask] = -c * np.cos(u[mask])

# Final renormalize
coor_x += face_w2
coor_y += face_w2
coor_x.clip(0, face_w, out=coor_x)
coor_y.clip(0, face_w, out=coor_y)

return cls(tp, coor_x, coor_y, order, face_w, face_w)


def cube_h2list(cube_h: NDArray[DType]) -> list[NDArray[DType]]:
"""Split an image into a list of 6 faces."""
Expand Down

0 comments on commit d278d1b

Please sign in to comment.