-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathutils.py
229 lines (179 loc) · 6.35 KB
/
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
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
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
"""
Various utility functions used throughout this project.
"""
import os
import numpy as np
import matplotlib.pyplot as plt
import scipy.signal as signal
def kernels_from_x(x0, mode='sym'):
''' optimize takes a single array x
take this 1d array and make the spatial (K_s) and temporal (K_t) kernels
Args:
x0 (array or list): array or list (length of list depends on mode)
mode (string): sets mode of how the spatial and temporal kernels are created
options: 'sym', 'four', 'all'
Returns:
K_s, K_t : two Kernel matrices
'''
if mode == 'sym':
udlr = x0[1]
center = x0[0]
corner = x0[2]
K_s = np.array([[corner, udlr, corner],
[udlr, center, udlr],
[corner, udlr, corner]])
K_t = x0[3:7]
if mode == 'four':
ud = x0[1]
lr = x0[2]
center = x0[0]
corner = x0[3]
K_s = np.array([[corner, ud, corner],
[lr, center, lr],
[corner, ud, corner]])
K_t = x0[4:8]
if mode == 'all':
K_s = np.reshape(x0[0:9],(3,3))
K_t = x0[9:13]
return K_s, K_t
def my_savefig(fig, figure_dir, figname, tight=True):
"""
save a figure given a handle and directory
Params:
fig: matplotlib handle
figure_dir: directory
figname: desired output name
Returns:
None
"""
if tight:
fig.tight_layout()
for e in ['.png', '.pdf','.svg']: # use pdf rather than eps to support transparency
fig.savefig(os.path.join(figure_dir,
figname + e), dpi=600)
def disp_img(img):
"""
display image
"""
plt.imshow(img)
def create_img(name):
"""
create a toy image with a given contrast and edge spacing
Params:
name (string): only options right now is 'toy'
Returns:
y : an image matrix
"""
if name == 'toy':
y = np.zeros((64,16))
img_w, img_h = y.shape
# to start edges only run in one direction
edge_width = 6
edge_spacing = 6
contrast = 0.1
contrast_step = 0.3
w = 0
while w < img_w - (edge_width*2+edge_spacing):
y[w:(w+edge_width),:] = 1
y[(w+edge_width):(w+2*edge_width),:] = 1*contrast
contrast = contrast + contrast_step
w += edge_width*2 + edge_spacing
return y
def GMSD(img, ref, rescale=True, ret_map=False):
"""
Copied from neutompy since there were way too many requirements
This function computes the Gradient Magnitude Similarity Deviation (GMSD).
This is a Python version of the Matlab script provided by the authors in [3]_
Parameters
----------
img : 2d array
Image to compare.
ref : 2d array
Reference image.
rescale : bool, optional
If True the input images were rescaled in such a way that `ref` has a
maximum pixel value of 255. If False no rescaling is performed.
Default value is True.
ret_map : bool, optional
If True the GMSD and GMS map are returned in a tuple.
Default value is False.
Returns
-------
gmsd_val : float
The GMSD value.
gms_map : 2d array
The GMS map, returned only if `map` is True.
References
----------
.. [3] Wufeng Xue, Lei Zhang, Xuanqin Mou, and Alan C. Bovik, "Gradient Magnitude
Similarity Deviation: A Highly Efficient Perceptual Image Quality Index",
http://www.comp.polyu.edu.hk/~cslzhang/IQA/GMSD/GMSD.htm
"""
if rescale:
k = 255.0 / ref.max()
else:
k = 1.0
T = 170
downscale = 2
hx = (1.0/3.0) * np.array([[1, 0, -1],
[1, 0, -1],
[1, 0, -1]])
hy = hx.T
avg_kernel = np.ones((2, 2)) / 4.0
avg_ref = signal.convolve2d(k * ref, avg_kernel, mode='same', boundary='symm')[::downscale,::downscale]
avg_img = signal.convolve2d(k * img, avg_kernel, mode='same', boundary='symm')[::downscale,::downscale]
ref_dx = signal.convolve2d(avg_ref, hx, mode='same', boundary='symm')
ref_dy = signal.convolve2d(avg_ref, hy, mode='same', boundary='symm')
MG_ref = np.sqrt(ref_dx**2 + ref_dy**2)
img_dx = signal.convolve2d(avg_img, hx, mode='same', boundary='symm')
img_dy = signal.convolve2d(avg_img, hy, mode='same', boundary='symm')
MG_img = np.sqrt(img_dx**2 + img_dy**2)
gms_map = (2*MG_ref*MG_img + T) / (MG_img**2 + MG_ref**2 + T)
gmsd_val = np.std(gms_map)
gms_avg = np.mean(gms_map)
if ret_map:
return gmsd_val, gms_avg, gms_map
else:
return gmsd_val, gms_avg
def GradientMag(img, rescale=False, downscale=1):
"""
Copied from GMSD above
(not used above since need the rescaling factor should be the same for reference and image)
Modified from GMSD function above
This is a Python version of the Matlab script provided by the authors in [3]
Parameters
----------
img : 2d array
Image to compare.
rescale : bool, optional
If True the input images were rescaled in such a way that `ref` has a
maximum pixel value of 255. If False no rescaling is performed.
Default value is True.
downscale : int
For a 1-1 mapping of GradientMagnitude and the original image this needs to be 1
GMSD calculations use 2
Returns
-------
gm : 2d array float
The gradient magnitude.
References
----------
.. [3] Wufeng Xue, Lei Zhang, Xuanqin Mou, and Alan C. Bovik, "Gradient Magnitude
Similarity Deviation: A Highly Efficient Perceptual Image Quality Index",
http://www.comp.polyu.edu.hk/~cslzhang/IQA/GMSD/GMSD.htm
"""
if rescale:
k = 255.0 / img.max()
else:
k = 1.0
T = 170
hx = (1.0/3.0) * np.array([[1, 0, -1],
[1, 0, -1],
[1, 0, -1]])
hy = hx.T
avg_kernel = np.ones((2, 2)) / 4.0
avg_img = signal.convolve2d(k * img, avg_kernel, mode='same', boundary='symm')[::downscale,::downscale]
img_dx = signal.convolve2d(avg_img, hx, mode='same', boundary='symm')
img_dy = signal.convolve2d(avg_img, hy, mode='same', boundary='symm')
MG_img = np.sqrt(img_dx**2 + img_dy**2)
return MG_img