forked from ando-khachatryan/HiDDeN
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcrop.py
75 lines (59 loc) · 2.9 KB
/
crop.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
import torch.nn as nn
import numpy as np
def random_float(min, max):
"""
Return a random number
:param min:
:param max:
:return:
"""
return np.random.rand() * (max - min) + min
def get_random_rectangle_inside(image, height_ratio_range, width_ratio_range):
"""
Returns a random rectangle inside the image, where the size is random and is controlled by height_ratio_range and width_ratio_range.
This is analogous to a random crop. For example, if height_ratio_range is (0.7, 0.9), then a random number in that range will be chosen
(say it is 0.75 for illustration), and the image will be cropped such that the remaining height equals 0.75. In fact,
a random 'starting' position rs will be chosen from (0, 0.25), and the crop will start at rs and end at rs + 0.75. This ensures
that we crop from top/bottom with equal probability.
The same logic applies to the width of the image, where width_ratio_range controls the width crop range.
:param image: The image we want to crop
:param height_ratio_range: The range of remaining height ratio
:param width_ratio_range: The range of remaining width ratio.
:return: "Cropped" rectange with width and height drawn randomly height_ratio_range and width_ratio_range
"""
image_height = image.shape[2]
image_width = image.shape[3]
remaining_height = int(np.rint(random_float(height_ratio_range[0], height_ratio_range[1]) * image_height))
remaining_width = int(np.rint(random_float(width_ratio_range[0], width_ratio_range[0]) * image_width))
if remaining_height == image_height:
height_start = 0
else:
height_start = np.random.randint(0, image_height - remaining_height)
if remaining_width == image_width:
width_start = 0
else:
width_start = np.random.randint(0, image_width - remaining_width)
return height_start, height_start+remaining_height, width_start, width_start+remaining_width
class Crop(nn.Module):
"""
Randomly crops the image from top/bottom and left/right. The amount to crop is controlled by parameters
heigth_ratio_range and width_ratio_range
"""
def __init__(self, height_ratio_range, width_ratio_range):
"""
:param height_ratio_range:
:param width_ratio_range:
"""
super(Crop, self).__init__()
self.height_ratio_range = height_ratio_range
self.width_ratio_range = width_ratio_range
def forward(self, noised_and_cover):
noised_image = noised_and_cover[0]
# crop_rectangle is in form (from, to) where @from and @to are 2D points -- (height, width)
h_start, h_end, w_start, w_end = get_random_rectangle_inside(noised_image, self.height_ratio_range, self.width_ratio_range)
noised_and_cover[0] = noised_image[
:,
:,
h_start: h_end,
w_start: w_end].clone()
return noised_and_cover