def encode_mask(mask): """ mask: input binary mask, type: uint8 output: full RLE encoding in the format: (x0, y0, w, h), RLE first get minimal axis-aligned region which contains all positive pixels extract this region from mask and calculate mask RLE within the region output position and size of the region, dimensions of the full mask and RLE encoding """ # calculate coordinates of the top-left corner and region width and height (minimal region containing all 1s) x_min, y_min, x_max, y_max = mask_bounds(mask) # handle the case when the mask empty if x_min is None: return (0, 0, 0, 0), [0] else: tl_x = x_min tl_y = y_min region_w = x_max - x_min + 1 region_h = y_max - y_min + 1 # extract target region from the full mask and calculate RLE # do not use full mask to optimize speed and space target_mask = mask[tl_y:tl_y + region_h, tl_x:tl_x + region_w] rle = mask_to_rle(np.array(target_mask)) return (tl_x, tl_y, region_w, region_h), rle
def convert(self, rtype: RegionType): if rtype == RegionType.MASK: return self.copy() elif rtype == RegionType.RECTANGLE: bounds = mask_bounds(self.mask) return Rectangle(bounds[0] + self.offset[0], bounds[1] + self.offset[1], bounds[2] - bounds[0], bounds[3] - bounds[1]) elif rtype == RegionType.POLYGON: bounds = mask_bounds(self.mask) if None in bounds: return Polygon([(0, 0), (0, 0), (0, 0), (0, 0)]) return Polygon([ (bounds[0] + self.offset[0], bounds[1] + self.offset[1]), (bounds[2] + self.offset[0], bounds[1] + self.offset[1]), (bounds[2] + self.offset[0], bounds[3] + self.offset[1]), (bounds[0] + self.offset[0], bounds[3] + self.offset[1])]) else: raise ConversionException("Unable to convert mask region to {}".format(rtype), source=self)
def _optimize(self): bounds = mask_bounds(self.mask) if bounds[0] is None: # mask is empty self._mask = np.zeros((0, 0), dtype=np.uint8) self._offset = (0, 0) else: self._mask = np.copy(self.mask[bounds[1]:bounds[3], bounds[0]:bounds[2]]) self._offset = (bounds[0] + self.offset[0], bounds[1] + self.offset[1])
def bounds(self): bounds = mask_bounds(self.mask) return bounds[0] + self.offset[0], bounds[1] + self.offset[1], bounds[ 2] + self.offset[0], bounds[3] + self.offset[1]