[docs]class RandomCrop(object):
"""Crop the given PIL Image at a random location.Args:
size (sequence or int): Desired output size of the crop. If size is an
int instead of sequence like (h, w), a square crop (size, size) is
made.
padding (int or sequence, optional): Optional padding on each border
of the image. Default is None, i.e no padding. If a sequence of length
4 is provided, it is used to pad left, top, right, bottom borders
respectively. If a sequence of length 2 is provided, it is used to
pad left/right, top/bottom borders, respectively.
pad_if_needed (boolean): It will pad the image if smaller than the
desired size to avoid raising an exception. Since cropping is done
after padding, the padding seems to be done at a random offset.
fill: Pixel fill value for constant fill. Default is 0. If a tuple of
length 3, it is used to fill R, G, B channels respectively.
This value is only used when the padding_mode is constant
padding_mode: Type of padding. Should be: constant, edge, reflect or symmetric. Default is constant.- constant: pads with a constant value, this value is specified with fill- edge: pads with the last value on the edge of the image- reflect: pads with reflection of image (without repeating the last value on the edge)padding [1, 2, 3, 4] with 2 elements on both sides in reflect mode
will result in [3, 2, 1, 2, 3, 4, 3, 2]- symmetric: pads with reflection of image (repeating the last value on the edge)padding [1, 2, 3, 4] with 2 elements on both sides in symmetric mode
will result in [2, 1, 1, 2, 3, 4, 4, 3]"""def __init__(self, size, padding=None, pad_if_needed=False, fill=0, padding_mode='constant'):
if isinstance(size, numbers.Number):
self.size = (int(size), int(size))
else:
self.size = size
self.padding = padding
self.pad_if_needed = pad_if_needed
self.fill = fill
self.padding_mode = padding_mode@staticmethod
def get_params(img, output_size):
"""Get parameters for ``crop`` for a random crop.Args:
img (PIL Image): Image to be cropped.
output_size (tuple): Expected output size of the crop.Returns:
tuple: params (i, j, h, w) to be passed to ``crop`` for random crop.
"""
w, h = _get_image_size(img)
th, tw = output_size
if w == tw and h == th:
return 0, 0, h, wi = random.randint(0, h - th)
j = random.randint(0, w - tw)
return i, j, th, twdef __call__(self, img):
"""
Args:
img (PIL Image): Image to be cropped.Returns:
PIL Image: Cropped image.
"""
if self.padding is not None:
img = F.pad(img, self.padding, self.fill, self.padding_mode)# pad the width if needed
if self.pad_if_needed and img.size[0] < self.size[1]:
img = F.pad(img, (self.size[1] - img.size[0], 0), self.fill, self.padding_mode)
# pad the height if needed
if self.pad_if_needed and img.size[1] < self.size[0]:
img = F.pad(img, (0, self.size[0] - img.size[1]), self.fill, self.padding_mode)i, j, h, w = self.get_params(img, self.size)return F.crop(img, i, j, h, w)def __repr__(self):
return self.__class__.__name__ + '(size={0}, padding={1})'.format(self.size, self.padding)[docs]class RandomHorizontalFlip(object):
"""Horizontally flip the given PIL Image randomly with a given probability.Args:
p (float): probability of the image being flipped. Default value is 0.5
"""def __init__(self, p=0.5):
self.p = pdef __call__(self, img):
"""
Args:
img (PIL Image): Image to be flipped.Returns:
PIL Image: Randomly flipped image.
"""
if random.random() < self.p:
return F.hflip(img)
return imgdef __repr__(self):
return self.__class__.__name__ + '(p={})'.format(self.p)def crop(img, i, j, h, w):
"""Crop the given PIL Image.Args:
img (PIL Image): Image to be cropped.
i (int): i in (i,j) i.e coordinates of the upper left corner.
j (int): j in (i,j) i.e coordinates of the upper left corner.
h (int): Height of the cropped image.
w (int): Width of the cropped image.Returns:
PIL Image: Cropped image.
"""
if not _is_pil_image(img):
raise TypeError('img should be PIL Image. Got {}'.format(type(img)))return img.crop((j, i, j + w, i + h))
【Pytorch|Pytorch RandomCrop】