PyOPIA 2.5.4__tar.gz → 2.5.6__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.
- {pyopia-2.5.4 → pyopia-2.5.6}/PKG-INFO +1 -1
- pyopia-2.5.6/pyopia/__init__.py +1 -0
- {pyopia-2.5.4 → pyopia-2.5.6}/pyopia/io.py +2 -2
- {pyopia-2.5.4 → pyopia-2.5.6}/pyopia/simulator/silcam.py +85 -19
- pyopia-2.5.4/pyopia/__init__.py +0 -1
- {pyopia-2.5.4 → pyopia-2.5.6}/LICENSE +0 -0
- {pyopia-2.5.4 → pyopia-2.5.6}/README.md +0 -0
- {pyopia-2.5.4 → pyopia-2.5.6}/pyopia/background.py +0 -0
- {pyopia-2.5.4 → pyopia-2.5.6}/pyopia/classify.py +0 -0
- {pyopia-2.5.4 → pyopia-2.5.6}/pyopia/cli.py +0 -0
- {pyopia-2.5.4 → pyopia-2.5.6}/pyopia/exampledata.py +0 -0
- {pyopia-2.5.4 → pyopia-2.5.6}/pyopia/instrument/__init__.py +0 -0
- {pyopia-2.5.4 → pyopia-2.5.6}/pyopia/instrument/common.py +0 -0
- {pyopia-2.5.4 → pyopia-2.5.6}/pyopia/instrument/holo.py +0 -0
- {pyopia-2.5.4 → pyopia-2.5.6}/pyopia/instrument/silcam.py +0 -0
- {pyopia-2.5.4 → pyopia-2.5.6}/pyopia/instrument/uvp.py +0 -0
- {pyopia-2.5.4 → pyopia-2.5.6}/pyopia/pipeline.py +0 -0
- {pyopia-2.5.4 → pyopia-2.5.6}/pyopia/plotting.py +0 -0
- {pyopia-2.5.4 → pyopia-2.5.6}/pyopia/process.py +0 -0
- {pyopia-2.5.4 → pyopia-2.5.6}/pyopia/simulator/__init__.py +0 -0
- {pyopia-2.5.4 → pyopia-2.5.6}/pyopia/statistics.py +0 -0
- {pyopia-2.5.4 → pyopia-2.5.6}/pyopia/tests/__init__.py +0 -0
- {pyopia-2.5.4 → pyopia-2.5.6}/pyopia/tests/test_classify.py +0 -0
- {pyopia-2.5.4 → pyopia-2.5.6}/pyopia/tests/test_notebooks.py +0 -0
- {pyopia-2.5.4 → pyopia-2.5.6}/pyopia/tests/test_pipeline.py +0 -0
- {pyopia-2.5.4 → pyopia-2.5.6}/pyproject.toml +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = '2.5.6'
|
|
@@ -390,7 +390,7 @@ def load_toml(toml_file):
|
|
|
390
390
|
return settings
|
|
391
391
|
|
|
392
392
|
|
|
393
|
-
def StatsH5():
|
|
393
|
+
def StatsH5(**kwargs):
|
|
394
394
|
'''.. deprecated:: 2.4.8
|
|
395
395
|
:class:`pyopia.io.StatsH5` will be removed in version 3.0.0, it is replaced by
|
|
396
396
|
:class:`pyopia.io.StatsToDisc`.
|
|
@@ -430,4 +430,4 @@ def StatsH5():
|
|
|
430
430
|
append = true
|
|
431
431
|
'''
|
|
432
432
|
logger.warning('StatsH5 will be removed in version 3.0.0, it is replaced by pyopia.io.StatsToDisc')
|
|
433
|
-
return StatsToDisc()
|
|
433
|
+
return StatsToDisc(**kwargs)
|
|
@@ -2,10 +2,11 @@
|
|
|
2
2
|
Module containing tools for assessing statistical reliability of silcam size distributions
|
|
3
3
|
'''
|
|
4
4
|
import numpy as np
|
|
5
|
-
|
|
5
|
+
import skimage.draw
|
|
6
6
|
import matplotlib.pyplot as plt
|
|
7
7
|
import skimage.util
|
|
8
8
|
import pandas as pd
|
|
9
|
+
import os
|
|
9
10
|
|
|
10
11
|
import pyopia.statistics
|
|
11
12
|
import pyopia.plotting
|
|
@@ -161,8 +162,21 @@ class SilcamSimulator():
|
|
|
161
162
|
axis=0),
|
|
162
163
|
self.dias)
|
|
163
164
|
|
|
164
|
-
def synthesize(self):
|
|
165
|
-
'''Synthesize an image and
|
|
165
|
+
def synthesize(self, add_noise=False, noise_var=0.001, database_path='', database_image_ext='tiff'):
|
|
166
|
+
'''Synthesize an image and document the distributions of particles used as input
|
|
167
|
+
|
|
168
|
+
Parameters
|
|
169
|
+
----------
|
|
170
|
+
add_noise : bool, optional
|
|
171
|
+
Uses skimage.util.random_noise() to add gaussian noise with variance defined by `noise_var`, by default False
|
|
172
|
+
noise_var : float, optional
|
|
173
|
+
Passed to the var argument of skimage.util.random_noise(), by default 0.001
|
|
174
|
+
database_path : str, optional
|
|
175
|
+
Path to a folder of particle ROI images to be randomly selected from to build the synthetic image.
|
|
176
|
+
If this is an empty string (default), then black discs will be used instead of real images., by default ''
|
|
177
|
+
database_image_ext : str, optional
|
|
178
|
+
Image file extension to look for within the folder specified by `database_path`
|
|
179
|
+
(must be a type that is loadable by skimage.io.imread() e.g. png of tiff), by default 'tiff'
|
|
166
180
|
|
|
167
181
|
Parameters
|
|
168
182
|
----------
|
|
@@ -171,36 +185,52 @@ class SilcamSimulator():
|
|
|
171
185
|
data['synthetic_image_data']['input_volume_distribution'] : array
|
|
172
186
|
Volume distribution used to create the synthetic image
|
|
173
187
|
'''
|
|
174
|
-
|
|
188
|
+
|
|
189
|
+
number_concentration = int(sum(self.data['number_distribution'])) # number concentration
|
|
175
190
|
|
|
176
191
|
# preallocate the image and logged volume distribution variables
|
|
177
192
|
img = np.zeros((self.imx, self.imy, 3), dtype=np.uint8()) + 230 # scale the initial brightness down a bit
|
|
178
|
-
log_ecd = np.zeros(
|
|
193
|
+
log_ecd = np.zeros(number_concentration)
|
|
179
194
|
# randomly select a droplet radii from the input distribution
|
|
180
195
|
# radius is in pixels
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
log_ecd =
|
|
185
|
-
for rad_ in rad:
|
|
186
|
-
# randomly decide where to put particles within the image
|
|
187
|
-
col = np.random.randint(1, high=self.imx - rad_)
|
|
188
|
-
row = np.random.randint(1, high=self.imy - rad_)
|
|
196
|
+
radii = np.random.choice(self.dias / 2,
|
|
197
|
+
size=number_concentration,
|
|
198
|
+
p=self.data['number_distribution'] / sum(self.data['number_distribution'])) / self.PIX_SIZE
|
|
199
|
+
log_ecd = radii * 2 * self.PIX_SIZE # log these sizes as a diameter in um
|
|
189
200
|
|
|
190
|
-
|
|
191
|
-
|
|
201
|
+
if database_path != '':
|
|
202
|
+
from pyopia.pipeline import FilesToProcess
|
|
203
|
+
file_list = FilesToProcess(os.path.join(database_path, '*.' + database_image_ext)).files
|
|
204
|
+
|
|
205
|
+
self.example_images = []
|
|
206
|
+
for radius in radii:
|
|
207
|
+
# randomly decide where to put particles within the image
|
|
208
|
+
row = np.random.randint(low=radius * 2, high=self.imx - (radius * 2))
|
|
209
|
+
col = np.random.randint(low=radius * 2, high=self.imy - (radius * 2))
|
|
210
|
+
|
|
211
|
+
if database_path != '':
|
|
212
|
+
example_image = extract_and_scale_example_image(radius, file_list)
|
|
213
|
+
img[row:row + example_image.shape[0],
|
|
214
|
+
col:col + example_image.shape[1],
|
|
215
|
+
:] = example_image
|
|
216
|
+
if np.min(np.shape(example_image[:, :, 0])) > 5:
|
|
217
|
+
self.example_images.append(example_image)
|
|
218
|
+
else:
|
|
219
|
+
rr, cc = skimage.draw.disk((row, col), radius) # make a cirle of the radius selected from the distribution
|
|
220
|
+
img[rr, cc, :] = 0
|
|
192
221
|
|
|
193
222
|
necd, edges = np.histogram(log_ecd, self.bin_limits) # count the input diameters into a number distribution
|
|
194
223
|
# convert to a volume distribution
|
|
195
|
-
|
|
224
|
+
temporal_volume_distribution = pyopia.statistics.vd_from_nd(necd, self.dias, sample_volume=self.sample_volume)
|
|
196
225
|
|
|
197
|
-
|
|
198
|
-
|
|
226
|
+
if add_noise:
|
|
227
|
+
# add some noise to the synthesized image
|
|
228
|
+
img = np.uint8(255 * skimage.util.random_noise(np.float64(img) / 255, mode='gaussian', var=noise_var))
|
|
199
229
|
|
|
200
230
|
img = np.uint8(img) # convert to uint8
|
|
201
231
|
self.data['synthetic_image_data'] = dict()
|
|
202
232
|
self.data['synthetic_image_data']['image'] = img
|
|
203
|
-
self.data['synthetic_image_data']['input_volume_distribution'] =
|
|
233
|
+
self.data['synthetic_image_data']['input_volume_distribution'] = temporal_volume_distribution
|
|
204
234
|
|
|
205
235
|
def process_synthetic_image(self):
|
|
206
236
|
'''Put the synthetic image `data['synthetic_image_data']['image']` through a basic pyopia processing pipeline
|
|
@@ -278,3 +308,39 @@ class SilcamSimulator():
|
|
|
278
308
|
plt.legend()
|
|
279
309
|
|
|
280
310
|
plt.tight_layout()
|
|
311
|
+
|
|
312
|
+
|
|
313
|
+
def extract_and_scale_example_image(output_length, file_list):
|
|
314
|
+
'''Randomly select a file from the input file_list list,
|
|
315
|
+
load this and then scale it (maintaining aspect ratio) to match the longest x-y dimention
|
|
316
|
+
to rad_ number of pixel
|
|
317
|
+
|
|
318
|
+
Parameters
|
|
319
|
+
----------
|
|
320
|
+
output_length : float
|
|
321
|
+
wanted longest dimention
|
|
322
|
+
file_list : list
|
|
323
|
+
list of filenames to chose from (to be read with skimage.io.imread)
|
|
324
|
+
|
|
325
|
+
Returns
|
|
326
|
+
-------
|
|
327
|
+
example_image : array
|
|
328
|
+
resized image
|
|
329
|
+
'''
|
|
330
|
+
filename = np.random.choice(file_list, size=1)[0]
|
|
331
|
+
raw_image = skimage.io.imread(filename).astype(float)
|
|
332
|
+
|
|
333
|
+
longest_axis = np.max(raw_image.shape[0:2])
|
|
334
|
+
|
|
335
|
+
scale_factor = output_length * 2 / longest_axis
|
|
336
|
+
|
|
337
|
+
size_row = scale_factor * np.float64(raw_image.shape[0])
|
|
338
|
+
size_col = scale_factor * np.float64(raw_image.shape[1])
|
|
339
|
+
|
|
340
|
+
example_image = skimage.transform.resize(raw_image,
|
|
341
|
+
(size_row, size_col),
|
|
342
|
+
anti_aliasing=True)
|
|
343
|
+
|
|
344
|
+
if np.min(np.shape(example_image)) > 0:
|
|
345
|
+
example_image += 255 - np.max(example_image)
|
|
346
|
+
return example_image
|
pyopia-2.5.4/pyopia/__init__.py
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
__version__ = '2.5.4'
|
|
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
|
|
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
|
|
File without changes
|