def _preprocess_mask(self, mask_array, target_shape=None, interpolation=cv2.INTER_AREA): """Image level preprocessing. Reimplement this to add preprocessing""" if target_shape and mask_array != target_shape: # dsize in the order of (x, y) mask_array = augmentation.resize(mask_array, dst_shape=target_shape[::-1], interpolation=interpolation) logging.debug('mask shape {}'.format(mask_array.shape)) return mask_array
def _preprocess_image(self, image_array, interpolation=cv2.INTER_AREA): """Image level preprocessing. Reimplement base class dummy method""" image_array = augmentation.resize(image_array, dst_shape=(0, 0), scale=self.scale, interpolation=interpolation) # image_array = augmentation.pad(image_array, padding=(self.padding_size)) return image_array
def crop_by_bbox_list(self, image_array, bbox_list, bbox_iscorrect_list, scale): for bbox_idx, (bbox, iscorrect) in enumerate( zip(bbox_list, bbox_iscorrect_list)): crop_center, crop_size = get_crop_center_and_size_from_bbox(bbox) if self.crop_by_bbox_size: logging.debug('raw crop_size {}'.format(crop_size)) crop_size = np.array( crop_size ) * self.bbox_dilation_ratio + 2 * self.bbox_dilation_size logging.debug('adjusted crop_size {}'.format(crop_size)) if self.crop_mode == 'square': patch_shape = np.array([max(crop_size), max(crop_size)]).astype(int) elif self.crop_mode == 'bbox': patch_shape = crop_size.astype(int) patch_image_array = self.crop_once(image_array, crop_center, patch_shape=patch_shape, scale=scale) if self.do_resize: patch_image_array = augmentation.resize( patch_image_array, dst_shape=(self.patch_size, self.patch_size)) else: patch_shape = np.asarray( [self.patch_size / scale, self.patch_size / scale]).astype(np.int) patch_image_array = self.crop_once(image_array, crop_center, patch_shape=patch_shape, scale=scale) assert patch_image_array.shape == (self.patch_size, self.patch_size) self.write_arrays(image_sample=patch_image_array, label_sample=None, output_dir=self.output_dir, name=self.name, scale=scale, bbox_idx=bbox_idx, iscorrect=iscorrect, suffix=self.suffix)
def generate_negative_sample(image_path, label_path, patch_size, neg_imagedir, isrotate=False, ignore_padding=0, n_patches=20, key='', nonezero_threshold=0.5, scale=1.0, resize_jitter_list=[0.75, 1.25], max_trial_per_patch=5): """ Generate the negative sample, random choose 100 points, to see if the result meet the demand Args: image_path(str) label_path(str): if empty, then use an all zero mask patch_size(int) neg_imagedir(str) Returns: None """ assert image_path image = cv2.imread(image_path, -1) if label_path: label = cv2.imread(label_path, -1) else: print('Use all zero mask!') label = np.zeros_like(image, dtype=np.uint8) target_size = np.array([patch_size * 3, patch_size * 2]) max_trial = n_patches * max_trial_per_patch # for each patch try up to max_trial_per_patch times i = 0 trial = 0 max_nonzero_ratio = 0 while trial <= max_trial and i < n_patches: trial += 1 resize_ratio_lower, resize_ratio_upper = resize_jitter_list resize_jitter = np.random.uniform(resize_ratio_lower, resize_ratio_upper) image_resize = augmentation.resize(image, scale=resize_jitter * scale) label_resize = augmentation.resize(label, scale=resize_jitter * scale) image_resize_shape = np.asarray(image_resize.shape) if np.any(image_resize_shape < target_size): target_size = np.maximum(target_size, image_resize_shape) image_pad = augmentation.center_pad(image_resize, target_size) label_pad = augmentation.center_pad(label_resize, target_size) # Generate rotation angle randomly if isrotate: degree = generate_rotate_list(rotations_per_axis=1, max_degree=180) M = cv2.getRotationMatrix2D( (image_pad.shape[0] / 2, image_pad.shape[1] / 2), degree[0], 1) # the rotation center must be tuple image_rotate = cv2.warpAffine( image_pad, M, (image_pad.shape[1], image_pad.shape[0])) label_rotate = cv2.warpAffine(label_pad, M, image_pad.shape) image_aug = image_rotate label_aug = label_rotate else: image_aug = image_pad label_aug = label_pad y = random.randint(patch_size / 2, image_aug.shape[0] - patch_size / 2) x = random.randint(patch_size / 2, image_aug.shape[1] - patch_size / 2) label_patch = label_aug[int(y - patch_size / 2):int(y + patch_size / 2), int(x - patch_size / 2):int(x + patch_size / 2)] image_patch = image_aug[int(y - patch_size / 2):int(y + patch_size / 2), int(x - patch_size / 2):int(x + patch_size / 2)] central_label_patch = label_patch[ignore_padding:-ignore_padding, ignore_padding:-ignore_padding] central_image_patch = image_patch[ignore_padding:-ignore_padding, ignore_padding:-ignore_padding] nonzero_ratio = np.count_nonzero( central_image_patch) / central_image_patch.size if not central_label_patch.any(): max_nonzero_ratio = max(max_nonzero_ratio, nonzero_ratio) if nonzero_ratio >= nonezero_threshold: print('============', nonzero_ratio) i += 1 neg_patch = image_patch neg_path = os.path.join( neg_imagedir, key, "{}_neg{:03d}_scale{:.2f}.png".format(key, i, scale)) neg_label_path = os.path.join( neg_imagedir, key, "{}_neg{:03d}_scale{:.2f}_mask.png".format(key, i, scale)) fileio.maybe_make_new_dir(os.path.dirname(neg_path)) fileio.maybe_make_new_dir(os.path.dirname(neg_label_path)) if neg_patch.shape == (patch_size, patch_size) and label_patch.shape == ( patch_size, patch_size): cv2.imwrite(neg_path, neg_patch) cv2.imwrite(neg_label_path, label_patch) else: continue print('max_nonzero_ratio', max_nonzero_ratio)