cell-data-loader 0.0.32__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,3 @@
1
+ __version__ = "0.0.32"
2
+
3
+ from .cell_data_loader import *
@@ -0,0 +1,47 @@
1
+ #!/usr/bin/python
2
+
3
+ import torch.utils.data as data
4
+ from PIL import Image
5
+ import torchvision.transforms as transforms
6
+
7
+ class BaseDataset(data.Dataset):
8
+ def __init__(self):
9
+ super(BaseDataset, self).__init__()
10
+
11
+ def name(self):
12
+ return 'BaseDataset'
13
+
14
+ def initialize(self, opt):
15
+ pass
16
+
17
+ def get_transform(opt):
18
+ transform_list = []
19
+ if opt.resize_or_crop == 'resize_and_crop':
20
+ osize = [opt.loadSize, opt.loadSize]
21
+ transform_list.append(transforms.Scale(osize, Image.BICUBIC))
22
+ transform_list.append(transforms.RandomCrop(opt.fineSize))
23
+ elif opt.resize_or_crop == 'crop':
24
+ transform_list.append(transforms.RandomCrop(opt.fineSize))
25
+ elif opt.resize_or_crop == 'scale_width':
26
+ transform_list.append(transforms.Lambda(
27
+ lambda img: __scale_width(img, opt.fineSize)))
28
+ elif opt.resize_or_crop == 'scale_width_and_crop':
29
+ transform_list.append(transforms.Lambda(
30
+ lambda img: __scale_width(img, opt.loadSize)))
31
+ transform_list.append(transforms.RandomCrop(opt.fineSize))
32
+
33
+ if opt.isTrain and not opt.no_flip:
34
+ transform_list.append(transforms.RandomHorizontalFlip())
35
+
36
+ transform_list += [transforms.ToTensor(),
37
+ transforms.Normalize((0.5, 0.5, 0.5),
38
+ (0.5, 0.5, 0.5))]
39
+ return transforms.Compose(transform_list)
40
+
41
+ def __scale_width(img, target_width):
42
+ ow, oh = img.size
43
+ if (ow == target_width):
44
+ return img
45
+ w = target_width
46
+ h = int(target_width * oh / ow)
47
+ return img.resize((w, h), Image.BICUBIC)
@@ -0,0 +1,622 @@
1
+ #!/usr/bin/python3
2
+
3
+ import os,sys,json,csv,cv2,glob,random,re,warnings
4
+ import numpy as np
5
+ import pickle
6
+ from numpy.random import choice,shuffle
7
+ from math import floor,ceil,sqrt
8
+ from PIL import Image,ImageEnhance
9
+ from scipy import ndimage
10
+ from scipy.signal import resample
11
+ from scipy.ndimage.interpolation import map_coordinates
12
+ from scipy.ndimage.filters import gaussian_filter
13
+ from .base_dataset import BaseDataset
14
+ import torch,torchvision
15
+ #torchvision.disable_beta_transforms_warning()
16
+ from .util import *
17
+ import torchvision.transforms as transforms
18
+
19
+ #import openslide
20
+ #import czifile
21
+ try:
22
+ import slideio
23
+ except:
24
+ warnings.warn("""No valid slideio installed, SVS and CZI files cannot
25
+ be read in -- run `pip install slideio` for support""")
26
+
27
+ class ImageLabelObject(BaseDataset):
28
+ def __init__(self,
29
+ filename,
30
+ mode="whole",
31
+ dtype="torch",
32
+ gpu_ids="",
33
+ dim=(64,64),
34
+ n_channels = None):
35
+ self.filename = filename
36
+ self.image = None
37
+ self.label = None
38
+ self.boxlabel = None
39
+ self.mode = mode
40
+ self.dtype = dtype
41
+ self.dim = dim
42
+ self.gpu_ids = gpu_ids
43
+ self.n_channels = n_channels
44
+ def im_type(self):
45
+ _,ext = os.path.splitext(self.filename)
46
+ ext = ext.lower()
47
+ if ext in [".png",".jpg",".jpeg",".tiff",".tif"]:
48
+ return "regular"
49
+ elif ext in [".svs"]:
50
+ #pip install aicspylibczi>=3.1.1
51
+ return "svs"
52
+ elif ext in [".czi"]:
53
+ return "czi"
54
+ else:
55
+ raise Exception("Image type unsupported: %s" % ext)
56
+ def get_image(self):
57
+ if self.image is None:
58
+ if self.im_type() == "regular":
59
+ self.image = cv2.imread(self.filename)
60
+ #elif self.im_type() == "svs":
61
+ #n = openslide.OpenSlide(self.filename)
62
+ #levels = n.level_dimensions
63
+ #level=len(levels)-1
64
+ #width0,height0 = levels[level]
65
+ #self.image = n.read_region((0,0),level,(width0,height0))
66
+ #self.image = np.array(self.image)
67
+ elif self.im_type() == "czi" or self.im_type() == "svs":
68
+ #https://towardsdatascience.com/slideio-a-new-python-library-for-reading-medical-images-11858a522059
69
+ #self.image = czifile.imread(self.filename)
70
+ try:
71
+ self.image = slideio.open_slide(self.filename,
72
+ self.im_type().upper())
73
+ except:
74
+ raise Exception(
75
+ "SVS/CZI read on %s failed -- check slideio install" %\
76
+ self.filename
77
+ )
78
+ n_scenes = self.image.num_scenes
79
+ self.image = self.image.get_scene(n_scenes-1)
80
+ self.image = self.image.read_block(
81
+ slices=(0,self.image.num_z_slices)
82
+ )
83
+ self.image = np.squeeze(self.image)
84
+ #self.image = np.moveaxis(self.image,0,-1)
85
+ if self.image.dtype != np.uint8:
86
+ self.image = self.image.astype(np.uint8)
87
+ if self.mode == "whole" and self.im_type() == "regular":
88
+ self.image = cv2.resize(self.image,self.dim[::-1])
89
+ assert(not np.isnan(self.image[0,0,0]))
90
+ elif self.mode == "whole" and self.im_type() in ["czi","svs"]:
91
+ #self.image = resize(self.image,self.dim)
92
+ self.image = cv2.resize(self.image,self.dim[::-1])
93
+ if len(self.image.shape) < 3:
94
+ self.image = np.expand_dims(self.image,axis=2)
95
+ s = self.image.shape
96
+ assert(len(s) == 3)
97
+ if s[0] < s[1] and s[0] < s[2]:
98
+ self.image = np.moveaxis(self.image,0,-1)
99
+ if len(self.image.shape) != 3:
100
+ self.image = np.expand_dims(self.image,axis=2)
101
+ assert(len(self.image.shape) == 3)
102
+ if self.n_channels is not None and \
103
+ self.image.shape[2] != self.n_channels:
104
+ self.image = resample(self.image,
105
+ self.n_channels,axis=2)
106
+ if self.dtype == "torch":
107
+ self.image = torch.tensor(self.image)
108
+ assert(len(self.image.size()) == 3)
109
+ elif self.dtype == "numpy":
110
+ assert(len(self.image.shape) == 3)
111
+ else:
112
+ raise Exception("Unimplemented dtype: %s" % self.dtype)
113
+ return self.image
114
+ def get_cell_box_label(self):
115
+ if self.boxlabel is None:
116
+ self.boxlabel,_ = get_cell_boxes_from_image(self.get_image())
117
+ return self.boxlabel
118
+ def get_orig_size(self):
119
+ if self.dtype == "torch":
120
+ s = self.get_image().size()
121
+ elif self.dtype == "numpy":
122
+ s = self.get_image().shape
123
+ else:
124
+ raise Exception("Unimplemented dtype: %s" % self.dtype)
125
+ return s
126
+ def get_n_channels(self):
127
+ if self.n_channels is not None:
128
+ return self.n_channels
129
+ s = self.get_orig_size()
130
+ if len(s) == 2: return 1
131
+ s_sorted = sorted(s,reverse=True)
132
+ return s_sorted[2]
133
+ def get_orig_dims(self):
134
+ s = self.get_orig_size()
135
+ s_sorted = sorted(s,reverse=True)
136
+ x,y = s_sorted[0],s_sorted[1]
137
+ if x == y: return x,y
138
+ if s.index(x) > s.index(y):
139
+ return y,x
140
+ else:
141
+ return x,y
142
+ def get_scaled_dims(self):
143
+ x,y = self.get_orig_dims()
144
+ return x // self.dim[0], y // self.dim[1]
145
+ def get_box_label_filename(self):
146
+ name,ext = os.path.splitext(self.filename)
147
+ filename = os.path.join(os.path.dirname(name),
148
+ ".%s_boxlabel.csv" % os.path.basename(name))
149
+ return filename
150
+ def read_box_label(self,box_label_file=None):
151
+ if box_label_file is None:
152
+ box_label_file = self.get_box_label_filename()
153
+ assert(os.path.isfile(box_label_file))
154
+ self.boxlabel = read_in_csv(box_label_file)
155
+ def __len__(self):
156
+ if self.mode == "whole":
157
+ return 1
158
+ elif self.mode == "sliced":
159
+ x,y = self.get_scaled_dims()
160
+ return x*y
161
+ elif self.mode == "cell":
162
+ return len(self.get_cell_box_label())
163
+ else:
164
+ raise Exception("Invalid mode: %s" % self.mode)
165
+ def __getitem__(self,index):
166
+ if self.mode == "whole":
167
+ im = self.get_image()
168
+ return im
169
+ elif self.mode == "sliced":
170
+ x_dim,y_dim = self.get_scaled_dims()
171
+ x = index % (x_dim)
172
+ y = (index // (x_dim)) % (y_dim)
173
+ imslice = self.get_image()[x * self.dim[0]:(x+1)*self.dim[0],
174
+ y * self.dim[1]:(y+1)*self.dim[1],...]
175
+ return imslice
176
+ elif self.mode == "cell":
177
+ if len(self.get_cell_box_label()) == 0:
178
+ #print("len self: %d" % len(self))
179
+ return -1
180
+ #raise Exception("No cells in this image — should not call")
181
+ #warnings.warn("No cells found in %s" % self.filename)
182
+ #return -1
183
+ index = index % len(self.get_cell_box_label())
184
+ x,y,l,w = self.get_cell_box_label()[index]
185
+ return slice_and_augment(self.get_image(),x,y,l,w,
186
+ out_size=self.dim)
187
+ raise Exception("Unimplemented")
188
+ else:
189
+ raise Exception("Invalid mode: %s" % self.mode)
190
+ def clear(self):
191
+ del self.image
192
+ self.image = None
193
+
194
+ class CellDataloader():#BaseDataset):
195
+ def __init__(self,
196
+ *image_folders,
197
+ label_regex = None,
198
+ label_file = None,
199
+ segment_image = "whole",
200
+ augment_image = True,
201
+ dim = (64,64),
202
+ batch_size = 64,
203
+ verbose = True,
204
+ dtype = "torch",
205
+ gpu_ids = None,
206
+ label_balance = True,
207
+ cell_box_regex = None,
208
+ cell_box_filelist = None,
209
+ n_channels = None,
210
+ channels_first = True,
211
+ match_labels=False,
212
+ normalize=True,
213
+ split = None,
214
+ return_filenames = False,
215
+ sample_output_folder = None):
216
+
217
+ self.verbose = verbose
218
+ self.label_balance = label_balance
219
+ self.segment_image = segment_image.lower()
220
+ self.dim = dim
221
+ self.batch_size = batch_size
222
+ self.dtype = dtype
223
+ self.index = 0
224
+ self.im_index = 0
225
+ self.gpu_ids = gpu_ids
226
+ self.cell_box_regex = cell_box_regex
227
+ self.cell_box_filelist = cell_box_filelist
228
+ self.dtype = dtype
229
+ self.n_channels = n_channels
230
+ self.channels_first = channels_first
231
+ self.augment_image = augment_image
232
+ self.normalize = normalize
233
+ self.return_filenames = return_filenames
234
+ self.sample_output_folder = sample_output_folder
235
+
236
+ if self.augment_image and self.dtype == "torch":
237
+ self.augment = transforms.Compose([
238
+ transforms.RandomHorizontalFlip(0.5),
239
+ transforms.RandomVerticalFlip(0.5),
240
+ transforms.GaussianBlur(5),
241
+ transforms.ColorJitter(brightness=(0.5,1.5),
242
+ contrast=(1), saturation=(0.5,1.5), hue=(-0.1,0.1)),
243
+ transforms.RandomResizedCrop(self.dim, antialias=True)])#,
244
+ #transforms.Normalize((0.5,0.5,0.5),(0.5,0.5,0.5))])
245
+ self.augment2 = transforms.Compose([
246
+ transforms.ElasticTransform()])
247
+ """
248
+ If true, outputs given labels equally. This may repeat images if the
249
+ counts of each don't line up.
250
+ """
251
+ self.match_labels = match_labels
252
+ """
253
+ Determines if image folders or file lists exist, then reads them in
254
+ """
255
+ all_filename_lists = []
256
+ duplicate_test = set()
257
+ for img in image_folders:
258
+ flist = get_file_list(img)
259
+ flist_set = set(flist)
260
+ if len(flist_set.intersection(duplicate_test))>0:
261
+ raise Exception("Intersecting files found between labels")
262
+ duplicate_test = duplicate_test.union(flist_set)
263
+ all_filename_lists.append(flist)
264
+
265
+ if self.segment_image not in ["whole","cell","sliced"]:
266
+ raise Exception(
267
+ """
268
+ %s is not a valid option for segment_image.
269
+ Must be 'whole','cell', or 'sliced'
270
+ """ % self.segment_image)
271
+
272
+ """
273
+ Determines the format of the labels in the fed-in data, if they're
274
+ present at all.
275
+ """
276
+ self.label_input_format = "None"
277
+ self.n_labels = 0
278
+ if label_file is not None and label_regex is not None:
279
+ raise Exception('Cannot have a label file and regex')
280
+ if label_file is not None:
281
+ if not os.path.isfile(label_file):
282
+ raise Exception("No label file: %s" % label_file)
283
+ self.label_input_format = "List"
284
+ elif label_regex is not None:
285
+ assert(isinstance(label_regex,list) or isinstance(label_regex,str))
286
+ if isinstance(label_regex,list):
287
+ assert(len(label_regex) > 0)
288
+ self.label_regex = []
289
+ for l in label_regex:
290
+ if isinstance(l,str):
291
+ self.label_regex.append(re.compile(l))
292
+ elif isinstance(l,list):
293
+ self.label_regex.append([re.compile(_) for _ in l])
294
+ else:
295
+ raise Exception(
296
+ f"Label regex {l} must be string or list"
297
+ )
298
+ if len(self.label_regex) == 1:
299
+ self.label_regex = self.label_regex[0]
300
+ self.n_labels = len(self.label_regex) + 1
301
+ else:
302
+ self.label_regex = re.compile(label_regex)
303
+ self.n_labels = 1
304
+ self.label_input_format = "Regex"
305
+ elif len(all_filename_lists) > 1:
306
+ self.label_input_format = "Folder"
307
+ self.n_labels = len(all_filename_lists)
308
+ if self.verbose:
309
+ print("Detected label format: %s" % self.label_input_format)
310
+ if self.segment_image == "cell":
311
+ """
312
+ The case when cells are sliced out of images individually. Requires
313
+ Cellpose.
314
+ """
315
+ try:
316
+ from cellpose import models,io
317
+ except:
318
+ raise Exception("Cellpose import failed -- need valid "+\
319
+ "cellpose version to use cell segmentation option.")
320
+ if self.cell_box_regex is not None:
321
+ assert(len(all_filename_lists) == 1)
322
+ self.cell_box_regex = re.compile(self.cell_box_regex)
323
+ self.label_input_format = "Cell_Box_Regex"
324
+ elif self.cell_box_filelist is not None:
325
+ assert(len(all_filename_lists) == 1)
326
+ if isinstance(self.cell_box_filelist,str): # One image
327
+ self.cell_box_filelist = [[self.cell_box_filelist]]
328
+ elif isinstance(self.cell_box_filelist,list):
329
+ assert(len(self.cell_box_filelist) > 0)
330
+ if isinstance(self.cell_box_filelist[0],str):
331
+ self.cell_box_filelist = [self.cell_box_filelist]
332
+ assert(isinstance(self.cell_box_filelist[0][0],str))
333
+ for i,l in enumerate(self.cell_box_filelist):
334
+ assert(len(all_filenames_list[i]) == len(l))
335
+ for filename in l:
336
+ if not os.path.isfile(filename):
337
+ raise Exception(
338
+ "File doesn't exist: %s" % filename)
339
+ self.label_input_format = "Cell_Box_Filelist"
340
+
341
+ """
342
+ Reads in and determines makeup of image folder
343
+ """
344
+
345
+ self.image_objects = []
346
+ for j,all_filename_list in enumerate(all_filename_lists):
347
+ for i,filename in enumerate(all_filename_list):
348
+ if is_image_file(filename):
349
+ if split is not None:
350
+ s1 = split[0] # List of numbers
351
+ s2 = split[1] # Max number
352
+ assert isinstance(s1,list)
353
+ assert isinstance(s2,int)
354
+ assert all([isinstance(_,int) for _ in s1])
355
+ assert all([ _ < s2 for _ in s1])
356
+ assert all([ _ >= 0 for _ in s1])
357
+ h = hash(filename)
358
+ if h % s2 not in s1:
359
+ continue
360
+ skip = False
361
+ imlabel = ImageLabelObject(filename,
362
+ gpu_ids=self.gpu_ids,
363
+ dtype=self.dtype,
364
+ dim=self.dim,
365
+ mode=self.segment_image)
366
+ if self.label_input_format == "Folder":
367
+ imlabel.label = j
368
+ elif self.label_input_format == "Regex":
369
+ imlabel.label = self.__matchitem__(filename)
370
+ if imlabel.label < 0: skip = True
371
+ elif self.label_input_format == "List":
372
+ imlabel.label = label_file_dict[filename]
373
+ elif self.label_input_format == "Cell_Box_Filelist":
374
+ imlabel.read_box_label(self.cell_box_filelist[j][i])
375
+ elif self.label_input_format == "Cell_Box_Regex":
376
+ raise Exception("Unimplemented")
377
+ imlabel.boxlabel = self.cell_im_regex(filename)
378
+ if skip: continue
379
+ self.image_objects.append(imlabel)
380
+ random.shuffle(self.image_objects)
381
+ if self.match_labels:
382
+ self.sort_to_match_labels()
383
+ if self.verbose:
384
+ print("%d image paths read" % len(self.image_objects))
385
+
386
+ """
387
+ Acts on the above commands to read in the labels as necessary
388
+ """
389
+
390
+ if self.label_input_format == "List":
391
+ label_list = read_label_file(label_file)
392
+
393
+ """
394
+ Makes batch array
395
+ """
396
+ self.batch = None
397
+ self.label_batch = None # [ 0 for _ in range(self.batch_size) ]
398
+ if self.return_labels():
399
+ if self.dtype == "numpy":
400
+ self.label_batch = np.zeros((self.batch_size,self.n_labels))
401
+ elif self.dtype == "torch":
402
+ self.label_batch = torch.zeros((self.batch_size,self.n_labels),
403
+ device = self.gpu_ids)
404
+ sample = self.image_objects[0]
405
+ if n_channels is None:
406
+ self.n_channels = sample.get_n_channels()
407
+ else:
408
+ self.n_channels = n_channels
409
+ if self.normalize and self.dtype == "torch":
410
+ from torchvision.transforms import Normalize
411
+ self.normalizer = Normalize(
412
+ tuple([0.5 for _ in range(self.n_channels)]),
413
+ tuple([0.5 for _ in range(self.n_channels)]))
414
+ for image_object in self.image_objects:
415
+ image_object.n_channels = self.n_channels
416
+ if self.verbose:
417
+ print("%d Channels Detected" % self.n_channels)
418
+ if self.dtype == "torch":
419
+ self.batch = torch.zeros(self.batch_size,self.dim[0],self.dim[1],
420
+ self.n_channels,device=self.gpu_ids)
421
+ elif self.dtype == "numpy":
422
+ self.batch = np.zeros((self.batch_size,self.dim[0],self.dim[1],
423
+ self.n_channels))
424
+ else:
425
+ raise Exception("Unimplemented dtype: %s" % self.dtype)
426
+
427
+ if self.sample_output_folder is not None:
428
+ if self.verbose:
429
+ print("Initiating sample output folder at %s" % \
430
+ self.sample_output_folder)
431
+ os.makedirs(self.sample_output_folder,exist_ok=True)
432
+ self.imcount = 0
433
+ def sort_to_match_labels(self):
434
+ assert(self.match_labels)
435
+ if not self.return_labels():
436
+ warnings.warn("Match labels is set to true but no labels found")
437
+ elif "cell" in self.label_input_format.lower():
438
+ warnings.warn("Match labels is set to true but cell-specific" +\
439
+ " matching unimplemented")
440
+ else:
441
+ assert(self.n_labels) > 1
442
+ label_sorter = {}
443
+ for i in range(self.n_labels):
444
+ label_sorter[i] = []
445
+ label_counter = 0
446
+ image_objects_matched = []
447
+ for obj in self.image_objects:
448
+ label_sorter[obj.label].append(obj)
449
+ while not np.all([label_counter >= len(label_sorter[i])\
450
+ for i in range(self.n_labels)]):
451
+ for j in range(self.n_labels):
452
+ image_objects_matched.append(
453
+ label_sorter[j][label_counter % len(label_sorter[j])])
454
+ label_counter += 1
455
+ self.image_objects = image_objects_matched
456
+ obj_counts = [0 for _ in range(self.n_labels)]
457
+ for obj in self.image_objects:
458
+ obj_counts[obj.label] += 1
459
+ assert(np.all([o == obj_counts[0] for o in obj_counts]))
460
+ assert(len(self.image_objects) // self.n_labels == obj_counts[0])
461
+ def __matchitem__(self,image_file):
462
+ if self.label_input_format != "Regex":
463
+ raise Exception("""
464
+ Label input format must be regex, is currently %s
465
+ """ % self.label_input_format)
466
+ if isinstance(self.label_regex,list):
467
+ m = -1
468
+ for i,reg in enumerate(self.label_regex):
469
+ if isinstance(reg,list):
470
+ expr = np.any(
471
+ [ bool(reg_.search(image_file)) for reg_ in reg ]
472
+ )
473
+ else: expr = bool(reg.search(image_file))
474
+ if expr:
475
+ if m > -1:
476
+ warnings.warn(
477
+ ("Image file %s matches at"+\
478
+ " least two regular expressions") % image_file)
479
+ m = i
480
+ return m
481
+ else:
482
+ if bool(self.label_regex.search(image_file)):
483
+ return 1
484
+ else:
485
+ return 0
486
+ def __iter__(self):
487
+ return self
488
+ def return_labels(self):
489
+ """
490
+ Boolean determining whether labels or just the image should be returned
491
+ """
492
+ if self.label_input_format == "None":
493
+ assert(self.n_labels == 0)
494
+ return False
495
+ elif self.segment_image in ["whole","sliced"]:
496
+ assert(self.n_labels > 0)
497
+ return True
498
+ assert(self.n_labels > 0)
499
+ return True
500
+ def next_im(self):
501
+ """
502
+ Returns the next single image
503
+ """
504
+ #self.index = (self.index + 1) #% len(self)
505
+ if self.index >= len(self.image_objects):
506
+ self.index = 0
507
+ self.im_index = 0
508
+ raise StopIteration
509
+ #assert(len(self.image_objects[self.index]) > 0)
510
+ im = self.image_objects[self.index][self.im_index]
511
+ label = self.image_objects[self.index].label
512
+ fname = self.image_objects[self.index].filename
513
+ self.im_index += 1
514
+ while self.im_index >= len(self.image_objects[self.index]) or \
515
+ (len(self.image_objects[self.index]) == 0):
516
+ self.image_objects[self.index].clear()
517
+ self.im_index = 0
518
+ self.index += 1
519
+ if self.index >= len(self.image_objects): break
520
+ #if self.augment_image and self.dtype == "torch":
521
+ #imdim = im.size()
522
+ #print("imdim: %s" % str(imdim))
523
+ #im = torch.permute(im,[len(imdim)-1]+list(range(0,len(imdim)-1)))
524
+ #print("imdim: %s" % str(im.size()))
525
+ #im = self.augment(im)
526
+ #im = torch.permute(im,list(range(1,len(imdim))) + [0])
527
+ #print("imdim: %s"%str(im.size()))
528
+ return im,label,fname
529
+ def __next__(self):
530
+ """
531
+ Returns the next batch of images
532
+ """
533
+ if self.return_filenames:
534
+ fnames = []
535
+ for i in range(self.batch_size):
536
+ if self.return_labels():
537
+ im,y,fname = self.next_im()
538
+
539
+ while isinstance(im,int) and im == -1:
540
+ im,y,fname = self.next_im()
541
+ if self.n_labels == 0:
542
+ raise Exception(
543
+ "Cannot return labels with self.n_labels as 0")
544
+ elif self.n_labels == 1:
545
+ self.label_batch[i,0] = y
546
+ else:
547
+ for j in range(self.n_labels):
548
+ self.label_batch[i,j] = 0
549
+ self.label_batch[i,y] = 1
550
+ else:
551
+ im,y,fname = self.next_im()
552
+ while isinstance(im,int) and im == -1:
553
+ im,y,fname = self.next_im()
554
+ if self.return_filenames: fnames.append(fname)
555
+ assert(not isinstance(im,int))
556
+ if self.dtype == "torch":
557
+ if len(im.size()) == 2 and self.n_channels == 1:
558
+ im = torch.unsqueeze(im,2)
559
+ self.batch[i,...] = torch.unsqueeze(im,0)
560
+ if self.channels_first:
561
+ b = torch.moveaxis(self.batch,-1,1)
562
+ else:
563
+ b = self.batch
564
+ if (self.augment_image and self.n_channels <= 3) or self.normalize:
565
+ if not self.channels_first:
566
+ b = torch.permute(b,[0,-1] + list(range(1,len(b.size())-1)))
567
+ #print("b.size(): %s" % str(b.size()))
568
+ if self.n_channels <= 3 and self.augment_image:
569
+ b = self.augment(b)
570
+ if self.dim[0] > 32 and self.dim[1] > 32:
571
+ b = self.augment2(b)
572
+ #print("b.size(): %s" % str(b.size()))
573
+ #print([0]+list(range(2,len(b.size()))) + [1])
574
+ if self.normalize:
575
+ b = self.normalizer(b)
576
+ if not self.channels_first:
577
+ b = torch.permute(b,[0]+list(range(2,len(b.size()))) + [1])
578
+ #print("b.size(): %s" % str(b.size()))
579
+ #print("sss")
580
+ elif self.dtype == "numpy":
581
+ if len(im.shape) == 2 and self.n_channels == 1:
582
+ im = np.expand_dims(im,axis=2)
583
+ self.batch[i,...] = np.expand_dims(im,axis=0)
584
+ if self.channels_first:
585
+ b = np.moveaxis(self.batch,-1,1)
586
+ else:
587
+ b = self.batch
588
+ else:
589
+ raise Exception("Unimplemented dtype: %s" % self.dtype)
590
+ if self.return_filenames: assert len(fnames) == self.batch_size
591
+ r = [b]
592
+ if self.sample_output_folder is not None:
593
+ for i in range(b.size()[0]):
594
+ out_file_name = os.path.join(self.sample_output_folder,
595
+ "%.8d" % self.imcount)
596
+ if self.return_labels():
597
+ out_file_name = "%s_%s" % (out_file_name,
598
+ str(self.label_batch[i]))
599
+ if self.return_filenames:
600
+ out_file_name = "%s_%s" % (out_file_name,
601
+ os.path.basename(os.path.splitext(fnames[i])[0]))
602
+ out_file_name = "%s.png" % out_file_name
603
+ self.imcount += 1
604
+ im = b[i,...]
605
+ im = im - im.min()
606
+ if im.max() > 0:
607
+ im = im / im.max()
608
+ if self.dtype == "torch":
609
+ im = im.cpu().detach().numpy()
610
+ if self.channels_first:
611
+ im = np.moveaxis(im, 0, -1)
612
+ im = im * 255
613
+ im = im.astype(np.uint8)
614
+ Image.fromarray(im).save(out_file_name)
615
+
616
+ if self.return_labels():
617
+ r.append(self.label_batch)
618
+ if self.return_filenames:
619
+ r.append(fnames)
620
+ if len(r) == 1: r = r[0]
621
+ else: r = tuple(r)
622
+ return r