Source code for florin.io

"""I/O functions for loading and saving data in a variety of formats.

Functions
---------
load
    Load image(s) from a file.
load_hdf5
    Load data from an HDF5 file.
load_image
    Load an image file.
load_images
    Load a directory of image files.
load_npy
    Load data from a numpy array file.
load_tiff
    Load a TIFF stack.
save
    Save image(s) in a variety of formats.
save_hdf5
    Save an image to HDF5 format.
save_image
    Save an image.
save_images
    Save a sequence of images.
save_npy
    Save an image to a numpy array file.
save_tiff
    Save an image to TIFF format.
"""

import glob
import os
import sys

import h5py
import numpy as np
from skimage.io import imread, imsave

from florin.closure import florinate


[docs]@florinate def load(path, **kwargs): """Load images from a file. Generic loader function that uses the file extension to determine how to load the data. Parameters ---------- path : str Path to the image file(s) to load. Other Parameters ---------------- key Key to load data from when working with key/value stores (e.g. HDF5, npz, etc.) Returns ------- data : numpy.ndarray """ _, ext = os.path.splitext(path) ext = ext.strip('.').lower() if ext == 'h5': img = load_hdf5(path, **kwargs) elif ext == 'npy': img = load_npy(path) elif ext in ['tif', 'tiff']: img = load_tiff(path) elif os.path.isdir(path): img = load_images(path) else: img = load_image(path) return img
[docs]def load_hdf5(path, key='stack'): """Load data from an HDF5 file. Parameters ---------- path : str Path to the HDF5 file to load. key Key to load data from. Returns ------- data : h5py.Dataset """ f = h5py.File(path, 'r') img = f[key] img.file_object = f return img
[docs]def load_image(path): """Load an image file. Parameters ---------- path : str Path to the image file to load. Returns ------- data : numpy.ndarray """ img = imread(path) return img
[docs]def load_images(path, ext='png'): """Load a directory of image files. Parameters ---------- path : str Path to the image file(s) to load. ext : str The file extension to match. Only files with this extension will be loaded. Default: 'png' Returns ------- data : numpy.ndarray """ img_names = sorted(glob.glob(os.path.join(path, '*' + ext))) imgs = None for i, img in enumerate(img_names): img = imread(img) if imgs is None: imgs = np.zeros((len(img_names),) + img.shape, dtype=img.dtype) imgs[i] += img return imgs
[docs]def load_npy(path): """Load data from a numpy array file. Parameters ---------- path : str Path to the array file to load. Returns ------- data : numpy.ndarray """ img = np.load(path) return img
[docs]def load_tiff(path): """Load a TIFF stack. Parameters ---------- path : str Path to the TIFF stack to load. Returns ------- data : numpy.ndarray """ img = imread(path, plugin='tifffile') return img
[docs]@florinate def save(img, path, **kwargs): """Save image(s) in a variety of formats. Parameters ---------- img : array_like The image/volume to save. path : str The filepath to save the data to. This path determines which format the data will be saved as. Returns ------- img The unaltered image/volume. Other Parameters ---------------- See ``save_hdf5``, ``save_image``, ``save_images``, ``save_npy``, and ``save_tiff`` for filetype-specific arguments. Notes ----- The filetype passed as ``path`` will determine the format of the saved file. If no extension is found, 3D arrays will automatically be saved as numbered PNG files in a directory created at ``path`` and 2D arrays will be saved to ``path`` directly as a PNG. """ if img.dtype == np.bool: img = img.astype(np.uint8) * 255 if isinstance(img, map): img = next(img) if isinstance(img, list) and len(img) == 1: img = img[0] _, ext = os.path.splitext(path) ext = ext.strip('.').lower() if ext == 'h5': save_hdf5(img, path, **kwargs) elif ext == 'npy': save_npy(img, path) elif ext in ['tif', 'tiff']: save_tiff(img, path) elif os.path.isdir(path) or ext == '': save_images(img, path) else: save_image(img, path) return img
[docs]def save_hdf5(img, path, key='stack'): """Save an image to HDF5 format. Parameters ---------- img : array_like The image/volume to save. path : str The filepath to save the data to. """ if os.path.isfile(path): f = h5py.File(path, 'r+') else: f = h5py.File(path, 'w') f.create_dataset(key, data=img)
[docs]def save_image(img, path): """Save an image. Parameters ---------- img : array_like The image/volume to save. path : str The filepath to save the data to. """ _, ext = os.path.splitext(path) ext = ext.strip('.').lower() if ext == '': ext = 'png' path = os.path.join(path, 'image.' + ext) imsave(path, img)
[docs]def save_images(img, path, ext='png'): """Save a sequence of images. Parameters ---------- img : array_like The image/volume to save. path : str The filepath to save the data to. ext : str The file extension to save each image with. """ if os.path.isfile(path) or img.ndim == 2: save_image(img, path) elif img.ndim == 3: if not os.path.isdir(path): if sys.version_info.major == 3: os.makedirs(path, exist_ok=True) else: os.makedirs(path) zeros = int(np.floor(np.log10(img.shape[0])) + 1) for i in range(img.shape[0]): fpath = '{}.{}'.format(str(i).zfill(zeros), ext.strip('.').lower()) imsave(os.path.join(path, fpath), img[i])
[docs]def save_npy(img, path): """Save an image to a numpy array file. Parameters ---------- img : array_like The image/volume to save. path : str The filepath to save the data to. """ np.save(path, img)
[docs]def save_tiff(img, path): """Save an image to TIFF format. Parameters ---------- img : array_like The image/volume to save. path : str The filepath to save the data to. """ imsave(path, img, plugin='tifffile')