cell-data-loader 0.0.1__tar.gz → 0.0.3__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.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: cell_data_loader
3
- Version: 0.0.1
3
+ Version: 0.0.3
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>
@@ -10,6 +10,8 @@ Keywords: biomedical,cell,cell image,cellpose,csz,dataloader
10
10
  Requires-Python: >=3.8
11
11
  Requires-Dist: numpy
12
12
  Requires-Dist: opencv-python>=4.5.4
13
+ Requires-Dist: pillow
14
+ Requires-Dist: scikit-image
13
15
  Requires-Dist: scipy
14
16
  Requires-Dist: slideio==2.4.1
15
17
  Requires-Dist: torch
@@ -23,7 +25,7 @@ Cell Data Loader is a simple AI support tool in Python that can take in images o
23
25
 
24
26
  To install Cell Data Loader, simply type into a standard UNIX terminal
25
27
 
26
- pip install cell_data_loader
28
+ pip install cell-data-loader
27
29
 
28
30
  The simplest way to use Cell Data Loader is to instantiate a dataloader as such:
29
31
 
@@ -90,8 +92,10 @@ imfolder = '/path/to/folder'
90
92
  dataloader = CellDataloader(imfolder,
91
93
  dim = (64,64),
92
94
  batch_size = 32,
93
- dtype = "numpy",
94
- n_channels = 3, #This is detected in the first read image by default, if not provided; it re-samples all images to force this number of channels
95
+ dtype = "numpy", # Can also be "torch"
96
+ label_regex = None,
97
+ n_channels = 3, # This is detected in the first read image by default, if not provided; it re-samples all images to force this number of channels
98
+ match_labels = False, # Outputs proportional amounts of each label in the dataset
95
99
  )
96
100
  ~~~
97
101
 
@@ -101,13 +105,22 @@ Dependencies
101
105
 
102
106
  Strict dependencies:
103
107
 
104
- > scipy
105
- > numpy
106
- > pytorch
108
+ numpy
109
+ torch
110
+ torchvision
111
+ opencv-python>=4.5.4
112
+ slideio==2.4.1
113
+ scipy
114
+ scikit-image
115
+ pillow
107
116
 
108
117
  Soft dependencies:
109
- > CellPose # For cell segmentation support
110
- > slideio # For reading .SVS and .CZI files
111
118
 
119
+ CellPose # For cell segmentation support
120
+ Tensorflow
112
121
 
113
- Note that some of the dependencies are not strict and vary depending on usage. Numpy and
122
+ Note that some of the dependencies are not strict and vary depending on usage. Numpy is a hard requirement, but Tensorflow is not if the user only uses the Torch capabilities. If the user attempts to load cell images in "cell" mode without a working Cellpose installation, CellDataLoader will throw an error. Cellpose needs be be installed separately to use "cell" mode:
123
+
124
+ pip install cellpose
125
+
126
+ And GPU integration is a separate matter.
@@ -5,7 +5,7 @@ Cell Data Loader is a simple AI support tool in Python that can take in images o
5
5
 
6
6
  To install Cell Data Loader, simply type into a standard UNIX terminal
7
7
 
8
- pip install cell_data_loader
8
+ pip install cell-data-loader
9
9
 
10
10
  The simplest way to use Cell Data Loader is to instantiate a dataloader as such:
11
11
 
@@ -72,8 +72,10 @@ imfolder = '/path/to/folder'
72
72
  dataloader = CellDataloader(imfolder,
73
73
  dim = (64,64),
74
74
  batch_size = 32,
75
- dtype = "numpy",
76
- n_channels = 3, #This is detected in the first read image by default, if not provided; it re-samples all images to force this number of channels
75
+ dtype = "numpy", # Can also be "torch"
76
+ label_regex = None,
77
+ n_channels = 3, # This is detected in the first read image by default, if not provided; it re-samples all images to force this number of channels
78
+ match_labels = False, # Outputs proportional amounts of each label in the dataset
77
79
  )
78
80
  ~~~
79
81
 
@@ -83,13 +85,22 @@ Dependencies
83
85
 
84
86
  Strict dependencies:
85
87
 
86
- > scipy
87
- > numpy
88
- > pytorch
88
+ numpy
89
+ torch
90
+ torchvision
91
+ opencv-python>=4.5.4
92
+ slideio==2.4.1
93
+ scipy
94
+ scikit-image
95
+ pillow
89
96
 
90
97
  Soft dependencies:
91
- > CellPose # For cell segmentation support
92
- > slideio # For reading .SVS and .CZI files
93
98
 
99
+ CellPose # For cell segmentation support
100
+ Tensorflow
94
101
 
95
- Note that some of the dependencies are not strict and vary depending on usage. Numpy and
102
+ Note that some of the dependencies are not strict and vary depending on usage. Numpy is a hard requirement, but Tensorflow is not if the user only uses the Torch capabilities. If the user attempts to load cell images in "cell" mode without a working Cellpose installation, CellDataLoader will throw an error. Cellpose needs be be installed separately to use "cell" mode:
103
+
104
+ pip install cellpose
105
+
106
+ And GPU integration is a separate matter.
@@ -1,16 +1,23 @@
1
1
  #!/usr/bin/python3
2
2
 
3
- from src.cell_loader_MLEMING import CellDataloader
3
+ from src.cell_data_loader import CellDataloader
4
4
  from keras import tensorflow as tf
5
5
  import numpy
6
6
  import os
7
7
 
8
8
  def example_numpy():
9
+
10
+ """
11
+ Replace whese with folders locally on your computer -- script will not work
12
+ without new folders.
13
+ """
9
14
  wd = os.path.dirname(os.path.realpath(__file__))
10
- imfolder_test = os.path.join(wd,'data','3368914_4_non_tumor')
11
- imfolder_train = os.path.join(wd,'data','4173633_5')
12
- model = resnet50()
15
+ imfolder_test = os.path.join(os.path.dirname(wd),'cell_data_loader_data',
16
+ '3368914_4_non_tumor')
17
+ imfolder_train = os.path.join(os.path.dirname(wd),'cell_data_loader_data',
18
+ '4173633_5')
13
19
 
20
+ model = resnet50()
14
21
  model = tf.keras.applications.resnet50.ResNet50(
15
22
  include_top=True,
16
23
  weights='imagenet',
@@ -36,7 +43,6 @@ def example_numpy():
36
43
  # Test
37
44
 
38
45
  model.eval()
39
-
40
46
  dataloader_test = CellDataloader(imfolder_test,imfolder_train,dtype="torch",
41
47
  verbose=False)
42
48
  total_images = 0
@@ -1,14 +1,21 @@
1
1
  #!/usr/bin/python3
2
2
 
3
- from src.cell_loader_MLEMING import CellDataloader
3
+ from src.cell_data_loader import CellDataloader
4
4
  from torchvision.models import resnet50
5
5
  import torch
6
6
  import os
7
7
 
8
8
  def example_torch():
9
+
10
+ """
11
+ Replace whese with folders locally on your computer -- script will not work
12
+ without new folders.
13
+ """
9
14
  wd = os.path.dirname(os.path.realpath(__file__))
10
- imfolder_test = os.path.join(wd,'data','3368914_4_non_tumor')
11
- imfolder_train = os.path.join(wd,'data','4173633_5')
15
+ imfolder_test = os.path.join(os.path.dirname(wd),'cell_data_loader_data',
16
+ '3368914_4_non_tumor')
17
+ imfolder_train = os.path.join(os.path.dirname(wd),'cell_data_loader_data',
18
+ '4173633_5')
12
19
  model = resnet50()
13
20
 
14
21
  # Train
@@ -2,6 +2,7 @@
2
2
 
3
3
  #git init
4
4
  git add README.md example_numpy.py example_torch.py src tests requirements.txt
5
+ git rm src/cell_data_loader/slice_images_out.py src/cell_data_loader/cell_segmenter.py
5
6
  git commit -m "First commit"
6
7
  git branch -M main
7
8
  git remote add origin https://github.com/mleming/CellDataLoader.git
@@ -0,0 +1,5 @@
1
+ #!/bin/bash
2
+
3
+ rm -r dist
4
+ python3 -m build --sdist
5
+ twine upload dist/*
@@ -2,7 +2,7 @@
2
2
 
3
3
  name = "cell_data_loader"
4
4
 
5
- version = "0.0.1"
5
+ version = "0.0.3"
6
6
 
7
7
  dependencies = [
8
8
  "numpy",
@@ -10,9 +10,11 @@ dependencies = [
10
10
  "torch",
11
11
  "torchvision",
12
12
  "opencv-python>=4.5.4",
13
- "slideio==2.4.1"
13
+ "slideio==2.4.1",
14
+ "scikit-image",
15
+ "pillow"
14
16
  ]
15
- requires-python = ">= 3.8"
17
+ requires-python = ">=3.8"
16
18
 
17
19
  authors = [
18
20
  {name = "Matt Leming", email = "mleming@mgh.harvard.edu"}
@@ -4,3 +4,5 @@ torchvision
4
4
  opencv-python>=4.5.4
5
5
  slideio==2.4.1
6
6
  scipy
7
+ scikit-image
8
+ pillow
@@ -174,9 +174,9 @@ class ImageLabelObject(BaseDataset):
174
174
  return imslice
175
175
  elif self.mode == "cell":
176
176
  if len(self.get_cell_box_label()) == 0:
177
- print("len self: %d" % len(self))
177
+ #print("len self: %d" % len(self))
178
178
  return -1
179
- raise Exception("No cells in this image — should not call")
179
+ #raise Exception("No cells in this image — should not call")
180
180
  #warnings.warn("No cells found in %s" % self.filename)
181
181
  #return -1
182
182
  index = index % len(self.get_cell_box_label())
@@ -283,10 +283,8 @@ class CellDataloader():#BaseDataset):
283
283
  try:
284
284
  from cellpose import models,io
285
285
  except:
286
- raise Exception("""
287
- Cellpose import failed -- need valid cellpose version to use
288
- cell segmentation option.
289
- """)
286
+ raise Exception("Cellpose import failed -- need valid "+\
287
+ "cellpose version to use cell segmentation option.")
290
288
  if self.cell_box_regex is not None:
291
289
  assert(len(all_filename_lists) == 1)
292
290
  self.cell_box_regex = re.compile(self.cell_box_regex)
@@ -294,13 +292,11 @@ class CellDataloader():#BaseDataset):
294
292
  elif self.cell_box_filelist is not None:
295
293
  assert(len(all_filename_lists) == 1)
296
294
  if self.image_folders is not None:
297
- raise Exception("""
298
- To input cell boxes, files must be input individually
299
- as a list and not as a folder, to ensure one-to-one
300
- correspondence between the box file and the image. Use
301
- the filelists parameter instead of the image_folders
302
- parameter
303
- """)
295
+ raise Exception(" To input cell boxes, files must be "+\
296
+ "input individually as a list and not as a folder, "+\
297
+ "to ensure one-to-one correspondence between the "+\
298
+ "box file and the image. Use the filelists parameter "+\
299
+ "instead of the image_folders parameter")
304
300
  if isinstance(self.cell_box_filelist,str): # One image
305
301
  self.cell_box_filelist = [[self.cell_box_filelist]]
306
302
  elif isinstance(self.cell_box_filelist,list):
@@ -312,9 +308,8 @@ class CellDataloader():#BaseDataset):
312
308
  assert(len(all_filenames_list[i]) == len(l))
313
309
  for filename in l:
314
310
  if not os.path.isfile(filename):
315
- raise Exception("""
316
- File doesn't exist: %s
317
- """ % filename)
311
+ raise Exception(
312
+ "File doesn't exist: %s" % filename)
318
313
  self.label_input_format = "Cell_Box_Filelist"
319
314
 
320
315
  """
@@ -364,7 +359,8 @@ class CellDataloader():#BaseDataset):
364
359
  if self.dtype == "numpy":
365
360
  self.label_batch = np.zeros((self.batch_size,self.n_labels))
366
361
  elif self.dtype == "torch":
367
- self.label_batch = torch.zeros(self.batch_size,self.n_labels)
362
+ self.label_batch = torch.zeros(self.batch_size,self.n_labels,
363
+ device = self.gpu_ids)
368
364
  sample = self.image_objects[0]
369
365
  if n_channels is None:
370
366
  self.n_channels = sample.get_n_channels()
@@ -420,9 +416,9 @@ class CellDataloader():#BaseDataset):
420
416
  for i,reg in enumerate(self.label_regex):
421
417
  if bool(reg.search(image_file)):
422
418
  if m > 0:
423
- warnings.warn("""
424
- Image file %s matches at least two regular expressions
425
- """ % image_file)
419
+ warnings.warn(
420
+ ("Image file %s matches at"+\
421
+ " least two regular expressions") % image_file)
426
422
  m = i + 1
427
423
  return m
428
424
  else:
@@ -507,20 +503,3 @@ class CellDataloader():#BaseDataset):
507
503
  return b,self.label_batch
508
504
  else:
509
505
  return b
510
-
511
- if __name__ == "__main__":
512
- wd = os.path.dirname(os.path.dirname(os.path.realpath(__file__)))
513
- imfolder = '/home/mleming/Dropbox (Partners HealthCare)/9. DROSE'
514
- dataset = CellDataloader(
515
- [
516
- os.path.join(imfolder,'raw_Test'),
517
- os.path.join(imfolder,'raw_Train, Val')
518
- ],
519
- segment_image = "whole")
520
- #dataset = CellDataloader(imfolder,label_regex=["Test","Train"])
521
-
522
- for i,(x,y) in enumerate(dataset):
523
- print(sys.getsizeof(x))
524
- #print(i.label)
525
- #print(i.filename)
526
-
@@ -1,9 +1,7 @@
1
1
  #!/usr/bin/python
2
2
 
3
3
  import os,sys,json,csv,cv2,glob,random,re
4
- import xml.etree.ElementTree as ET
5
4
  import numpy as np
6
- import pickle
7
5
  from numpy.random import choice,shuffle
8
6
  from math import floor,ceil,sqrt
9
7
  from PIL import Image,ImageEnhance
@@ -18,28 +16,11 @@ import warnings
18
16
  try:
19
17
  from cellpose import models, io
20
18
  except:
21
- warnings.warn("""
22
- Working Cellpose not installed -- cell segmentation not possible
23
- """)
24
- #from deepcell.applications import CytoplasmSegmentation
25
- #import numpy as np
26
- #from PIL import Image
27
- #from shutil import copyfile
28
- #from model import *
29
- #from scipy import ndimage
30
- import skimage
31
- #import itertools
32
- #import torch
33
- #import skimage.measure
34
- #from torchvision import transforms
19
+ warnings.warn("Working Cellpose not installed -- cell segmentation not"+\
20
+ " possible")
35
21
 
22
+ import skimage
36
23
  # DEFINE CELLPOSE MODEL
37
- # model_type='cyto' or model_type='nuclei'
38
- imagename = '/home/mleming/Desktop/Malaria_Cell_Project/data/AI_DATA_SET_UNZIPPED/TE201016063147_Mal_Cls2_201019/0258_21100_54800_005_23368.jpg'
39
- #imagename = '/home/mleming/Desktop/Malaria_Cell_Project/data/new_update_011421_UNZIPPED/TE201231032353/0533.jpg'
40
- #imagename = '/home/mleming/Desktop/Malaria_Cell_Project/data/new_update_011421_UNZIPPED/M2009090043/0833.jpg'
41
- imagename = '/home/mleming/Desktop/Malaria_Cell_Project/data/AI_DATA_SET_UNZIPPED/M2009091344/0583.jpg'
42
- imagename = '/home/mleming/Desktop/Malaria_Cell_Project/data/AI_DATA_SET_UNZIPPED/TE201231032353/0509.jpg'
43
24
 
44
25
  @contextmanager
45
26
  def suppress_stdout():
@@ -178,7 +159,8 @@ def slice_and_augment(im,x,y,l,w,
178
159
  #new_image = PIL.ImageEnhance.Contrast(image).enhance(1.2)
179
160
  if out_size is not None:
180
161
  if dtype == "torch":
181
- imslice = torch.permute(torchvision.transforms.Resize(out_size)(torch.permute(imslice,(2,0,1))),(1,2,0))
162
+ imslice = torch.permute(torchvision.transforms.Resize(
163
+ out_size)(torch.permute(imslice,(2,0,1))),(1,2,0))
182
164
  elif dtype == "numpy":
183
165
  imslice = cv2.resize(imslice,out_size[::-1])
184
166
  return imslice
@@ -338,8 +320,8 @@ def remove_unsmooth(mask,thresh=25):
338
320
  elif len(mask.shape) == 3:
339
321
  for z in range(mask.shape[2]):
340
322
  smoothnesses[z] = get_smoothness(crop2(np.squeeze(mask[:,:,z])))
341
- max_smoothness = smoothnesses.max()#max([smoothnesses[s] for s in smoothnesses])
342
- min_smoothness = smoothnesses.min()#min([smoothnesses[s] for s in smoothnesses])
323
+ max_smoothness = smoothnesses.max()
324
+ min_smoothness = smoothnesses.min()
343
325
  for i in range(mask.max()):
344
326
  if smoothnesses[i] > thresh:
345
327
  mask[mask == i+1] = 0
@@ -7,13 +7,12 @@ import os,sys,time
7
7
  import numpy as np
8
8
  import torch
9
9
 
10
- wd = os.path.dirname(os.path.dirname(os.path.dirname(os.path.realpath(__file__))))
11
- im_root = os.path.join(wd,'cell_data_loader_data')
10
+ wd = os.path.dirname(os.path.dirname(os.path.realpath(__file__)))
11
+ im_root = os.path.join(os.path.dirname(wd),'cell_data_loader_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')
15
15
  imfolder3 = os.path.join(im_root,'H6-13_Mars1+dapi')
16
-
17
16
  sys.path.insert(0,os.path.join(wd))
18
17
  from src.cell_data_loader import *
19
18
 
@@ -152,6 +151,29 @@ class TestSimple(unittest.TestCase):
152
151
  counts[int(np.argmax(y))] += 1
153
152
  self.assertEqual(counts[0],counts[1])
154
153
  self.assertEqual(counts[1],counts[2])
154
+ def test_gpu(self):
155
+ batch_size = 5
156
+ dim = (6,7)
157
+ for dtype in ["torch","numpy"]:
158
+ if dtype == "torch":
159
+ if not torch.cuda.is_available():
160
+ print("No available GPU for torch -- skipping")
161
+ continue
162
+ device = torch.cuda.current_device()
163
+ elif dtype == "numpy":
164
+ continue
165
+ dataset = CellDataloader(imfolder1,imfolder2,imfolder3,dim=dim,
166
+ batch_size=batch_size,dtype=dtype,match_labels=True,
167
+ gpu_ids = device)
168
+ for x,y in dataset:
169
+ if dtype == "torch":
170
+ self.assertEquals(device,x.device.index)
171
+ self.assertEquals(device,y.device.index)
172
+ break
173
+ elif dtype == "numpy":
174
+ break
175
+ else:
176
+ break
155
177
 
156
178
  if __name__ == "__main__":
157
179
  unittest.main()