Shortcuts

Source code for caer.io.io

#    _____           ______  _____
#  / ____/    /\    |  ____ |  __ \
# | |        /  \   | |__   | |__) | Caer - Modern Computer Vision
# | |       / /\ \  |  __|  |  _  /  Languages: Python, C, C++, Cuda
# | |___   / ____ \ | |____ | | \ \  http://github.com/jasmcaus/caer
#  \_____\/_/    \_ \______ |_|  \_\

# Licensed under the MIT License <http://opensource.org/licenses/MIT>
# SPDX-License-Identifier: MIT
# Copyright (c) 2020-2021 The Caer Authors <http://github.com/jasmcaus>


import cv2 as cv
import numpy as np
from urllib.request import urlopen

# from urllib.error import URLError

from .resize import resize
from ..coreten import to_tensor, Tensor
from ..color import rgb2bgr, to_bgr
from ..path import exists
from .._internal import _check_target_size
from typing import Tuple, Optional, Union


__all__ = [
    "imread", 
    "imsave"
]

IMREAD_COLOR = 1


[docs]def imread( image_path: str, rgb: bool = True, target_size: Optional[Tuple[int, int]] = None, resize_factor: Optional[Union[float, Tuple]] = None, preserve_aspect_ratio: bool = False, interpolation: str = "bilinear", ) -> Tensor: r""" Loads in an image from `image_path` (can be either a system filepath or a URL) Args: image_path (str): Filepath/URL to read the image from. rgb (bool): Boolean to keep RGB ordering. Default: True target_size (tuple): Size of the target image resize_factor (float, tuple): Resizing Factor to employ. Shrinks the image if ``resize_factor < 1`` Enlarges the image if ``resize_factor > 1`` preserve_aspect_ration (bool): Prevent aspect ratio distortion (employs center crop). Default:False Returns: Tensor with shape ``(height, width, channels)``. Examples:: >> tens = caer.imread(tens_path) # From FilePath >> tens.shape (427, 640, 3) >> tens = caer.imread('https://raw.githubusercontent.com/jasmcaus/caer/master/caer/data/beverages.jpg') # From URL >> tens.shape (427, 640, 3) """ return _imread(image_path,rgb=rgb,target_size=target_size,resize_factor=resize_factor,preserve_aspect_ratio=preserve_aspect_ratio,interpolation=interpolation,)
def _imread( image_path, rgb: bool = True, target_size=None, resize_factor=None, preserve_aspect_ratio=False, interpolation: str = "bilinear" ) -> Tensor: if target_size is not None: _check_target_size(target_size) # if not isinstance(channels, int) or channels not in [1, 3]: # raise ValueError("channels must be an integer - 1 (Grayscale) or 3 (RGB)") interpolation_methods = { 'nearest': 0, '0': 0, 0: 0, # 0 'bilinear': 1, '1': 1, 1: 1, # 1 'bicubic': 2, '2': 2, 2: 2, # 2 'area': 3, '3': 3, 3: 3, # 3 } if interpolation not in interpolation_methods: raise ValueError("Specify a valid interpolation type - area/nearest/bicubic/bilinear") if exists(image_path): tens = _read_image(image_path) # returns RGB # TODO: Create URL validator elif image_path.startswith(('http://", "https://')): # Returns RGB image tens = _url_to_image(image_path) # If the URL is valid, but no image at that URL, NoneType is returned if tens is None: raise ValueError("The URL specified does not point to an image") else: raise ValueError("Specify either a valid URL or filepath") # try: # # Returns RGB image # tens = _url_to_image(image_path) # # If the URL is valid, but no image at that URL, NoneType is returned # if tens is None: # raise ValueError("The URL specified does not point to an image") # # return tens # # If the URL is invalid # except (Exception, URLError): # if exists(image_path): # tens = _read_image(image_path) # returns RGB # else: # raise ValueError("Specify either a valid URL or filepath") if target_size is not None or resize_factor is not None: # Enforce a Tensor is passed to resize() to_tensor(tens, cspace="rgb") tens = resize(tens,target_size,resize_factor=resize_factor,preserve_aspect_ratio=preserve_aspect_ratio,interpolation=interpolation,) # If `rgb=False`, then we assume that BGR is expected if not rgb: tens = rgb2bgr(tens) # We need to convert back to tensor return to_tensor(tens, cspace="bgr") return to_tensor(tens, cspace="rgb") def _read_image(image_path: str) -> np.ndarray: r""" Returns an RGB ndarray Args: image_path (str): Filepath/URL to read the image from. """ if not exists(image_path): raise FileNotFoundError("The image file was not found") # BGR image tens = cv.imread(image_path) # Convert to RGB # WARNING: DO NOT USE to_rgb() as it creates a brand new Tensor (which defaults to RGB) # This issue will, hopefully, be fixed in a future update. # tens = to_rgb(tens) return cv.cvtColor(tens, cv.COLOR_BGR2RGB) def _url_to_image(url: str) -> np.ndarray: r""" Returns an RGB ndarray. """ response = urlopen(url) tens = np.asarray(bytearray(response.read()), dtype="uint8") # BGR image tens = cv.imdecode(tens, IMREAD_COLOR) if tens is not None: return cv.cvtColor(tens, cv.COLOR_BGR2RGB) else: raise ValueError(f"No image found at '{url}'")
[docs]def imsave(path: str, tens: Tensor) -> bool: r""" Saves a Tensor to `path` Args: path (str): Filepath to save the image to Returns ``True``; if `tens` was written to `path` ``False``; otherwise Examples:: >> tens = caer.data.audio_mixer() >> caer.imsave("audio_mixer.png", tens) True """ if not isinstance(tens, Tensor): raise TypeError("`tens` must be a caer.Tensor") # Convert to tensor tens._nullprt() # raises a ValueError if we're dealing with a Foreign Tensor with illegal `.cspace` value try: # OpenCV uses BGR Tensors and saves them as RGB images if tens.cspace != "bgr": tens = to_bgr(tens) # type: ignore return cv.imwrite(path, tens) except: raise ValueError( "`tens` needs to be a caer Tensor. Try reading the image using `caer.imread()`." "More support for additional platforms will follow. Check the Changelog for further details." )