cell-data-loader 0.0.5__tar.gz → 0.0.7__tar.gz
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.
- {cell_data_loader-0.0.5 → cell_data_loader-0.0.7}/PKG-INFO +15 -1
- {cell_data_loader-0.0.5 → cell_data_loader-0.0.7}/README.md +14 -0
- {cell_data_loader-0.0.5 → cell_data_loader-0.0.7}/example_numpy.py +5 -6
- {cell_data_loader-0.0.5 → cell_data_loader-0.0.7}/example_torch.py +2 -2
- {cell_data_loader-0.0.5 → cell_data_loader-0.0.7}/pyproject.toml +1 -1
- {cell_data_loader-0.0.5 → cell_data_loader-0.0.7}/src/cell_data_loader/cell_data_loader.py +37 -13
- {cell_data_loader-0.0.5 → cell_data_loader-0.0.7}/tests/unit_tests.py +1 -1
- {cell_data_loader-0.0.5 → cell_data_loader-0.0.7}/.gitattributes +0 -0
- {cell_data_loader-0.0.5 → cell_data_loader-0.0.7}/__init__.py +0 -0
- {cell_data_loader-0.0.5 → cell_data_loader-0.0.7}/github_push.sh +0 -0
- {cell_data_loader-0.0.5 → cell_data_loader-0.0.7}/pypi_push.sh +0 -0
- {cell_data_loader-0.0.5 → cell_data_loader-0.0.7}/requirements.txt +0 -0
- {cell_data_loader-0.0.5 → cell_data_loader-0.0.7}/setup.py +0 -0
- {cell_data_loader-0.0.5 → cell_data_loader-0.0.7}/src/cell_data_loader/__init__.py +0 -0
- {cell_data_loader-0.0.5 → cell_data_loader-0.0.7}/src/cell_data_loader/base_dataset.py +0 -0
- {cell_data_loader-0.0.5 → cell_data_loader-0.0.7}/src/cell_data_loader/util.py +0 -0
- {cell_data_loader-0.0.5 → cell_data_loader-0.0.7}/tests/__init__.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.3
|
|
2
2
|
Name: cell_data_loader
|
|
3
|
-
Version: 0.0.
|
|
3
|
+
Version: 0.0.7
|
|
4
4
|
Summary: Converts general images of cells into formats and labels for deep learning pipelines
|
|
5
5
|
Project-URL: Homepage, https://github.com/mleming/CellDataLoader
|
|
6
6
|
Author-email: Matt Leming <mleming@mgh.harvard.edu>
|
|
@@ -86,6 +86,20 @@ for label,image in dataloader:
|
|
|
86
86
|
...
|
|
87
87
|
~~~
|
|
88
88
|
|
|
89
|
+
Boxes
|
|
90
|
+
-----
|
|
91
|
+
|
|
92
|
+
In cases where you need to cut out individual cells from an image and have the coordinates file, cell_data_loader.py accepts an argument, cell_box_filelist, which is a list of files corresponding to the inputs that mark out the coordinates of labels on the cells. The format of the csv is as follows:
|
|
93
|
+
|
|
94
|
+
| X | Y | W | H | Label |
|
|
95
|
+
| - | - | - | - | ----- |
|
|
96
|
+
| 14 | 13 | 5 | 6 | 0 |
|
|
97
|
+
| 20 | 25 | 15 | 5 | 1 |
|
|
98
|
+
|
|
99
|
+
|
|
100
|
+
~~~python
|
|
101
|
+
dataloader = CellDataloader('/path/to/file.svs',cell_box_filelist=['/path/to/boxfile.csv'])
|
|
102
|
+
~~~
|
|
89
103
|
|
|
90
104
|
Arguments
|
|
91
105
|
---------
|
|
@@ -66,6 +66,20 @@ for label,image in dataloader:
|
|
|
66
66
|
...
|
|
67
67
|
~~~
|
|
68
68
|
|
|
69
|
+
Boxes
|
|
70
|
+
-----
|
|
71
|
+
|
|
72
|
+
In cases where you need to cut out individual cells from an image and have the coordinates file, cell_data_loader.py accepts an argument, cell_box_filelist, which is a list of files corresponding to the inputs that mark out the coordinates of labels on the cells. The format of the csv is as follows:
|
|
73
|
+
|
|
74
|
+
| X | Y | W | H | Label |
|
|
75
|
+
| - | - | - | - | ----- |
|
|
76
|
+
| 14 | 13 | 5 | 6 | 0 |
|
|
77
|
+
| 20 | 25 | 15 | 5 | 1 |
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
~~~python
|
|
81
|
+
dataloader = CellDataloader('/path/to/file.svs',cell_box_filelist=['/path/to/boxfile.csv'])
|
|
82
|
+
~~~
|
|
69
83
|
|
|
70
84
|
Arguments
|
|
71
85
|
---------
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
#!/usr/bin/python3
|
|
2
|
-
|
|
3
2
|
from src.cell_data_loader import CellDataloader
|
|
4
3
|
|
|
5
4
|
try:
|
|
@@ -10,7 +9,7 @@ except:
|
|
|
10
9
|
except:
|
|
11
10
|
raise Exception("Need valid tensorflow")
|
|
12
11
|
|
|
13
|
-
import numpy
|
|
12
|
+
import numpy as np
|
|
14
13
|
import os
|
|
15
14
|
|
|
16
15
|
def example_numpy(verbose=True):
|
|
@@ -20,13 +19,13 @@ def example_numpy(verbose=True):
|
|
|
20
19
|
the test/train folders in this script are the same -- you would need to
|
|
21
20
|
have a separate train/test set in your own implementation
|
|
22
21
|
"""
|
|
23
|
-
wd = os.path.dirname(os.path.realpath(__file__))
|
|
22
|
+
wd = os.path.dirname(os.path.dirname(os.path.realpath(__file__)))
|
|
24
23
|
imfolder1 = os.path.join(wd,'data',
|
|
25
24
|
'3368914_4_non_tumor')
|
|
26
25
|
imfolder2 = os.path.join(wd,'data',
|
|
27
26
|
'4173633_5')
|
|
28
27
|
|
|
29
|
-
model = resnet50()
|
|
28
|
+
#model = resnet50()
|
|
30
29
|
model = tf.keras.applications.resnet50.ResNet50(
|
|
31
30
|
include_top=True,
|
|
32
31
|
weights='imagenet',
|
|
@@ -42,13 +41,13 @@ def example_numpy(verbose=True):
|
|
|
42
41
|
dtype="numpy",verbose=False)
|
|
43
42
|
|
|
44
43
|
z = None
|
|
45
|
-
for epoch in range(
|
|
44
|
+
for epoch in range(1):
|
|
46
45
|
for image,y in dataloader_train:
|
|
47
46
|
if z is None:
|
|
48
47
|
z_dim = list(y.shape)
|
|
49
48
|
z_dim[1] = 1000 - z_dim[1]
|
|
50
49
|
z = np.zeros(z_dim)
|
|
51
|
-
y = np.concatenate(y,z,axis=1)
|
|
50
|
+
y = np.concatenate((y,z),axis=1)
|
|
52
51
|
model.fit(image,y)
|
|
53
52
|
|
|
54
53
|
# Test
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/python3
|
|
2
2
|
|
|
3
|
-
from cell_data_loader import CellDataloader
|
|
3
|
+
from src.cell_data_loader import CellDataloader
|
|
4
4
|
from torchvision.models import resnet50 #, ResNet50_Weights
|
|
5
5
|
import torch
|
|
6
6
|
import os
|
|
@@ -48,7 +48,7 @@ def example_torch(gpu_ids = None,verbose=True):
|
|
|
48
48
|
dtype="torch",
|
|
49
49
|
verbose=False, gpu_ids=gpu_ids)
|
|
50
50
|
if verbose: print("Beginning training")
|
|
51
|
-
n_epochs =
|
|
51
|
+
n_epochs = 1
|
|
52
52
|
for epoch in range(n_epochs):
|
|
53
53
|
l = 0
|
|
54
54
|
c = 0
|
|
@@ -12,6 +12,7 @@ from scipy.ndimage.interpolation import map_coordinates
|
|
|
12
12
|
from scipy.ndimage.filters import gaussian_filter
|
|
13
13
|
from .base_dataset import BaseDataset
|
|
14
14
|
import torch,torchvision
|
|
15
|
+
torchvision.disable_beta_transforms_warning()
|
|
15
16
|
from .util import *
|
|
16
17
|
import warnings
|
|
17
18
|
|
|
@@ -204,7 +205,8 @@ class CellDataloader():#BaseDataset):
|
|
|
204
205
|
cell_box_filelist = None,
|
|
205
206
|
n_channels = None,
|
|
206
207
|
channels_first = True,
|
|
207
|
-
match_labels=False
|
|
208
|
+
match_labels=False,
|
|
209
|
+
normalize=True):
|
|
208
210
|
|
|
209
211
|
self.verbose = verbose
|
|
210
212
|
self.label_balance = label_balance
|
|
@@ -221,19 +223,20 @@ class CellDataloader():#BaseDataset):
|
|
|
221
223
|
self.n_channels = n_channels
|
|
222
224
|
self.channels_first = channels_first
|
|
223
225
|
self.augment_image = augment_image
|
|
226
|
+
self.normalize = normalize
|
|
224
227
|
if self.augment_image and self.dtype == "torch":
|
|
225
|
-
|
|
228
|
+
import torchvision.transforms.v2 as transforms
|
|
226
229
|
|
|
227
230
|
self.augment = transforms.Compose([
|
|
228
|
-
#transforms.ElasticTransform(),
|
|
229
231
|
transforms.RandomHorizontalFlip(0.5),
|
|
230
232
|
transforms.RandomVerticalFlip(0.5),
|
|
231
233
|
transforms.GaussianBlur(5),
|
|
232
234
|
transforms.ColorJitter(brightness=(0.5,1.5),
|
|
233
235
|
contrast=(1), saturation=(0.5,1.5), hue=(-0.1,0.1)),
|
|
234
|
-
transforms.RandomResizedCrop(
|
|
236
|
+
transforms.RandomResizedCrop(self.dim, antialias=True)])#,
|
|
235
237
|
#transforms.Normalize((0.5,0.5,0.5),(0.5,0.5,0.5))])
|
|
236
|
-
|
|
238
|
+
self.augment2 = transforms.Compose([
|
|
239
|
+
transforms.ElasticTransform()])
|
|
237
240
|
"""
|
|
238
241
|
If true, outputs given labels equally. This may repeat images if the
|
|
239
242
|
counts of each don't line up.
|
|
@@ -304,12 +307,6 @@ class CellDataloader():#BaseDataset):
|
|
|
304
307
|
self.label_input_format = "Cell_Box_Regex"
|
|
305
308
|
elif self.cell_box_filelist is not None:
|
|
306
309
|
assert(len(all_filename_lists) == 1)
|
|
307
|
-
if self.image_folders is not None:
|
|
308
|
-
raise Exception(" To input cell boxes, files must be "+\
|
|
309
|
-
"input individually as a list and not as a folder, "+\
|
|
310
|
-
"to ensure one-to-one correspondence between the "+\
|
|
311
|
-
"box file and the image. Use the filelists parameter "+\
|
|
312
|
-
"instead of the image_folders parameter")
|
|
313
310
|
if isinstance(self.cell_box_filelist,str): # One image
|
|
314
311
|
self.cell_box_filelist = [[self.cell_box_filelist]]
|
|
315
312
|
elif isinstance(self.cell_box_filelist,list):
|
|
@@ -379,6 +376,11 @@ class CellDataloader():#BaseDataset):
|
|
|
379
376
|
self.n_channels = sample.get_n_channels()
|
|
380
377
|
else:
|
|
381
378
|
self.n_channels = n_channels
|
|
379
|
+
if self.normalize and self.dtype == "torch":
|
|
380
|
+
from torchvision.transforms.v2 import Normalize
|
|
381
|
+
self.normalizer = Normalize(
|
|
382
|
+
tuple([0.5 for _ in range(self.n_channels)]),
|
|
383
|
+
tuple([0.5 for _ in range(self.n_channels)]))
|
|
382
384
|
for image_object in self.image_objects:
|
|
383
385
|
image_object.n_channels = self.n_channels
|
|
384
386
|
if self.verbose:
|
|
@@ -471,8 +473,14 @@ class CellDataloader():#BaseDataset):
|
|
|
471
473
|
self.im_index = 0
|
|
472
474
|
self.index += 1
|
|
473
475
|
if self.index >= len(self.image_objects): break
|
|
474
|
-
if self.augment_image and self.dtype == "torch":
|
|
475
|
-
|
|
476
|
+
#if self.augment_image and self.dtype == "torch":
|
|
477
|
+
#imdim = im.size()
|
|
478
|
+
#print("imdim: %s" % str(imdim))
|
|
479
|
+
#im = torch.permute(im,[len(imdim)-1]+list(range(0,len(imdim)-1)))
|
|
480
|
+
#print("imdim: %s" % str(im.size()))
|
|
481
|
+
#im = self.augment(im)
|
|
482
|
+
#im = torch.permute(im,list(range(1,len(imdim))) + [0])
|
|
483
|
+
#print("imdim: %s"%str(im.size()))
|
|
476
484
|
if self.return_labels():
|
|
477
485
|
return im,label
|
|
478
486
|
else:
|
|
@@ -508,6 +516,22 @@ class CellDataloader():#BaseDataset):
|
|
|
508
516
|
b = torch.moveaxis(self.batch,-1,1)
|
|
509
517
|
else:
|
|
510
518
|
b = self.batch
|
|
519
|
+
if (self.augment_image and self.n_channels <= 3) or self.normalize:
|
|
520
|
+
if not self.channels_first:
|
|
521
|
+
b = torch.permute(b,[0,-1] + list(range(1,len(b.size())-1)))
|
|
522
|
+
#print("b.size(): %s" % str(b.size()))
|
|
523
|
+
if self.n_channels <= 3 and self.augment:
|
|
524
|
+
b = self.augment(b)
|
|
525
|
+
if self.dim[0] > 32 and self.dim[1] > 32:
|
|
526
|
+
b = self.augment2(b)
|
|
527
|
+
#print("b.size(): %s" % str(b.size()))
|
|
528
|
+
#print([0]+list(range(2,len(b.size()))) + [1])
|
|
529
|
+
if self.normalize:
|
|
530
|
+
b = self.normalizer(b)
|
|
531
|
+
if not self.channels_first:
|
|
532
|
+
b = torch.permute(b,[0]+list(range(2,len(b.size()))) + [1])
|
|
533
|
+
#print("b.size(): %s" % str(b.size()))
|
|
534
|
+
#print("sss")
|
|
511
535
|
elif self.dtype == "numpy":
|
|
512
536
|
if len(im.shape) == 2 and self.n_channels == 1:
|
|
513
537
|
im = np.expand_dims(im,axis=2)
|
|
@@ -8,7 +8,7 @@ import numpy as np
|
|
|
8
8
|
import torch
|
|
9
9
|
|
|
10
10
|
wd = os.path.dirname(os.path.dirname(os.path.realpath(__file__)))
|
|
11
|
-
im_root = os.path.join(wd,'data')
|
|
11
|
+
im_root = os.path.join(os.path.dirname(wd),'data')
|
|
12
12
|
#imfile_svs = os.path.join(im_root,'10447627_1.svs')
|
|
13
13
|
imfolder1 = os.path.join(im_root,'4173633_5')
|
|
14
14
|
imfolder2 = os.path.join(im_root,'3368914_4_non_tumor')
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|