def from_json(cls, data): ''' The function from_json convert Point from json format to Point class object. :param data: input Point in json format :return: Point class object ''' labeler_login = data.get(LABELER_LOGIN, None) updated_at = data.get(UPDATED_AT, None) created_at = data.get(CREATED_AT, None) sly_id = data.get(ID, None) class_id = data.get(CLASS_ID, None) return cls.from_point_location(PointLocation.from_json(data), sly_id=sly_id, class_id=class_id, labeler_login=labeler_login, updated_at=updated_at, created_at=created_at)
def resize_origin_and_bitmap(origin: PointLocation, bitmap: np.ndarray, in_size, out_size): new_size = restore_proportional_size(in_size=in_size, out_size=out_size) row_scale = new_size[0] / in_size[0] col_scale = new_size[1] / in_size[1] # TODO: Double check (+restore_proportional_size) or not? bitmap.shape and in_size are equal? # Make sure the resulting size has at least one pixel in every direction (i.e. limit the shrinkage to avoid having # empty bitmaps as a result). scaled_rows = max(round(bitmap.shape[0] * row_scale), 1) scaled_cols = max(round(bitmap.shape[1] * col_scale), 1) scaled_origin = PointLocation(row=round(origin.row * row_scale), col=round(origin.col * col_scale)) scaled_bitmap = resize_inter_nearest(bitmap, (scaled_rows, scaled_cols)) return scaled_origin, scaled_bitmap
def crop(self, rect): maybe_cropped_bbox = self.to_bbox().crop(rect) if len(maybe_cropped_bbox) == 0: return [] else: [cropped_bbox] = maybe_cropped_bbox cropped_bbox_relative = cropped_bbox.translate( drow=-self.origin.row, dcol=-self.origin.col) cropped_mask = cropped_bbox_relative.get_cropped_numpy_slice( self._data) if not np.any(cropped_mask): return [] return [ Bitmap(data=cropped_mask, origin=PointLocation(row=cropped_bbox.top, col=cropped_bbox.left)) ]
def rotate(self, rotator): ''' The function rotate render the bitmap within the full image canvas and rotate the whole canvas with a given rotator (ImageRotator class object contain size of image and angle to rotate) :param rotator: ImageRotator class object :return: MultichannelBitmap class object ''' full_img_data = np.zeros(rotator.src_imsize + self.data.shape[2:], dtype=self.data.dtype) full_img_data[self.origin.row:(self.origin.row + self.data.shape[0]), self.origin.col:(self.origin.col + self.data.shape[1]), ...] = self.data[:, :, ...] rotated_full_data = rotator.rotate_img(full_img_data, use_inter_nearest=True) # Rotate the bounding box to find out the bounding box of the rotated bitmap within the full image. rotated_bbox = self.to_bbox().rotate(rotator) rotated_origin = PointLocation(row=rotated_bbox.top, col=rotated_bbox.left) return MultichannelBitmap( data=rotated_bbox.get_cropped_numpy_slice(rotated_full_data), origin=rotated_origin)
def crop(self, rect): ''' Crop the current Bitmap object with a given rectangle :param rect: Rectangle class object :return: Bitmap class object ''' maybe_cropped_bbox = self.to_bbox().crop(rect) if len(maybe_cropped_bbox) == 0: return [] else: [cropped_bbox] = maybe_cropped_bbox cropped_bbox_relative = cropped_bbox.translate( drow=-self.origin.row, dcol=-self.origin.col) cropped_mask = cropped_bbox_relative.get_cropped_numpy_slice( self._data) if not np.any(cropped_mask): return [] return [ Bitmap(data=cropped_mask, origin=PointLocation(row=cropped_bbox.top, col=cropped_bbox.left)) ]
def crop(self, rect): ''' Crop the current MultichannelBitmap object with a given rectangle :param rect: Rectangle class object :return: MultichannelBitmap class object ''' maybe_cropped_area = self.to_bbox().crop(rect) if len(maybe_cropped_area) == 0: return [] else: [cropped_area] = maybe_cropped_area cropped_origin = PointLocation(row=cropped_area.top, col=cropped_area.left) cropped_area_in_data = cropped_area.translate( drow=-self._origin.row, dcol=-self.origin.col) return [ MultichannelBitmap( data=cropped_area_in_data.get_cropped_numpy_slice( self._data), origin=cropped_origin, ) ]
def flipud(self, img_size): flipped_mask = np.flip(self.data, axis=0) flipped_origin = PointLocation( row=(img_size[0] - flipped_mask.shape[0] - self.origin.row), col=self.origin.col) return self.__class__(data=flipped_mask, origin=flipped_origin)
def fliplr(self, img_size): flipped_mask = np.flip(self.data, axis=1) flipped_origin = PointLocation( row=self.origin.row, col=(img_size[1] - flipped_mask.shape[1] - self.origin.col)) return self.__class__(data=flipped_mask, origin=flipped_origin)
def center(self): return PointLocation(row=(self.top + self.bottom) // 2, col=(self.left + self.right) // 2)
def from_json(cls, data): return cls.from_point_location(PointLocation.from_json(data))
def point_location(self) -> PointLocation: return PointLocation(row=self.row, col=self.col)
def point_location(self) -> PointLocation: ''' The function point_location create PointLocation class object from Point class object :return: PointLocation class object ''' return PointLocation(row=self.row, col=self.col)
def transform_point(self, point): point_np_uniform = np.array([point.row, point.col, 1]) transformed_np = self.affine_matrix.dot(point_np_uniform) # Unwrap numpy types so that round() produces integer results. return PointLocation(row=round(transformed_np[0].item()), col=round(transformed_np[1].item()))
def from_json(cls, data): # TODO validations loc = data[LOC] return cls(location=PointLocation(row=loc[1], col=loc[0]), disabled=data.get(DISABLED, False))
def corners(self): ''' :return: list of coners(PointLocation class objects) of Rectangle ''' return [PointLocation(row=self.top, col=self.left), PointLocation(row=self.top, col=self.right), PointLocation(row=self.bottom, col=self.right), PointLocation(row=self.bottom, col=self.left)]
def center(self): ''' :return: center of rectangle(PointLocation class obgect) ''' return PointLocation(row=(self.top + self.bottom) // 2, col=(self.left + self.right) // 2)
def setUp(self): self.origin = PointLocation(row=0, col=4) self.data = np.array([[[0.0, 0.1], [0.2, 0.3], [0.4, 0.5]], [[0.6, 0.7], [0.8, 0.9], [1.0, 1.1]]], dtype=np.float64) self.bitmap = MultichannelBitmap(data=self.data, origin=self.origin)