-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathimage_utils.py
116 lines (78 loc) · 3.21 KB
/
image_utils.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
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
import numpy as np
import cv2
from PIL import Image
import torch
IMAGENET_MEAN, IMAGENET_STD = np.array([0.485, 0.456, 0.406]), np.array([0.229, 0.224, 0.225])
def crop_image(image, bbox):
"""Crops area from image specified as bbox. Always returns area of size as bbox filling missing parts with zeros
Args:
image numpy array of shape (height, width, 3): input image
bbox tuple of size 4: input bbox (left, upper, right, lower)
Returns:
cropped_image numpy array of shape (height, width, 3): resulting cropped image
"""
image_pil = Image.fromarray(image)
image_pil = image_pil.crop(bbox)
return np.asarray(image_pil)
def resize_image(image, shape):
return cv2.resize(image, (shape[1], shape[0]), interpolation=cv2.INTER_AREA)
def get_square_bbox(bbox):
"""Makes square bbox from any bbox by stretching of minimal length side
Args:
bbox tuple of size 4: input bbox (left, upper, right, lower)
Returns:
bbox: tuple of size 4: resulting square bbox (left, upper, right, lower)
"""
left, upper, right, lower = bbox
width, height = right - left, lower - upper
if width > height:
y_center = (upper + lower) // 2
upper = y_center - width // 2
lower = upper + width
else:
x_center = (left + right) // 2
left = x_center - height // 2
right = left + height
return left, upper, right, lower
def scale_bbox(bbox, scale):
left, upper, right, lower = bbox
width, height = right - left, lower - upper
x_center, y_center = (right + left) // 2, (lower + upper) // 2
new_width, new_height = int(scale * width), int(scale * height)
new_left = x_center - new_width // 2
new_right = new_left + new_width
new_upper = y_center - new_height // 2
new_lower = new_upper + new_height
return new_left, new_upper, new_right, new_lower
def to_numpy(tensor):
if torch.is_tensor(tensor):
return tensor.cpu().detach().numpy()
elif type(tensor).__module__ != 'numpy':
raise ValueError("Cannot convert {} to numpy array"
.format(type(tensor)))
return tensor
def to_torch(ndarray):
if type(ndarray).__module__ == 'numpy':
return torch.from_numpy(ndarray)
elif not torch.is_tensor(ndarray):
raise ValueError("Cannot convert {} to torch tensor"
.format(type(ndarray)))
return ndarray
def image_batch_to_numpy(image_batch):
image_batch = to_numpy(image_batch)
image_batch = np.transpose(image_batch, (0, 2, 3, 1)) # BxCxHxW -> BxHxWxC
return image_batch
def image_batch_to_torch(image_batch):
image_batch = np.transpose(image_batch, (0, 3, 1, 2)) # BxHxWxC -> BxCxHxW
image_batch = to_torch(image_batch).float()
return image_batch
def normalize_image(image):
"""Normalizes image using ImageNet mean and std
Args:
image numpy array of shape (h, w, 3): image
Returns normalized_image numpy array of shape (h, w, 3): normalized image
"""
return (image / 255.0 - IMAGENET_MEAN) / IMAGENET_STD
def denormalize_image(image):
"""Reverse to normalize_image() function"""
return np.clip(255.0 * (image * IMAGENET_STD + IMAGENET_MEAN), 0, 255)