Spaces:
Runtime error
Runtime error
from typing import Tuple, Type | |
import numpy as np | |
from ..image_utils import MAX_VALUES_BY_DTYPE, as_3d | |
def np_denorm(x: np.ndarray, min_max: Tuple[float, float] = (-1.0, 1.0)) -> np.ndarray: | |
"""Denormalize from [-1,1] range to [0,1] | |
formula: xi' = (xi - mu)/sigma | |
Example: "out = (x + 1.0) / 2.0" for denorm | |
range (-1,1) to (0,1) | |
for use with proper act in Generator output (ie. tanh) | |
""" | |
out = (x - min_max[0]) / (min_max[1] - min_max[0]) | |
return np.clip(out, 0, 1) | |
def np_norm(x: np.ndarray) -> np.ndarray: | |
"""Normalize (z-norm) from [0,1] range to [-1,1]""" | |
out = (x - 0.5) * 2.0 | |
return np.clip(out, -1, 1) | |
def np_bgr_to_rgb(img: np.ndarray) -> np.ndarray: | |
out: np.ndarray = img[::-1, ...] | |
return out | |
def np_rgb_to_bgr(img: np.ndarray) -> np.ndarray: | |
# same operation as bgr_to_rgb(), flip image channels | |
return np_bgr_to_rgb(img) | |
def np_bgra_to_rgba(img: np.ndarray) -> np.ndarray: | |
out: np.ndarray = img[[2, 1, 0, 3], ...] # type: ignore | |
return out | |
def np_rgba_to_bgra(img: np.ndarray) -> np.ndarray: | |
# same operation as bgra_to_rgba(), flip image channels | |
return np_bgra_to_rgba(img) | |
def np2nptensor( | |
img: np.ndarray, | |
bgr2rgb=True, | |
data_range=1.0, # pylint: disable=unused-argument | |
normalize=False, | |
change_range=True, | |
add_batch=True, | |
) -> np.ndarray: | |
"""Converts a numpy image array into a numpy Tensor array. | |
Parameters: | |
img (numpy array): the input image numpy array | |
add_batch (bool): choose if new tensor needs batch dimension added | |
""" | |
# check how many channels the image has, then condition. ie. RGB, RGBA, Gray | |
# if bgr2rgb: | |
# img = img[ | |
# :, :, [2, 1, 0] | |
# ] # BGR to RGB -> in numpy, if using OpenCV, else not needed. Only if image has colors. | |
if change_range: | |
dtype = img.dtype | |
maxval = MAX_VALUES_BY_DTYPE.get(dtype.name, 1.0) | |
t_dtype = np.dtype("float32") | |
img = img.astype(t_dtype) / maxval # ie: uint8 = /255 | |
# "HWC to CHW" and "numpy to tensor" | |
img = np.ascontiguousarray(np.transpose(as_3d(img), (2, 0, 1))).astype(np.float32) | |
if bgr2rgb: | |
# BGR to RGB -> in tensor, if using OpenCV, else not needed. Only if image has colors.) | |
if ( | |
img.shape[0] % 3 == 0 | |
): # RGB or MultixRGB (3xRGB, 5xRGB, etc. For video tensors.) | |
img = np_bgr_to_rgb(img) | |
elif img.shape[0] == 4: # RGBA | |
img = np_bgra_to_rgba(img) | |
if add_batch: | |
img = np.expand_dims( | |
img, axis=0 | |
) # Add fake batch dimension = 1 . squeeze() will remove the dimensions of size 1 | |
if normalize: | |
img = np_norm(img) | |
return img | |
def nptensor2np( | |
img: np.ndarray, | |
rgb2bgr=True, | |
remove_batch=True, | |
data_range=255, | |
denormalize=False, | |
change_range=True, | |
imtype: Type = np.uint8, | |
) -> np.ndarray: | |
"""Converts a Tensor array into a numpy image array. | |
Parameters: | |
img (tensor): the input image tensor array | |
4D(B,(3/1),H,W), 3D(C,H,W), or 2D(H,W), any range, RGB channel order | |
remove_batch (bool): choose if tensor of shape BCHW needs to be squeezed | |
denormalize (bool): Used to denormalize from [-1,1] range back to [0,1] | |
imtype (type): the desired type of the converted numpy array (np.uint8 | |
default) | |
Output: | |
img (np array): 3D(H,W,C) or 2D(H,W), [0,255], np.uint8 (default) | |
""" | |
n_dim = img.ndim | |
img = img.astype(np.float32) | |
if n_dim in (4, 3): | |
# if n_dim == 4, has to convert to 3 dimensions | |
if n_dim == 4 and remove_batch: | |
# remove a fake batch dimension | |
img = img.squeeze(0) | |
if img.shape[0] == 3 and rgb2bgr: # RGB | |
# RGB to BGR -> in tensor, if using OpenCV, else not needed. Only if image has colors. | |
img_np = np_rgb_to_bgr(img) | |
elif img.shape[0] == 4 and rgb2bgr: # RGBA | |
# RGBA to BGRA -> in tensor, if using OpenCV, else not needed. Only if image has colors. | |
img_np = np_rgba_to_bgra(img) | |
else: | |
img_np = img | |
img_np = np.transpose(img_np, (1, 2, 0)) # CHW to HWC | |
elif n_dim == 2: | |
img_np = img | |
else: | |
raise TypeError( | |
f"Only support 4D, 3D and 2D tensor. But received with dimension: {n_dim:d}" | |
) | |
# if rgb2bgr: | |
# img_np = img_np[[2, 1, 0], :, :] #RGB to BGR -> in numpy, if using OpenCV, else not needed. Only if image has colors. | |
if denormalize: | |
img_np = np_denorm(img_np) # denormalize if needed | |
if change_range: | |
img_np = np.clip( | |
data_range * img_np, 0, data_range # type: ignore | |
).round() # np.clip to the data_range | |
# has to be in range (0,255) before changing to np.uint8, else np.float32 | |
return img_np.astype(imtype) | |