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.
 
 
 

94 lines
3.1 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
@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
@property
def is_valid(self):
"""
Not every image stored in an ND2 is a real image! If you take 4 images at one field of view and 2 at another
in a repeating cycle, there will be 4 images at BOTH field of view. The 2 non-images are the same size as all
the other images, only pure black (i.e. every pixel has a value of zero).
This is probably an artifact of some algorithm in NIS Elements determining the maximum number of possible
images and pre-allocating the space with zeros. Regardless of why they exit, we can't tell that they're
not actual images until we examine the data. If every pixel value is exactly 0, it's a gap image.
"""
return np.any(self._raw_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 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