diff --git a/situr/image/situ_image.py b/situr/image/situ_image.py index aa9f5df..02032ae 100644 --- a/situr/image/situ_image.py +++ b/situr/image/situ_image.py @@ -8,8 +8,9 @@ def extend_dim(array): ones = np.ones((array.shape[0], 1)) return np.append(array, ones, axis=1) + def remove_dim(array): - return array[:,:-1] + return array[:, :-1] class SituImage: @@ -32,7 +33,7 @@ class SituImage: self.files = file_list self.data = None self.nucleaus_channel = nucleaus_channel - + def get_data(self): if self.data is None: self._load_image() @@ -45,8 +46,8 @@ class SituImage: Returns: numpy.array: The loaded image of shape (focus_level, width, height) ''' - return self.get_data()[channel,:,:,:] - + return self.get_data()[channel, :, :, :] + def _load_image(self): ''' Loads the channels of an image from seperate files and returns them as numpy array. @@ -64,7 +65,7 @@ class SituImage: channels.append(np.array(Image.open(file))) image_list.append(channels) self.data = np.array(image_list) - + def unload_image(self): ''' Unloads the image data to free up memory @@ -83,7 +84,7 @@ class SituImage: Returns: image: The image of the specified focus level and channel ''' - img = Image.fromarray(self.get_data()[0,0,:,:]) + img = Image.fromarray(self.get_data()[0, 0, :, :]) img.show() return img @@ -107,9 +108,10 @@ class SituImage: np.array: The peaks found by this method as np.array of shape (n, 2) ''' img = img_as_float(self.get_data()[channel, focus_level, :, :]) - peaks = blob_dog(img, min_sigma=min_sigma, max_sigma=max_sigma, threshold=threshold) + peaks = blob_dog(img, min_sigma=min_sigma, + max_sigma=max_sigma, threshold=threshold) return peaks[:, 0:2] - + def show_channel_peaks(self, channel, focus_level=0, min_sigma=0.75, max_sigma=3, threshold=0.1): ''' Returns and shows the found. Uses get_channel_peaks internally. @@ -128,11 +130,13 @@ class SituImage: Returns: image: The image of the specified focus level and channel with encircled peaks. ''' - peaks = self.get_channel_peaks(channel, focus_level, min_sigma, max_sigma, threshold) - + peaks = self.get_channel_peaks( + channel, focus_level, min_sigma, max_sigma, threshold) + img = Image.fromarray(self.get_data()[channel, focus_level, :, :]) draw = ImageDraw.Draw(img) - for x, y in zip(peaks[:,0], peaks[:,1]): - draw.ellipse((x - 5, y - 5, x + 5, y + 5), outline ='white', width = 3) + for x, y in zip(peaks[:, 0], peaks[:, 1]): + draw.ellipse((x - 5, y - 5, x + 5, y + 5), + outline='white', width=3) img.show() - return img \ No newline at end of file + return img diff --git a/situr/registration/channel_registration.py b/situr/registration/channel_registration.py index 5d63dbe..576c339 100644 --- a/situr/registration/channel_registration.py +++ b/situr/registration/channel_registration.py @@ -1,14 +1,25 @@ +import abc +import open3d as o3 +from probreg import filterreg +from situr.image import extend_dim + +from situr.transformation import ScaleRotateTranslateChannelTransform + + class ChannelRegistration: __metaclass__ = abc.ABCMeta - def do_registration(self, situ_img , reference_channel=0): + def do_registration(self, situ_img, reference_channel=0): # For each channel (except nucleus) compute transform compared to reference_channel # Add Channel transformation to Channel pass + @abc.abstractmethod def register_single_channel(self, peaks_data, reference_peaks): """Performs the channel registration on an image. Expects the peaks in each image as input.""" - raise NotImplementedError(self.__class__.__name__ + '.register_single_channel') + raise NotImplementedError( + self.__class__.__name__ + '.register_single_channel') + class FilterregChannelRegistration(ChannelRegistration): def register_single_channel(self, data_peaks, reference_peaks): @@ -17,7 +28,7 @@ class FilterregChannelRegistration(ChannelRegistration): target = o3.geometry.PointCloud() target.points = o3.utility.Vector3dVector(extend_dim(reference_peaks)) - registration_method=filterreg.registration_filterreg + registration_method = filterreg.registration_filterreg tf_param, _, _ = filterreg.registration_filterreg(source, target) return ScaleRotateTranslateChannelTransform(transform_matrix=tf_param.rot[0:2, 0:2], scale=tf_param.scale, offset=tf_param.t[0:2]) diff --git a/situr/transformation/__init__.py b/situr/transformation/__init__.py index e69de29..46ddf85 100644 --- a/situr/transformation/__init__.py +++ b/situr/transformation/__init__.py @@ -0,0 +1 @@ +from .channel_transformation import ChannelTransform, ScaleRotateTranslateChannelTransform diff --git a/situr/transformation/channel_transformation.py b/situr/transformation/channel_transformation.py index c05acce..189e899 100644 --- a/situr/transformation/channel_transformation.py +++ b/situr/transformation/channel_transformation.py @@ -1,28 +1,35 @@ +import abc +import numpy as np +import scipy + + class ChannelTransform: __metaclass__ = abc.ABCMeta @abc.abstractmethod - def apply_transformation(self, situ_img , channel): + def apply_transformation(self, situ_img, channel): """Performs a transformation on one channel, all focus_levels are transformed the same way""" - raise NotImplementedError(self.__class__.__name__ + '.apply_transformation') + raise NotImplementedError( + self.__class__.__name__ + '.apply_transformation') class ScaleRotateTranslateChannelTransform(ChannelTransform): def __init__(self, transform_matrix, scale=1, offset=np.array([0, 0])): - # TODO: check + # TODO: check # * transform matrix is 2x2 # * offset is array (2,) self.transform_matrix = transform_matrix self.offset = offset self.scale = scale - def apply_tranformation(self, situ_img , channel): + def apply_tranformation(self, situ_img, channel): channel_img = situ_img.get_channel(channel) focus_levels = channel_img.shape[0] for focus_level in range(focus_levels): - img = channel_img [focus_level, :, :] + img = channel_img[focus_level, :, :] - img [:, :] = scipy.ndimage.affine_transform(img, self.transform_matrix) - img [:, :] = scipy.ndimage.zoom(img, self.scale) - img [:, :] = scipy.ndimage.shift(img, self.offset) \ No newline at end of file + img[:, :] = scipy.ndimage.affine_transform( + img, self.transform_matrix) + img[:, :] = scipy.ndimage.zoom(img, self.scale) + img[:, :] = scipy.ndimage.shift(img, self.offset)