You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

93 lines
2.9 KiB

import collections
import numpy as np
import logging
log = logging.getLogger(__name__)
class Image(object):
def __init__(self, timestamp, raw_array, field_of_view, channel, z_level, height, width):
self._timestamp = timestamp
self._raw_data = raw_array
self._field_of_view = field_of_view
self._channel = channel
self._z_level = z_level
self._height = height
self._width = width
self._data = None
def __repr__(self):
return "\n".join(["<ND2 Image>",
"%sx%s (HxW)" % (self._height, self._width),
"Timestamp: %s" % self.timestamp,
"Field of View: %s" % self.field_of_view,
"Channel: %s" % self.channel,
"Z-Level: %s" % self.z_level,
])
@property
def field_of_view(self):
return self._field_of_view
@property
def timestamp(self):
"""
The number of seconds after the beginning of the acquisition that the image was taken. Note that for a given
field of view and z-level offset, if you have images of multiple channels, they will all be given the same
timestamp. No, this doesn't make much sense. But that's how ND2s are structured, so if your experiment depends
on millisecond accuracy, you need to find an alternative imaging system.
"""
return self._timestamp / 1000.0
@property
def channel(self):
return self._channel
@property
def z_level(self):
return self._z_level
@property
def data(self):
if self._data is None:
# The data is just a flat, 1-dimensional array. We convert it to a 2D image here.
self._data = np.reshape(self._raw_data, (self._height, self._width))
return self._data
class ImageSet(object):
"""
A group of images that share the same timestamp. NIS Elements doesn't store a unique timestamp for every
image, rather, it stores one for each set of images that share the same field of view and z-axis level.
"""
def __init__(self):
self._images = collections.defaultdict(dict)
def __repr__(self):
return "\n".join(["<ND2 Image Set>",
"Image count: %s" % len(self)])
def get(self, channel="", z_level=0):
"""
Retrieve an image with a given channel and z-level. For most users, z_level will always be 0.
"""
try:
image = self._images[channel][z_level]
except KeyError:
return None
else:
return image
def __len__(self):
""" The number of images in the image set. """
return sum([len(channel) for channel in self._images.values()])
def add(self, image):
"""
:type image: nd2reader.model.Image()
"""
self._images[image.channel][image.z_level] = image