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.
Returns