|
|
- import six
- import numpy as np
-
-
- class Roi(object):
- """
- A ND2 ROI representation.
- Coordinates are the center coordinates of the ROI in (x, y, z) order in micron.
- Sizes are the sizes of the ROI in (x, y, z) order in micron.
- Shapes are represented by numbers, defined by constants in this class.
- All these properties can be set for multiple time points (in ms).
- """
- SHAPE_RECTANGLE = 3
- SHAPE_CIRCLE = 9
-
- TYPE_BACKGROUND = 2
-
- def __init__(self, raw_roi_dict, metadata):
- """
-
- :param raw_roi_dict:
- :param metadata
- """
- self.timepoints = []
- self.positions = []
- self.sizes = []
- self.shape = self.SHAPE_CIRCLE
- self.type = self.TYPE_BACKGROUND
-
- self._img_width_micron = metadata.width * metadata.pixel_microns
- self._img_height_micron = metadata.height * metadata.pixel_microns
- self._pixel_microns = metadata.pixel_microns
-
- self._extract_vect_anims(raw_roi_dict)
-
- def _extract_vect_anims(self, raw_roi_dict):
- """
- Extract the vector animation parameters from the ROI.
- This includes the position and size at the given timepoints.
- :param raw_roi_dict:
- :return:
- """
- number_of_timepoints = raw_roi_dict[six.b('m_vectAnimParams_Size')]
-
- for i in range(number_of_timepoints):
- self._parse_vect_anim(raw_roi_dict[six.b('m_vectAnimParams_%d') % i])
-
- self.shape = raw_roi_dict[six.b('m_sInfo')][six.b('m_uiShapeType')]
- self.type = raw_roi_dict[six.b('m_sInfo')][six.b('m_uiInterpType')]
-
- # convert to NumPy arrays
- self.timepoints = np.array(self.timepoints, dtype=np.float)
- self.positions = np.array(self.positions, dtype=np.float)
- self.sizes = np.array(self.sizes, dtype=np.float)
-
- def _parse_vect_anim(self, animation_dict):
- """
- Parses a ROI vector animation object and adds it to the global list of timepoints and positions.
- :param animation_dict:
- :return:
- """
- self.timepoints.append(animation_dict[six.b('m_dTimeMs')])
-
- # positions are taken from the center of the image as a fraction of the half width/height of the image
- position = np.array((0.5 * self._img_width_micron * (1 + animation_dict[six.b('m_dCenterX')]),
- 0.5 * self._img_height_micron * (1 + animation_dict[six.b('m_dCenterY')]),
- animation_dict[six.b('m_dCenterZ')]))
- self.positions.append(position)
-
- size_dict = animation_dict[six.b('m_sBoxShape')]
-
- # sizes are fractions of the half width/height of the image
- self.sizes.append((size_dict[six.b('m_dSizeX')] * 0.25 * self._img_width_micron,
- size_dict[six.b('m_dSizeY')] * 0.25 * self._img_height_micron,
- size_dict[six.b('m_dSizeZ')]))
-
- def is_circle(self):
- return self.shape == self.SHAPE_CIRCLE
-
- def is_rectangle(self):
- return self.shape == self.SHAPE_RECTANGLE
|