albumentations
albumentations copied to clipboard
Add RandomCropNearBorders transform
Transform used by @ZFTurbo
- Specify the distance from 4 sides in pixels or in percent.
- Sample distance from
[0, specified_distance]
- Crop the corresponding part of the image/mask.
- Resize the crop to its original size.
Something like this:
class RandomCropFromBorders(DualTransform):
"""Cuts out a rectangular portion of the image by randomly indenting each side. There is no resize of image at the end.
Args:
crop_value (float): float value in (0.0, 0.5) range. Default 0.1
crop_left (float): float value in (0.0, 1.0) range. Default 0.1
crop_right (float): float value in (0.0, 1.0) range. Default 0.1
crop_top (float): float value in (0.0, 1.0) range. Default 0.1
crop_bottom (float): float value in (0.0, 1.0) range. Default 0.1
p (float): probability of applying the transform. Default: 1.
Targets:
image, mask, bboxes, keypoints
Image types:
uint8, float32
"""
def __init__(
self,
crop_value=None,
crop_left=None,
crop_right=None,
crop_top=None,
crop_bottom=None,
always_apply=False,
p=1.0
):
super(RandomCropFromBorders, self).__init__(always_apply, p)
self.crop_left = 0.1
self.crop_right = 0.1
self.crop_top = 0.1
self.crop_bottom = 0.1
if crop_value is not None:
self.crop_left = crop_value
self.crop_right = crop_value
self.crop_top = crop_value
self.crop_bottom = crop_value
if crop_left is not None:
self.crop_left = crop_left
if crop_right is not None:
self.crop_right = crop_right
if crop_top is not None:
self.crop_top = crop_top
if crop_bottom is not None:
self.crop_bottom = crop_bottom
def get_params_dependent_on_targets(self, params):
img = params["image"]
x_min = random.randint(0, int(self.crop_left * img.shape[1]))
x_max = random.randint(max(x_min + 1, int((1 - self.crop_right) * img.shape[1])), img.shape[1])
y_min = random.randint(0, int(self.crop_top * img.shape[0]))
y_max = random.randint(max(y_min + 1, int((1 - self.crop_bottom) * img.shape[0])), img.shape[0])
return {"x_min": x_min, "x_max": x_max, "y_min": y_min, "y_max": y_max}
def apply(self, img, x_min=0, x_max=0, y_min=0, y_max=0, **params):
return F_albu.clamping_crop(img, x_min, y_min, x_max, y_max)
def apply_to_mask(self, mask, x_min=0, x_max=0, y_min=0, y_max=0, **params):
return F_albu.clamping_crop(mask, x_min, y_min, x_max, y_max)
def apply_to_bbox(self, bbox, x_min=0, x_max=0, y_min=0, y_max=0, **params):
rows, cols = params["rows"], params['cols']
return F_albu.bbox_crop(bbox, x_min, y_min, x_max, y_max, rows, cols)
def apply_to_keypoint(self, keypoint, x_min=0, x_max=0, y_min=0, y_max=0, **params):
return F_albu.crop_keypoint_by_coords(
keypoint,
crop_coords=(x_min, y_min, x_max, y_max),
crop_height=y_max - y_min,
crop_width=x_max - x_min,
rows=params["rows"],
cols=params["cols"],
)
@property
def targets_as_params(self):
return ["image"]
def get_transform_init_args_names(self):
return "crop_value", "crop_left", "crop_right", "crop_top", "crop_bottom"
Hi @ternaus, I would like to work on this issue.