mirror of
https://github.com/nerfstudio-project/nerfstudio.git
synced 2026-11-11 02:24:38 +08:00
102 lines
3.2 KiB
Python
102 lines
3.2 KiB
Python
# Copyright 2022 The Plenoptix Team. All rights reserved.
|
|
#
|
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
# you may not use this file except in compliance with the License.
|
|
# You may obtain a copy of the License at
|
|
#
|
|
# http://www.apache.org/licenses/LICENSE-2.0
|
|
#
|
|
# Unless required by applicable law or agreed to in writing, software
|
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
# See the License for the specific language governing permissions and
|
|
# limitations under the License.
|
|
|
|
""" Helper functions for visualizing outputs """
|
|
|
|
from typing import Optional
|
|
|
|
import torch
|
|
from matplotlib import cm
|
|
from torchtyping import TensorType
|
|
|
|
from nerfactory.utils import colors
|
|
|
|
|
|
def apply_colormap(image: TensorType["bs":..., 1], cmap="viridis") -> TensorType["bs":..., "rgb":3]:
|
|
"""Convert single channel to a color image.
|
|
|
|
Args:
|
|
image: Single channel image.
|
|
cmap: Colormap for image.
|
|
|
|
Returns:
|
|
TensorType: Colored image
|
|
"""
|
|
|
|
colormap = cm.get_cmap(cmap)
|
|
colormap = torch.tensor(colormap.colors).to(image.device) # type: ignore
|
|
image_long = (image * 255).long()
|
|
image_long_min = torch.min(image_long)
|
|
image_long_max = torch.max(image_long)
|
|
assert image_long_min >= 0, f"the min value is {image_long_min}"
|
|
assert image_long_max <= 255, f"the max value is {image_long_max}"
|
|
return colormap[image_long[..., 0]]
|
|
|
|
|
|
def apply_depth_colormap(
|
|
depth: TensorType["bs":..., 1],
|
|
accumulation: Optional[TensorType["bs":..., 1]] = None,
|
|
near_plane: Optional[float] = None,
|
|
far_plane: Optional[float] = None,
|
|
cmap="turbo",
|
|
) -> TensorType["bs":..., "rgb":3]:
|
|
"""Converts a depth image to color for easier analysis.
|
|
|
|
Args:
|
|
depth: Depth image.
|
|
accumulation: Ray accumulation used for masking vis.
|
|
near_plane: Closest depth to consider. If None, use min image value.
|
|
far_plane: Furthest depth to consider. If None, use max image value.
|
|
cmap: Colormap to apply.
|
|
|
|
Returns:
|
|
Colored depth image
|
|
"""
|
|
|
|
near_plane = near_plane or float(torch.min(depth))
|
|
far_plane = far_plane or float(torch.max(depth))
|
|
|
|
depth = (depth - near_plane) / (far_plane - near_plane + 1e-10)
|
|
depth = torch.clip(depth, 0, 1)
|
|
# depth = torch.nan_to_num(depth, nan=0.0) # TODO(ethan): remove this
|
|
|
|
colored_image = apply_colormap(depth, cmap=cmap)
|
|
|
|
if accumulation is not None:
|
|
colored_image = colored_image * accumulation + (1 - accumulation)
|
|
|
|
return colored_image
|
|
|
|
|
|
def apply_boolean_colormap(
|
|
image: TensorType["bs":..., 1, bool],
|
|
true_color: TensorType["bs":..., "rgb":3] = colors.WHITE,
|
|
false_color: TensorType["bs":..., "rgb":3] = colors.BLACK,
|
|
) -> TensorType["bs":..., "rgb":3]:
|
|
"""Converts a depth image to color for easier analysis.
|
|
|
|
Args:
|
|
image: Boolean image.
|
|
true_color: Color to use for True.
|
|
false_color: Color to use for False.
|
|
|
|
Returns:
|
|
Colored boolean image
|
|
"""
|
|
|
|
colored_image = torch.ones(image.shape[:-1] + (3,))
|
|
colored_image[image[..., 0], :] = true_color
|
|
colored_image[~image[..., 0], :] = false_color
|
|
return colored_image
|