def _get_features(self, frame, cell_label): """Gets the features of the cell in the frame. Args: frame (int): frame from which to get cell features. cell_label (int): label of the cell. Returns: dict: a dictionary with keys as the feature names. """ # Get the bounding box X_frame = self._get_frame(self.x, frame) y_frame = self._get_frame(self.y, frame) roi = (y_frame == cell_label).astype('int32') props = regionprops(np.squeeze(roi), coordinates='rc')[0] centroid = props.centroid rprop = np.array([ props.area, props.perimeter, props.eccentricity ]) # Extract images from bounding boxes minr, minc, maxr, maxc = props.bbox if self.data_format == 'channels_first': appearance = np.copy(X_frame[:, minr:maxr, minc:maxc]) else: appearance = np.copy(X_frame[minr:maxr, minc:maxc, :]) # Resize images from bounding box appearance = resize(appearance, (self.crop_dim, self.crop_dim), data_format=self.data_format) # Get the neighborhood neighborhood = self._sub_area(X_frame, y_frame, cell_label) # Try to assign future areas if future frame is available # TODO: We shouldn't grab a future frame if the frame is dark (was padded) try: X_future_frame = self._get_frame(self.x, frame + 1) future_area = self._sub_area(X_future_frame, y_frame, cell_label) except IndexError: future_area = neighborhood # future areas are not a feature instead a part of the neighborhood feature return { 'appearance': np.expand_dims(appearance, axis=0), 'distance': np.expand_dims(centroid, axis=0), 'neighborhood': np.expand_dims(neighborhood, axis=0), 'regionprop': np.expand_dims(rprop, axis=0), '~future area': np.expand_dims(future_area, axis=0) }
def test_resize(self): channel_sizes = (3, 1) # skimage used for multi-channel, cv2 otherwise for c in channel_sizes: for data_format in ('channels_last', 'channels_first'): channel_axis = 2 if data_format == 'channels_last' else 0 img = np.stack([_get_image()] * c, axis=channel_axis) resize_shape = (28, 28) resized_img = utils.resize(img, resize_shape, data_format=data_format) if data_format == 'channels_first': assert resized_img.shape[1:] == resize_shape else: assert resized_img.shape[:-1] == resize_shape
def _sub_area(self, X_frame, y_frame, cell_label): """Fetch a neighborhood surrounding the cell in the given frame. Slices out a neighborhood_true_size square region around the center of the provided cell, and reshapes it to neighborhood_scale_size square. Args: X_frame (np.array): 2D numpy array, a frame of raw data. y_frame (np.array): 2D numpy array, a frame of annotated data. cell_label (int): The label of the cell to slice out. Returns: numpy.array: the resized region of X_frame around cell_label. """ pads = ((self.neighborhood_true_size, self.neighborhood_true_size), (self.neighborhood_true_size, self.neighborhood_true_size), (0, 0)) X_padded = np.pad(X_frame, pads, mode='constant', constant_values=0) y_padded = np.pad(y_frame, pads, mode='constant', constant_values=0) roi = (y_padded == cell_label).astype('int32') props = regionprops(np.squeeze(roi), coordinates='rc') center_x, center_y = props[0].centroid center_x, center_y = np.int(center_x), np.int(center_y) x1 = center_x - self.neighborhood_true_size x2 = center_x + self.neighborhood_true_size y1 = center_y - self.neighborhood_true_size y2 = center_y + self.neighborhood_true_size X_reduced = X_padded[x1:x2, y1:y2] # resize to neighborhood_scale_size resize_shape = (2 * self.neighborhood_scale_size + 1, 2 * self.neighborhood_scale_size + 1) X_reduced = resize(X_reduced, resize_shape, data_format=self.data_format) return X_reduced