Source code for imagesplit.file.image_file_reader

# coding=utf-8
"""Write multidimensional data line by line"""

from abc import ABCMeta, abstractmethod
from copy import deepcopy
import itertools
import numpy as np

from imagesplit.utils.utilities import to_rgb
from imagesplit.image.image_wrapper import ImageWrapper, ImageStorage
from imagesplit.utils.utilities import rescale_image


# pylint:disable=unnecessary-pass
[docs]class ImageFileReader(object): """Base class for writing data from source to destination""" __metaclass__ = ABCMeta
[docs] @abstractmethod def write_image(self, data_source, rescale_limits): """Create and write out this file, using data from this image source""" pass
[docs]class LinearImageFileReader(ImageFileReader): """Base class for writing data from source to destination line by line""" def __init__(self, image_size): self.size = image_size
[docs] @abstractmethod def write_line(self, start, image_line, rescale_limits): """Write the next line of bytes to the file"""
[docs] @abstractmethod def read_line(self, start, num_voxels): """Reads a line of bytes from the file""" pass
[docs] @abstractmethod def close_file(self): """Close the file""" pass
[docs] def read_image(self, start_local, size_local): """Read the specified part of the image""" # Compute coordinate ranges ranges = [range(st, st + sz) for st, sz in zip(start_local, size_local)] # Exclude first coordinate and get others in reverse order ranges_to_iterate = ranges[:0:-1] # Initialise the output array only when we know the data tyoe combined_image = ImageWrapper(origin=start_local, image_size=size_local) # Iterate over each line (equivalent to multiple for loops) for start_points in itertools.product(*ranges_to_iterate): start = [start_local[0]] + list(reversed(start_points)) size = np.ones_like(size_local) size[0] = size_local[0] # Read one image line from the file image_line = self.read_line(start, size[0]) sub_image = ImageWrapper( origin=start, image=ImageStorage(image_line).reshape(size)) combined_image.set_sub_image(sub_image) return combined_image.image
[docs] def write_image(self, data_source, rescale_limits): """Create and write out this file, using data from this image source""" # Compute coordinate ranges ranges = [range(0, sz) for sz in self.size] # Exclude first two coordinates and get others in reverse order ranges_to_iterate = ranges[:1:-1] # Iterate over each line (equivalent to multiple for loops) for main_dim_size in itertools.product(*ranges_to_iterate): start = [0] * min(2, len(self.size)) + \ list(reversed(main_dim_size)) # Size contains the first two dimensions and ones size = self.size[:2] + [1] * (len(self.size) - 2) # Read one image slice from the transformed source image_slice = data_source.read_image(start, size) # Write out the image data to the file for line in range(0, size[1] if len(size) > 1 else 1): out_start = deepcopy(start) out_size = [self.size[0]] + [1] * (len(self.size) - 1) if len(start) > 1: out_start[1] = line image_line = image_slice.get_sub_image(out_start, out_size).image self.write_line(out_start, image_line.get_raw(), rescale_limits) self.close_file()
[docs]class BlockImageFileReader(ImageFileReader): """Base class for writing data from source to destination as a 2d block"""
[docs] @abstractmethod def save(self, image): """Write the image to the file"""
[docs] @abstractmethod def load(self): """Reads an image from the file""" pass
[docs] @abstractmethod def close_file(self): """Close the file""" pass
def __init__(self, image_size, data_type): self.size = image_size self.data_type = data_type
[docs] def read_image(self, start_local, size_local): """Read the specified part of the image""" image_data_raw = self.load() image_data = ImageStorage.from_raw_image(image_data_raw, self.size) if image_data.get_size() != self.size: raise ValueError("Image is not the expected size") image = ImageWrapper(origin=np.zeros_like(start_local), image=image_data) return image.get_sub_image(start_local, size_local).image
[docs] def write_image(self, data_source, rescale_limits): """Create and write out this file, using data from this image source""" numpy_format = self.data_type.get_numpy_format() data_type = np.dtype(numpy_format) image_data = \ data_source.read_image(np.zeros_like(self.size), self.size).image image_data_raw = image_data.get_raw_image() if rescale_limits: image_data_raw = rescale_image(data_type, image_data_raw, rescale_limits) else: image_data_raw = np.around(image_data_raw).astype(data_type) if self.data_type.get_is_rgb(): image_data_raw = to_rgb(image_data_raw) else: if image_data_raw.dtype != data_type: image_data_raw = np.around(image_data_raw).astype(data_type) self.save(image_data_raw) self.close_file()