| |
| |
| |
| |
| |
| |
| |
| import numpy as np |
|
|
|
|
| class Cell(): |
|
|
| def __init__(self, num_masks, num_patches): |
| self.num_masks = num_masks |
| self.num_patches = num_patches |
| self.size = num_masks + num_patches |
| self.queue = np.hstack([np.ones(num_masks), np.zeros(num_patches)]) |
| self.queue_ptr = 0 |
|
|
| def set_ptr(self, pos=-1): |
| self.queue_ptr = np.random.randint(self.size) if pos < 0 else pos |
|
|
| def get_cell(self): |
| cell_idx = (np.arange(self.size) + self.queue_ptr) % self.size |
| return self.queue[cell_idx] |
|
|
| def run_cell(self): |
| self.queue_ptr += 1 |
|
|
|
|
| class RandomMaskingGenerator: |
|
|
| def __init__(self, input_size, mask_ratio): |
| if not isinstance(input_size, tuple): |
| input_size = (input_size, ) * 3 |
|
|
| self.frames, self.height, self.width = input_size |
|
|
| self.num_patches = self.frames * self.height * self.width |
| self.num_mask = int(mask_ratio * self.num_patches) |
|
|
| def __repr__(self): |
| repr_str = "Mask: total patches {}, mask patches {}".format( |
| self.num_patches, self.num_mask) |
| return repr_str |
|
|
| def __call__(self): |
| mask = np.hstack([ |
| np.zeros(self.num_patches - self.num_mask), |
| np.ones(self.num_mask), |
| ]) |
| np.random.shuffle(mask) |
| return mask |
|
|
|
|
| class TubeMaskingGenerator: |
|
|
| def __init__(self, input_size, mask_ratio): |
| self.frames, self.height, self.width = input_size |
| self.num_patches_per_frame = self.height * self.width |
| self.total_patches = self.frames * self.num_patches_per_frame |
| self.num_masks_per_frame = int(mask_ratio * self.num_patches_per_frame) |
| self.total_masks = self.frames * self.num_masks_per_frame |
|
|
| def __repr__(self): |
| repr_str = "Tube Masking: total patches {}, mask patches {}".format( |
| self.total_patches, self.total_masks) |
| return repr_str |
|
|
| def __call__(self): |
| mask_per_frame = np.hstack([ |
| np.zeros(self.num_patches_per_frame - self.num_masks_per_frame), |
| np.ones(self.num_masks_per_frame), |
| ]) |
| np.random.shuffle(mask_per_frame) |
| mask = np.tile(mask_per_frame, (self.frames, 1)) |
| return mask |
|
|
|
|
| class RunningCellMaskingGenerator: |
|
|
| def __init__(self, input_size, mask_ratio=0.5): |
| self.frames, self.height, self.width = input_size |
| self.mask_ratio = mask_ratio |
|
|
| num_masks_per_cell = int(4 * self.mask_ratio) |
| assert 0 < num_masks_per_cell < 4 |
| num_patches_per_cell = 4 - num_masks_per_cell |
|
|
| self.cell = Cell(num_masks_per_cell, num_patches_per_cell) |
| self.cell_size = self.cell.size |
|
|
| mask_list = [] |
| for ptr_pos in range(self.cell_size): |
| self.cell.set_ptr(ptr_pos) |
| mask = [] |
| for _ in range(self.frames): |
| self.cell.run_cell() |
| mask_unit = self.cell.get_cell().reshape(2, 2) |
| mask_map = np.tile(mask_unit, |
| [self.height // 2, self.width // 2]) |
| mask.append(mask_map.flatten()) |
| mask = np.stack(mask, axis=0) |
| mask_list.append(mask) |
| self.all_mask_maps = np.stack(mask_list, axis=0) |
|
|
| def __repr__(self): |
| repr_str = f"Running Cell Masking with mask ratio {self.mask_ratio}" |
| return repr_str |
|
|
| def __call__(self): |
| mask = self.all_mask_maps[np.random.randint(self.cell_size)] |
| return np.copy(mask) |
|
|