-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathcomposite.py
305 lines (243 loc) · 11.2 KB
/
composite.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
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
"""Functions to generate composite images and videos for thermal data analysis"""
from abc import ABC, abstractmethod
import argparse
import numpy as np
import matplotlib.pyplot as plt
from helper_functions import printProgressBar, get_description_dict
from dataset import DataSet, get_dataset_CLargs, validate_range_arg
class Composite(ABC):
def __init__(self, dataset: DataSet, gui_instance=None):
self.dataset = dataset
self._img = None
self.plot_title = None
self.colorbar_label = None
self.filename = None
self.gui_instance = gui_instance
@property
def img(self):
if self._img is None:
self._img = self.get_img()
return self._img
def save_img(self):
fig, ax = plt.subplots()
fig.suptitle(self.plot_title)
im = ax.imshow(self.img, cmap='inferno')
_ = ax.figure.colorbar(im, ax=ax, label=self.colorbar_label)
plt.savefig(self.filename + '.png')
plt.imsave(self.filename + '_raw.png', self.img, cmap='inferno')
plt.close()
print('Saved to: ' + str(self.filename))
@abstractmethod
def get_img(self):
pass
class ThresholdImg(Composite):
def __init__(self, dataset: DataSet, threshold: int, gui_instance=None):
super().__init__(dataset, gui_instance)
self.threshold = threshold
self.plot_title = 'Build: ' + self.dataset.build_folder_name + ' Threshold: ' + str(
self.threshold)
self.colorbar_label = '# frames above ' + str(self.threshold)
self.filename = self.dataset.build_folder + '/' + self.dataset.build_folder_name + '_threshold' + str(
self.threshold)
def get_img(self):
# Get frame size info
height, width = self.dataset[0].shape[0], self.dataset[0].shape[1]
# Make blank image to increment
img = np.zeros((height, width), dtype=np.float32)
if self.gui_instance is not None:
self.gui_instance.create_progress_bar()
for i, frame in enumerate(self.dataset):
if self.gui_instance is not None:
self.gui_instance.update_progress_bar(
i - self.dataset.start_frame,
self.dataset.end_frame - self.dataset.start_frame)
printProgressBar(i - self.dataset.start_frame,
self.dataset.end_frame - self.dataset.start_frame,
"Generating threshold image...")
img = np.where(frame > self.threshold, img + 1, img)
if self.gui_instance is not None:
self.gui_instance.remove_progress_bar()
return img
class MaxImg(Composite):
def __init__(self, dataset: DataSet, gui_instance=None):
super().__init__(dataset, gui_instance)
self.plot_title = 'Build: ' + self.dataset.build_folder_name + ' Maximum Temperatures'
self.colorbar_label = 'Temperature (C)'
self.filename = self.dataset.build_folder + '/' + self.dataset.build_folder_name + '_max_temps'
def get_img(self):
# Get frame size info
height, width = self.dataset[0].shape[0], self.dataset[0].shape[1]
# Make blank image to update
max_temp_img = np.zeros((height, width), dtype=np.float32)
if self.gui_instance is not None:
self.gui_instance.create_progress_bar()
for i, frame in enumerate(self.dataset):
if self.gui_instance is not None:
self.gui_instance.update_progress_bar(i,
self.dataset.end_frame)
printProgressBar(i, self.dataset.end_frame,
'Creating max temp composite...')
max_temp_img = np.maximum(max_temp_img, frame)
if self.gui_instance is not None:
self.gui_instance.remove_progress_bar()
return max_temp_img
class AvgImg(Composite):
def __init__(self, dataset: DataSet, gui_instance=None):
super().__init__(dataset, gui_instance)
self.plot_title = 'Build: ' + self.dataset.build_folder_name + ' Average Temperatures'
self.colorbar_label = 'Temperature (C)'
self.filename = self.dataset.build_folder + '/' + self.dataset.build_folder_name + '_avg_temps'
def get_img(self):
# Get frame size info
height, width = self.dataset[0].shape[0], self.dataset[0].shape[1]
# Make blank image to update
avg_temp_img = np.zeros((height, width), dtype=np.float32)
num_pixels = (height + 1) * (width + 1)
if self.gui_instance is not None:
self.gui_instance.create_progress_bar()
cur_pix_num = 0
for row_num, _ in enumerate(avg_temp_img):
for col_num, _ in enumerate(avg_temp_img[row_num]):
if self.gui_instance is not None:
self.gui_instance.update_progress_bar(
cur_pix_num, num_pixels)
printProgressBar(cur_pix_num, num_pixels,
'Generating avg temp composite...')
avg_temp_img[row_num,
col_num] = np.mean(self.dataset[:, row_num,
col_num])
cur_pix_num += 1
if self.gui_instance is not None:
self.gui_instance.remove_progress_bar()
return avg_temp_img
class IntegrationImg(Composite):
def __init__(self, dataset: DataSet, threshold: int, gui_instance=None):
super().__init__(dataset, gui_instance)
self.threshold = threshold
self.plot_title = 'Build: ' + self.dataset.build_folder_name + ' Threshold: ' + str(
self.threshold)
self.colorbar_label = 'Accumulation of temperature of threshold: ' + str(
self.threshold)
self.filename = self.dataset.build_folder + '/' + self.dataset.build_folder_name + '_integration' + str(
self.threshold)
def get_img(self):
# Get frame size info
height, width = self.dataset[0].shape[0], self.dataset[0].shape[1]
# Make blank image to update
integration_img = np.zeros((height, width), dtype=np.float32)
if self.gui_instance is not None:
self.gui_instance.create_progress_bar()
for i, frame in enumerate(self.dataset):
if self.gui_instance is not None:
self.gui_instance.update_progress_bar(
i, self.dataset.end_frame - 1)
printProgressBar(i, self.dataset.end_frame - 1,
'Generating integration image...')
integration_img = np.where(
frame > self.threshold,
integration_img + (frame - self.threshold), integration_img)
if self.gui_instance is not None:
self.gui_instance.remove_progress_bar()
return integration_img
class HotspotImg(Composite):
def __init__(self, dataset: DataSet, gui_instance=None):
super().__init__(dataset, gui_instance)
self.plot_title = 'Build: ' + self.dataset.build_folder_name + ' Hotspots'
self.colorbar_label = 'Temperatue (C)'
self.filename = self.dataset.build_folder + '/' + self.dataset.build_folder_name + '_hotspot'
def get_img(self):
# Get frame size info
height, width = self.dataset[0].shape[0], self.dataset[0].shape[1]
# Make blank image to update
hotspot_img = np.zeros((height, width), dtype=np.float32)
if self.gui_instance is not None:
self.gui_instance.create_progress_bar()
for i, frame in enumerate(self.dataset):
if self.gui_instance is not None:
self.gui_instance.update_progress_bar(
i, self.dataset.end_frame - 1)
printProgressBar(i, self.dataset.end_frame - 1,
'Generating hotspot image...')
max_temp = np.amax(frame)
hotspot_img = np.where(frame == max_temp, max_temp, hotspot_img)
if self.gui_instance is not None:
self.gui_instance.remove_progress_bar()
return hotspot_img
def get_composite_CLargs(parser: argparse.ArgumentParser):
"""Add composite related CL arguments to given parser.
Added Arguments
---------------
threshold: optional
int specifying the threshold to be used for the composite image.
dst_folder: optional
str specifying where to save the composite image. Defaults to build folder.
cap: optional
int specifying the max number of frames to use for composite.
max: optional
0 or 1 specifying whether or not to generate a max temperature composite image.
avg: optional
0 or 1 specifying whether or not to generate an average temperature composite image.
int: optional
int specifying threshold to be used to generate a temperature integration composite image.
hotspot: optional
0 or 1 specifying whether or not to generate a hotspot composite image.
"""
desc_dict = get_description_dict()
parser.add_argument('-threshold',
type=int,
help=desc_dict['threshold'],
default=None)
parser.add_argument('-dst_folder',
type=str,
default=None,
help=desc_dict['thresh_dst_folder'])
parser.add_argument('-cap', type=int, help=desc_dict['thresh_cap'])
parser.add_argument('-max',
type=int,
help=desc_dict['max_temp_composite_CLarg'],
default=0)
parser.add_argument('-avg',
type=int,
help=desc_dict['avg_composite_CLarg'],
default=0)
parser.add_argument('-int',
type=int,
help=desc_dict['int_composite'],
default=None)
parser.add_argument('-hotspot',
type=int,
help=desc_dict['hotspot_CLarg'],
default=None)
if __name__ == '__main__':
arg_parser = argparse.ArgumentParser(
description='Generate a composite image.')
get_dataset_CLargs(arg_parser)
get_composite_CLargs(arg_parser)
args = arg_parser.parse_args()
temp_data = args.temp_data
top = bool(args.top)
bot = bool(args.bot)
composite_threshold = args.threshold
integration_threshold = args.int
destination_folder = args.dst_folder
frame_cap = args.cap
max_composite = bool(args.max)
avg_composite = bool(args.avg)
int_composite = args.int
hotspot_composite = bool(args.hotspot)
start_frame, end_frame = validate_range_arg(args.range)
data_set = DataSet(temp_data,
remove_top_reflection=top,
remove_bottom_reflection=bot,
start_frame=start_frame,
end_frame=end_frame)
if composite_threshold is not None:
ThresholdImg(data_set, composite_threshold).save_img()
if max_composite:
MaxImg(data_set).save_img()
if avg_composite:
AvgImg(data_set).save_img()
if integration_threshold is not None:
IntegrationImg(data_set, integration_threshold).save_img()
if hotspot_composite:
HotspotImg(data_set).save_img()