-
Notifications
You must be signed in to change notification settings - Fork 1
/
fm_image_sequence.py
279 lines (236 loc) · 10.6 KB
/
fm_image_sequence.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
"""This module defines an Image Sequence that contains images of type fm_image."""
import os
import sys
import PIL
import numpy as np
import tifffile as tf
import fm_image
class ImageSequence():
"""Image sequences containing multiple images of type fm_image
"""
def __init__(self,
path_noisy,
save_path_noisy,
save_path_denoised,
time_series_params,
frame_range = None,
path_gt = None,
crop_region = None):
self.images = []
self.path_noisy = path_noisy
self.save_path_noisy = save_path_noisy
self.save_path_denoised = save_path_denoised
if path_gt == "NULL":
self.path_gt = None
else:
self.path_gt = path_gt
if crop_region == "NULL":
self.crop_region = None
else:
self.crop_region = crop_region
self.is_time_series = time_series_params["is_series"]
if not self.is_time_series:
self.back_and_forth = False
else:
self.back_and_forth = time_series_params["back_and_forth"]
if frame_range == "NULL":
frame_range = None
assert(frame_range is None or len(frame_range) == 2)
self.frame_range = frame_range
self.load_images()
def load_images(self):
"""load tif or png images (with their corresponding ground truth image if available)
"""
# both, noisy images and ground truths are folders
if os.path.isdir(self.path_noisy) and os.path.isdir(self.path_gt):
img_paths = list(self.get_image_paths(self.path_noisy))
img_gt_paths = list(self.get_image_paths(self.path_noisy))
for i, (file, file_gt) in enumerate(zip(img_paths, img_gt_paths)):
assert(f"{file}"[-6:-4] == f"{file_gt}"[-6:-4] or file_gt == "NULL")
img_list = self.prepare_imgs(file,
self.save_path_noisy,
self.save_path_denoised,
file_gt = file_gt,
frame_number = i)
self.images.extend(img_list)
# there are multiple noisy images in one folder, ground truth not available
elif os.path.isdir(self.path_noisy) and not self.path_gt:
img_paths = list(self.get_image_paths(self.path_noisy))
for i, file in enumerate(img_paths):
img_list = self.prepare_imgs(file,
self.save_path_noisy,
self.save_path_denoised,
file_gt = None,
frame_number = i)
self.images.extend(img_list)
# noisy images are in one folder and there is only one ground truth image
elif os.path.isdir(self.path_noisy) and not os.path.isdir(self.path_gt):
img_paths = list(self.get_image_paths(self.path_noisy))
for i, file in enumerate(img_paths):
img_list = self.prepare_imgs(file,
self.save_path_noisy,
self.save_path_denoised,
frame_number = i)
self.images.extend(img_list)
# there is only one noisy image
else:
img_list = self.prepare_imgs(self.path_noisy,
self.save_path_noisy,
self.save_path_denoised)
self.images.extend(img_list)
# adjust frame range
if self.frame_range:
self.images = self.images[self.frame_range[0] : self.frame_range[1]]
def load_png(self, path, crop_region = None):
"""load a png image
Args:
path (str): path to image
crop_region (list, optional): list with the crop region: [left, top, right, bottom].
Defaults to None.
Returns:
np.Array: numpy array with the image, shape: (1, shape_x, shape_y)
"""
# convert to grayscale
img = PIL.Image.open(path).convert('L')
if crop_region:
# crop region: [left, top, right, bottom]
img = img.crop(tuple(crop_region))
img_np = np.array(img)[None, ...].astype(np.float32) / 255
return img_np
def load_tif(self, path, imgs_min = None, imgs_max = None):
"""load tif image
Args:
path (str): path to tif file
imgs_min (float, optional): minimum value of all images in the tiff file.
Defaults to None.
imgs_max (float, optional): maximum value of all images in the tiff file.
Defaults to None.
Returns:
(List of np.Array, float, float): list of images as np.Array(1, shape_x, shape_y),
imgs_min, imgs_max
"""
imgs = tf.imread(path)
imgs = imgs.astype(np.float32)
if len(imgs.shape) < 3:
imgs = imgs[None, ...]
if self.crop_region:
imgs = imgs[:, self.crop_region[1]:self.crop_region[3],
self.crop_region[0]:self.crop_region[2]]
img_list = []
num_imgs = imgs.shape[0]
if imgs_min is None or imgs_max is None:
imgs_min = imgs.min()
imgs_max = imgs.max()
if num_imgs == 1:
img = (imgs - imgs_min) / (imgs_max - imgs_min)
img = img.clip(min=0, max=1)
img_list.append(img)
else:
for i in range(num_imgs):
img = (imgs[i][None, ...] - imgs_min) / (imgs_max - imgs_min)
img = img.clip(min=0, max=1)
img_list.append(img)
return img_list, imgs_min, imgs_max
def prepare_imgs_png(self, file_noisy, save_dir_noisy, save_dir_denoised, file_gt = None,
frame_number = 0):
"""create an fm_image for the image
Args:
save_dir_noisy (str): path where to save the noisy image
save_dir_denoised (str): path where to save the denoised image
frame_number (int): number of the image
Returns:
List[fm_image.Image]: list with one fm_image
"""
img_noisy = self.load_png(file_noisy, self.crop_region)
img_gt = None
if file_gt:
assert file_noisy.endswith(".png")
img_gt = self.load_png(file_gt, self.crop_region)
image = fm_image.Image(data_noisy = img_noisy,
path_noisy = file_noisy,
save_dir_noisy = save_dir_noisy,
save_dir_denoised = save_dir_denoised,
data_gt = img_gt,
path_gt = file_gt,
crop_region = self.crop_region,
frame_number = frame_number)
image.save_noisy()
return [image]
def prepare_imgs_tif(self, file_noisy, save_dir_noisy, save_dir_denoised):
"""create fm_images for each image
Args:
save_dir_noisy (str): path where to save noisy images
save_dir_denoised (str): path where to save the denoised images
Returns:
(List[fm_image.Image]): list of fm_images
"""
imgs_noisy, imgs_min, imgs_max = self.load_tif(file_noisy)
if self.path_gt:
assert file_noisy.endswith(".tif")
imgs_gt, _, _ = self.load_tif(self.path_gt, imgs_min, imgs_max)
images = []
for i, (img_noisy, img_gt) in enumerate(zip(imgs_noisy, imgs_gt)):
image = fm_image.Image(data_noisy = img_noisy,
path_noisy = file_noisy,
save_dir_noisy = save_dir_noisy,
save_dir_denoised = save_dir_denoised,
data_gt = img_gt,
path_gt = self.path_gt,
crop_region = self.crop_region,
frame_number = i,
images_min = imgs_min,
images_max = imgs_max)
image.save_noisy()
images.append(image)
else:
images = []
for i, img_noisy in enumerate(imgs_noisy):
image = fm_image.Image(data_noisy = img_noisy,
path_noisy = file_noisy,
save_dir_noisy = save_dir_noisy,
save_dir_denoised = save_dir_denoised,
data_gt = None,
path_gt = self.path_gt,
crop_region = self.crop_region,
frame_number = i,
images_min = imgs_min,
images_max = imgs_max)
image.save_noisy()
images.append(image)
return images
def prepare_imgs(self, path_noisy, save_dir_noisy, save_dir_denoised, file_gt = None,
frame_number = 0):
"""create an fm_image for each image
Args:
path_noisy (str): path to the noisy image
save_dir_noisy (str): path to where the noisy images are stored
save_dir_denoised (str): path to where the denoised images are stored
frame_number (int, optional): number of the image/frame. Defaults to 0.
Returns:
List[fm_image]: list of fm_images
"""
if path_noisy.endswith(".png"):
image_list = self.prepare_imgs_png(path_noisy, save_dir_noisy, save_dir_denoised,
file_gt, frame_number)
return image_list
if path_noisy.endswith(".tif"):
image_list = self.prepare_imgs_tif(path_noisy, save_dir_noisy, save_dir_denoised)
return image_list
print("error: file ends neither with png nor tif")
sys.exit()
def get_image_paths(self, path, rev=False):
"""iterator over all png and tif files in a directory
Args:
path (str): path to the directory
rev (bool, optional): iterate in reverse alphabetic order. Defaults to False.
Yields:
str: path to png/tif file
"""
if rev:
files = reversed(sorted(os.listdir(path)))
else:
files = sorted(os.listdir(path))
for file in files:
if os.path.isfile(os.path.join(path, file)) and (f"{file}".endswith(".png") or
f"{file}".endswith(".tif")):
yield f"{path}/{file}"