Skip to content

Image utilities

Kano provides some image-related functions:

  • show_image: show image from a file path or a numpy array.
  • download_image: download an image from the internet.
  • get_randow_image: download an image with desired size.
  • rotate_image: rotate an image around its center.
  • concatenate_images: concatenate a 2-dimensional list of images.

kano.image.show_image(image, figsize=(10, 10))

Show image from a numpy array or a file path. Which can be used when run .py or .ipynb files.

Parameters:

Name Type Description Default
image Union[ndarray, str]

a numpy array or a file path

required
figsize Tuple[int, int]

(width, height) for image to show

(10, 10)
Source code in kano\image\utils.py
def show_image(image, figsize=(10, 10)):
    """
    Show image from a numpy array or a file path.
    Which can be used when run .py or .ipynb files.

    Args:
        image (Union[np.ndarray, str]): a numpy array or a file path
        figsize (Tuple[int, int]): (width, height) for image to show
    """
    if isinstance(image, str):
        temp_image = cv2.imread(image)
    else:
        temp_image = image.copy()

    plt.figure(figsize=figsize)
    temp_image = cv2.cvtColor(temp_image.astype(np.uint8), cv2.COLOR_BGR2RGB)
    plt.imshow(temp_image)
    plt.show()

kano.image.download_image(url, save_path=None)

Download image from given url

Parameters:

Name Type Description Default
url str

url of the image

required
save_path str

path to save image

None

Returns:

Name Type Description
image Union[ndarray, NoneType]

return numpy array of the image if it's downloaded successfullly. Otherwise return None

Source code in kano\image\utils.py
def download_image(url, save_path=None):
    """
    Download image from given url

    Args:
        url (str): url of the image
        save_path (str): path to save image

    Returns:
        image (Union[np.ndarray, NoneType]): return numpy array of the image if
            it's downloaded successfullly. Otherwise return None
    """
    response = requests.get(url)
    if response.status_code == 200:
        image_stream = BytesIO(response.content)
        image_data = np.frombuffer(image_stream.read(), dtype=np.uint8)
        image = cv2.imdecode(image_data, cv2.IMREAD_COLOR)

        if save_path:
            cv2.imwrite(save_path, image)

        return image
    else:
        print(f"Failed to download image from {url}")
        return None

kano.image.get_random_image(width=400, height=300, save_path=None)

Download a random image with desired size.

Source code in kano\image\utils.py
def get_random_image(
    width: int = 400, height: int = 300, save_path: Optional[str] = None
) -> Optional[np.ndarray]:
    """Download a random image with desired size."""
    return download_image(f"https://picsum.photos/{width}/{height}", save_path)

kano.image.rotate_image(image, degree, expand=False)

Rotate the given image with given degree

Parameters:

Name Type Description Default
image ndarray

numpy array of the image

required
degree float

total degrees to rotate

required
expand bool

Pad rotated image with black color if True, otherwise return the cropped rotated image

False

Returns:

Name Type Description
rotated_image ndarray

numpy array of the rotated image

Source code in kano\image\process.py
def rotate_image(
    image: np.ndarray, degree: float, expand: bool = False
) -> np.ndarray:
    """
    Rotate the given image with given degree

    Args:
        image (np.ndarray): numpy array of the image
        degree (float): total degrees to rotate
        expand (bool): Pad rotated image with black color if True,
            otherwise return the cropped rotated image

    Returns:
        rotated_image (np.ndarray): numpy array of the rotated image
    """
    height, width = image.shape[:2]
    center_point = (width / 2, height / 2)

    rotation_matrix = cv2.getRotationMatrix2D(center_point, degree, 1.0)

    new_height, new_width = image.shape[:2]
    if expand:
        abs_cos = abs(rotation_matrix[0, 0])
        abs_sin = abs(rotation_matrix[0, 1])

        new_width = int(height * abs_sin + width * abs_cos)
        new_height = int(height * abs_cos + width * abs_sin)

        rotation_matrix[0, 2] += new_width / 2 - center_point[0]
        rotation_matrix[1, 2] += new_height / 2 - center_point[1]

    rotated_image = cv2.warpAffine(
        image, rotation_matrix, (new_width, new_height)
    )

    return rotated_image

kano.image.concatenate_images(image_list, padding_size=0)

Concatenate images based on its appearance order in the given 2D list Each image will be padded to the max height, max width in the given list.

Parameters:

Name Type Description Default
image_list list(list(np.ndarray

2D (or 1D) list of images

required
padding_size int

padding distance between each image

0

Returns:

Name Type Description
concatenated_image ndarray

the concatenated image from 2D list

Source code in kano\image\process.py
def concatenate_images(
    image_list: List[List[np.ndarray]], padding_size: int = 0
) -> np.ndarray:
    """
    Concatenate images based on its appearance order in the given 2D list
    Each image will be padded to the max height, max width in the given list.

    Args:
        image_list (list(list(np.ndarray))): 2D (or 1D) list of images
        padding_size (int): padding distance between each image

    Returns:
        concatenated_image (np.ndarray): the concatenated image from 2D list
    """

    # ensure image_list is a 2D list
    new_image_list = copy.deepcopy(image_list)
    if not isinstance(image_list[0], list):
        new_image_list = [copy.deepcopy(image_list)]

    rows = len(new_image_list)
    cols = max(len(row) for row in new_image_list)

    for image_row in new_image_list:
        image_row += [None] * (cols - len(image_row))

    # pad every images
    max_height = max(
        image.shape[0]
        for row in new_image_list
        for image in row
        if image is not None
    )
    max_width = max(
        image.shape[1]
        for row in new_image_list
        for image in row
        if image is not None
    )

    padded_image_list = list()
    for i, row in enumerate(new_image_list):
        padded_image_list.append(list())
        for j, image in enumerate(row):
            padded_image = np.zeros((max_height, max_width, 3), dtype=np.uint8)
            if image is not None:
                padded_image = pad_image(image, (max_height, max_width))
            padded_image_list[i].append(padded_image)

    concatenated_image = np.zeros(
        (
            max_height * rows + padding_size * (rows - 1),
            max_width * cols + padding_size * (cols - 1),
            3,
        ),
        dtype=np.uint8,
    )

    for i, row in enumerate(padded_image_list):
        for j, image in enumerate(row):

            h, w, _ = image.shape
            concatenated_image[
                (i > 0) * padding_size
                + i * max_height : (i > 0) * padding_size
                + i * max_height
                + h,
                (j > 0) * padding_size
                + j * max_width : (j > 0) * padding_size
                + j * max_width
                + w,
            ] = image

    return concatenated_image