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.
 
 
 

81 lines
3.0 KiB

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