-
Notifications
You must be signed in to change notification settings - Fork 33
/
Copy pathlib.py
148 lines (108 loc) · 5.42 KB
/
lib.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
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
"""Useful functions for running experiments"""
import os
import cv2
import numpy as np
from PIL import Image as PILImage
import scipy.io as sio
import dilated
__author__ = 'Anurag Arnab'
__copyright__ = 'Copyright (c) 2018, Anurag Arnab'
__credits__ = ['Anurag Arnab', 'Ondrej Miksik', 'Philip Torr']
__email__ = '[email protected]'
__license__ = 'MIT'
def CreateDir(dirname):
"""Create directory if it does not exist."""
try:
os.makedirs(dirname)
except OSError, e:
if e.errno != os.errno.EEXIST:
raise
def SavePredictionScores(pred_scores, adv_scores, im_height, im_width, args, is_debug=False):
"""Saves the outputs of the network in a mat file."""
pred_scores = softmax(pred_scores)
adv_scores = softmax(adv_scores)
conf = pred_scores.max(axis = 0)
adv_conf = adv_scores.max(axis = 0)
entropy_map = entropy(pred_scores)
conf_ratio_map = conf_ratio(pred_scores)
adv_entropy_map = entropy(adv_scores)
adv_conf_ratio_map = conf_ratio(adv_scores)
model_name = args.model_name
image_name = os.path.basename(args.image).split('.')[0]
save_name = os.path.join(
args.out_dir, "{}_scores_{}_eps={}.mat".format(image_name, model_name, args.eps))
if not is_debug:
sio.savemat(save_name, {'conf': conf, 'adv_conf': adv_conf, 'im_height' : im_height, 'im_width': im_width, 'entropy': entropy_map, 'conf_ratio': conf_ratio_map, 'adv_entropy': adv_entropy_map, 'adv_conf_ratio': adv_conf_ratio_map}, do_compression=True)
else:
sio.savemat(save_name, {'unary': pred_scores, 'unary_adv': adv_scores, 'conf': conf, 'adv_conf': adv_conf, 'im_height' : im_height, 'im_width': im_width, 'entropy': entropy_map, 'conf_ratio': conf_ratio_map, 'adv_entropy': adv_entropy_map, 'adv_conf_ratio': adv_conf_ratio_map}, do_compression=True)
return conf
def PreprocessImage(name, pad_size, scale=None, pad_value=cv2.BORDER_REFLECT_101,
resize_dims=None, args=None):
"""Preprocesses the image so that it can be fed into the network.
name: filename of the image
pad_size: the size which the image is padded to for input to the network.
Images which are larger than this are resized down whilst preserving the aspect ratio,
and the smaller side is then padded to the specified size.
scale: Whether to resize the image by a specific scale after padding.
pad_value: Type of padding to use, according to OpenCV.
resize_dims: If this is passed, the image is first resized to the specified size before
doing the padding as described above.
args: Other command-line args passed to the program.
"""
if args.is_dilated:
return dilated.PreprocessImage(name, args)
image = cv2.imread(name, 1).astype(np.float32)
input_image = image - args.mean
# Make image smaller, if it is bigger than pad_width x pad_height
im_height = input_image.shape[0]
im_width = input_image.shape[1]
pad_width, pad_height = im_width, im_height
if pad_size is not None:
pad_width, pad_height = pad_size[0], pad_size[1]
if (im_height > pad_height or im_width > pad_width) and resize_dims is None:
if im_height > im_width:
ratio = float( max(pad_width, pad_height) / float(im_height) )
else:
ratio = float( max(pad_width, pad_height) / float(im_width) )
input_image = cv2.resize(input_image, dsize=( int(im_width * ratio), int(im_height * ratio) ) )
elif resize_dims is not None:
image = cv2.resize(image, dsize=(resize_dims[0], resize_dims[1]))
input_image = cv2.resize(input_image, dsize=(resize_dims[0], resize_dims[1]))
if pad_size is None:
pad_height, pad_width = input_image.shape[0], input_image.shape[1]
if scale is not None:
if scale > 1:
input_image = cv2.resize(input_image, dsize=(0,0), fx=scale, fy=scale,
interpolation=cv2.INTER_CUBIC)
if scale < 1:
input_image = cv2.resize(input_image, dsize=(0,0), fx=scale, fy=scale,
interpolation=cv2.INTER_AREA)
if (pad_width is not None) and (pad_height is not None):
input_image = cv2.copyMakeBorder(input_image, 0, pad_height - input_image.shape[0], 0,
pad_width - input_image.shape[1], pad_value)
input_image = input_image.transpose([2,0,1]) # To make it C x H x W for Caffe
return input_image, im_height, im_width, image
def SavePredictionIm(prediction, palette, save_name):
"""Saves prediction image with a colour map"""
prediction = prediction.astype(np.uint8)
prediction_im = PILImage.fromarray(prediction)
prediction_im.putpalette(palette)
prediction_im.save(save_name)
def softmax(x, axis=0):
y = np.exp(x)
denominator = np.sum(y,axis = axis)
return y / denominator
def entropy(x, axis=0):
epsilon = np.finfo(float).eps
y = -np.sum (x * np.log(x + epsilon), axis = 0)
return y
def conf_ratio(x, axis=0):
"""Ratio of most-confident to second-most confident prediction.
Done in a quick and dirty way: the scores are sorted first.
"""
x_sorted = np.sort(x, axis=axis)
channels = x_sorted.shape[axis]
if channels < 2:
raise AssertionError("Need at least two channels")
epsilon = np.finfo(float).eps
return x_sorted[channels-1,:,:] / (x_sorted[channels-2,:,:] + epsilon)