Browse Source

#2 finished comments and cleanup of image and image set

feature/load_slices
Jim Rybarski 10 years ago
parent
commit
e6471f5a1f
1 changed files with 74 additions and 20 deletions
  1. +74
    -20
      nd2reader/model/__init__.py

+ 74
- 20
nd2reader/model/__init__.py View File

@ -1,3 +1,5 @@
# -*- coding: utf-8 -*-
import collections import collections
import numpy as np import numpy as np
import logging import logging
@ -7,6 +9,25 @@ log = logging.getLogger(__name__)
class Image(object): class Image(object):
def __init__(self, timestamp, raw_array, field_of_view, channel, z_level, height, width): def __init__(self, timestamp, raw_array, field_of_view, channel, z_level, height, width):
"""
A wrapper around the raw pixel data of an image.
:param timestamp: The number of milliseconds after the beginning of the acquisition that this image was taken.
:type timestamp: int
:param raw_array: The raw sequence of bytes that represents the image.
:type raw_array: array.array()
:param field_of_view: The label for the place in the XY-plane where this image was taken.
:type field_of_view: int
:param channel: The name of the color of this image
:type channel: str
:param z_level: The label for the location in the Z-plane where this image was taken.
:type z_level: int
:param height: The height of the image in pixels.
:type height: int
:param width: The width of the image in pixels.
:type width: int
"""
self._timestamp = timestamp self._timestamp = timestamp
self._raw_data = raw_array self._raw_data = raw_array
self._field_of_view = field_of_view self._field_of_view = field_of_view
@ -25,8 +46,28 @@ class Image(object):
"Z-Level: %s" % self.z_level, "Z-Level: %s" % self.z_level,
]) ])
@property
def data(self):
"""
The actual image data.
:rtype np.array()
"""
if self._data is None:
# The data is just a 1-dimensional array originally.
# We convert it to a 2D image here.
self._data = np.reshape(self._raw_data, (self._height, self._width))
return self._data
@property @property
def field_of_view(self): def field_of_view(self):
"""
Which of the fixed locations this image was taken at.
:rtype int:
"""
return self._field_of_view return self._field_of_view
@property @property
@ -37,56 +78,69 @@ class Image(object):
timestamp. No, this doesn't make much sense. But that's how ND2s are structured, so if your experiment depends 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. on millisecond accuracy, you need to find an alternative imaging system.
:rtype float:
""" """
return self._timestamp / 1000.0 return self._timestamp / 1000.0
@property @property
def channel(self): def channel(self):
"""
The name of the filter used to acquire this image. These are user-supplied in NIS Elements.
:rtype str:
"""
return self._channel return self._channel
@property @property
def z_level(self): def z_level(self):
return self._z_level
"""
The vertical offset of the image. These are simple integers starting from 0, where the 0 is the lowest
z-level and each subsequent level incremented by 1.
@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
For example, if you acquired images at -3 µm, 0 µm, and +3 µm, your z-levels would be:
-3 µm: 0
0 µm: 1
+3 µm: 2
:rtype int:
"""
return self._z_level
class ImageSet(object): 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.
A group of images that were taken at roughly the same time.
""" """
def __init__(self): def __init__(self):
self._images = collections.defaultdict(dict) self._images = collections.defaultdict(dict)
def __len__(self):
""" The number of images in the image set. """
return sum([len(channel) for channel in self._images.values()])
def __repr__(self): def __repr__(self):
return "\n".join(["<ND2 Image Set>", return "\n".join(["<ND2 Image Set>",
"Image count: %s" % len(self)]) "Image count: %s" % len(self)])
def get(self, channel="", z_level=0):
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. 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
:type channel: str
:type z_level: int
def __len__(self):
""" The number of images in the image set. """
return sum([len(channel) for channel in self._images.values()])
"""
return self._images.get(channel).get(z_level)
def add(self, image): def add(self, image):
""" """
Stores an image.
:type image: nd2reader.model.Image() :type image: nd2reader.model.Image()
""" """

Loading…
Cancel
Save