Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Base ImageIOReader on FramesSequenceND #320

Merged
merged 10 commits into from
May 5, 2020
Merged
1 change: 1 addition & 0 deletions pims/base_frames.py
Original file line number Diff line number Diff line change
Expand Up @@ -606,3 +606,4 @@ def __repr__(self):
s += "Axis '{0}' size: {1}\n".format(dim, self._sizes[dim])
s += """Pixel Datatype: {dtype}""".format(dtype=self.pixel_type)
return s

62 changes: 54 additions & 8 deletions pims/imageio_reader.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,8 @@

import six

from pims.base_frames import FramesSequenceND
from distutils.version import LooseVersion

from pims.base_frames import FramesSequence
from pims.frame import Frame

try:
Expand All @@ -21,11 +20,12 @@ def available():
return imageio is not None


class ImageIOReader(FramesSequence):
"""
Read images from a video file via a ImageIO interface.
"""
class ImageIOReader(FramesSequenceND):
class_priority = 6

propagate_attrs = ['frame_shape', 'pixel_type', 'metadata',
'get_metadata_raw', 'reader_class_name']

@classmethod
def class_exts(cls):
return {'tiff', 'bmp', 'cut', 'dds', 'exr', 'g3', 'hdr', 'iff', 'j2k',
Expand All @@ -40,6 +40,9 @@ def __init__(self, filename, **kwargs):
if imageio is None:
raise ImportError('The ImageIOReader requires imageio and '
'(for imageio >= 2.5) imageio-ffmpeg to work.')

super(self.__class__, self).__init__()

self.reader = imageio.get_reader(filename, **kwargs)
self.filename = filename
self._len = self.reader.get_length()
Expand All @@ -48,11 +51,54 @@ def __init__(self, filename, **kwargs):
if self._len == float("inf"):
self._len = self.reader.count_frames()

first_frame = self.get_frame(0)
first_frame = self.get_frame_2D(t=0)
self._shape = first_frame.shape
self._dtype = first_frame.dtype

def get_frame(self, i):
self._setup_axes()
self._register_get_frame(self.get_frame_2D, 'yx')

def _setup_axes(self):
"""Setup the xyctz axes, iterate over t axis by default

"""
if self._shape[1] > 0:
self._init_axis('x', self._shape[1])
if self._shape[0] > 0:
self._init_axis('y', self._shape[0])
if self._len > 0:
self._init_axis('t', self._len)

if len(self.sizes) == 0:
raise EmptyFileError("No axes were found for this file.")

# provide the default
self.iter_axes = self._guess_default_iter_axis()


def _guess_default_iter_axis(self):
"""
Guesses the default axis to iterate over based on axis sizes.
Returns:
the axis to iterate over
"""
priority = ['t', 'z', 'c', 'v']
found_axes = []
for axis in priority:
try:
current_size = self.sizes[axis]
except KeyError:
continue

if current_size > 1:
return axis

found_axes.append(axis)

return found_axes[0]

def get_frame_2D(self, **coords):
i = coords['t'] if 't' in coords else 0
frame = self.reader.get_data(i)
rbnvrw marked this conversation as resolved.
Show resolved Hide resolved
return Frame(frame, frame_no=i, metadata=frame.meta)

Expand Down