csi_images.csi_images
1import numpy as np 2 3 4def make_rgb( 5 images: list[np.ndarray], colors=list[tuple[float, float, float]] 6) -> np.ndarray: 7 """ 8 Combine multiple channels into a single RGB image. 9 :param images: list of numpy arrays representing the channels. 10 :param colors: list of RGB tuples for each channel. 11 :return: 12 """ 13 if len(images) == 0: 14 raise ValueError("No images provided.") 15 if len(colors) == 0: 16 raise ValueError("No colors provided.") 17 if len(images) != len(colors): 18 raise ValueError("Number of images and colors must match.") 19 if not all([isinstance(image, np.ndarray) for image in images]): 20 raise ValueError("Images must be numpy arrays.") 21 if not all([len(c) == 3 for c in colors]): 22 raise ValueError("Colors must be RGB tuples.") 23 24 # Create an output with same shape and larger type to avoid overflow 25 dims = images[0].shape 26 dtype = images[0].dtype 27 if dtype not in [np.uint8, np.uint16]: 28 raise ValueError("Image dtype must be uint8 or uint16.") 29 rgb = np.zeros((*dims, 3), dtype=np.uint16 if dtype == np.uint8 else np.uint32) 30 31 # Combine images with colors (can also be thought of as gains) 32 for image, color in zip(images, colors): 33 if image.shape != dims: 34 raise ValueError("All images must have the same shape.") 35 if image.dtype != dtype: 36 raise ValueError("All images must have the same dtype.") 37 rgb[..., 0] += (image * color[0]).astype(rgb.dtype) 38 rgb[..., 1] += (image * color[1]).astype(rgb.dtype) 39 rgb[..., 2] += (image * color[2]).astype(rgb.dtype) 40 41 # Cut off any overflow and convert back to original dtype 42 rgb = np.clip(rgb, np.iinfo(dtype).min, np.iinfo(dtype).max).astype(dtype) 43 return rgb
def
make_rgb( images: list[numpy.ndarray], colors=list[tuple[float, float, float]]) -> numpy.ndarray:
5def make_rgb( 6 images: list[np.ndarray], colors=list[tuple[float, float, float]] 7) -> np.ndarray: 8 """ 9 Combine multiple channels into a single RGB image. 10 :param images: list of numpy arrays representing the channels. 11 :param colors: list of RGB tuples for each channel. 12 :return: 13 """ 14 if len(images) == 0: 15 raise ValueError("No images provided.") 16 if len(colors) == 0: 17 raise ValueError("No colors provided.") 18 if len(images) != len(colors): 19 raise ValueError("Number of images and colors must match.") 20 if not all([isinstance(image, np.ndarray) for image in images]): 21 raise ValueError("Images must be numpy arrays.") 22 if not all([len(c) == 3 for c in colors]): 23 raise ValueError("Colors must be RGB tuples.") 24 25 # Create an output with same shape and larger type to avoid overflow 26 dims = images[0].shape 27 dtype = images[0].dtype 28 if dtype not in [np.uint8, np.uint16]: 29 raise ValueError("Image dtype must be uint8 or uint16.") 30 rgb = np.zeros((*dims, 3), dtype=np.uint16 if dtype == np.uint8 else np.uint32) 31 32 # Combine images with colors (can also be thought of as gains) 33 for image, color in zip(images, colors): 34 if image.shape != dims: 35 raise ValueError("All images must have the same shape.") 36 if image.dtype != dtype: 37 raise ValueError("All images must have the same dtype.") 38 rgb[..., 0] += (image * color[0]).astype(rgb.dtype) 39 rgb[..., 1] += (image * color[1]).astype(rgb.dtype) 40 rgb[..., 2] += (image * color[2]).astype(rgb.dtype) 41 42 # Cut off any overflow and convert back to original dtype 43 rgb = np.clip(rgb, np.iinfo(dtype).min, np.iinfo(dtype).max).astype(dtype) 44 return rgb
Combine multiple channels into a single RGB image.
Parameters
- images: list of numpy arrays representing the channels.
- colors: list of RGB tuples for each channel.