PyOPIA 2.16.4__tar.gz → 2.16.5__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.16.4 → pyopia-2.16.5}/PKG-INFO +1 -1
- pyopia-2.16.5/pyopia/__init__.py +1 -0
- {pyopia-2.16.4 → pyopia-2.16.5}/pyopia/process.py +91 -7
- pyopia-2.16.4/pyopia/__init__.py +0 -1
- {pyopia-2.16.4 → pyopia-2.16.5}/.gitignore +0 -0
- {pyopia-2.16.4 → pyopia-2.16.5}/LICENSE +0 -0
- {pyopia-2.16.4 → pyopia-2.16.5}/README.md +0 -0
- {pyopia-2.16.4 → pyopia-2.16.5}/pyopia/auxillarydata.py +0 -0
- {pyopia-2.16.4 → pyopia-2.16.5}/pyopia/background.py +0 -0
- {pyopia-2.16.4 → pyopia-2.16.5}/pyopia/cf_metadata.json +0 -0
- {pyopia-2.16.4 → pyopia-2.16.5}/pyopia/classify.py +0 -0
- {pyopia-2.16.4 → pyopia-2.16.5}/pyopia/classify_torch.py +0 -0
- {pyopia-2.16.4 → pyopia-2.16.5}/pyopia/cli.py +0 -0
- {pyopia-2.16.4 → pyopia-2.16.5}/pyopia/dataexport/__init__.py +0 -0
- {pyopia-2.16.4 → pyopia-2.16.5}/pyopia/dataexport/ecotaxa.py +0 -0
- {pyopia-2.16.4 → pyopia-2.16.5}/pyopia/exampledata.py +0 -0
- {pyopia-2.16.4 → pyopia-2.16.5}/pyopia/instrument/__init__.py +0 -0
- {pyopia-2.16.4 → pyopia-2.16.5}/pyopia/instrument/common.py +0 -0
- {pyopia-2.16.4 → pyopia-2.16.5}/pyopia/instrument/holo.py +0 -0
- {pyopia-2.16.4 → pyopia-2.16.5}/pyopia/instrument/silcam.py +0 -0
- {pyopia-2.16.4 → pyopia-2.16.5}/pyopia/instrument/uvp.py +0 -0
- {pyopia-2.16.4 → pyopia-2.16.5}/pyopia/io.py +0 -0
- {pyopia-2.16.4 → pyopia-2.16.5}/pyopia/metadata.py +0 -0
- {pyopia-2.16.4 → pyopia-2.16.5}/pyopia/pipeline.py +0 -0
- {pyopia-2.16.4 → pyopia-2.16.5}/pyopia/plotting.py +0 -0
- {pyopia-2.16.4 → pyopia-2.16.5}/pyopia/realtime.py +0 -0
- {pyopia-2.16.4 → pyopia-2.16.5}/pyopia/simulator/__init__.py +0 -0
- {pyopia-2.16.4 → pyopia-2.16.5}/pyopia/simulator/silcam.py +0 -0
- {pyopia-2.16.4 → pyopia-2.16.5}/pyopia/statistics.py +0 -0
- {pyopia-2.16.4 → pyopia-2.16.5}/pyopia/tests/__init__.py +0 -0
- {pyopia-2.16.4 → pyopia-2.16.5}/pyopia/tests/test_auxillarydata.py +0 -0
- {pyopia-2.16.4 → pyopia-2.16.5}/pyopia/tests/test_classify.py +0 -0
- {pyopia-2.16.4 → pyopia-2.16.5}/pyopia/tests/test_io.py +0 -0
- {pyopia-2.16.4 → pyopia-2.16.5}/pyopia/tests/test_notebooks.py +0 -0
- {pyopia-2.16.4 → pyopia-2.16.5}/pyopia/tests/test_pipeline.py +0 -0
- {pyopia-2.16.4 → pyopia-2.16.5}/pyopia/tests/test_process.py +0 -0
- {pyopia-2.16.4 → pyopia-2.16.5}/pyopia/tests/test_realtime.py +0 -0
- {pyopia-2.16.4 → pyopia-2.16.5}/pyproject.toml +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = "2.16.5"
|
|
@@ -204,6 +204,59 @@ def extract_roi(input_image, bbox):
|
|
|
204
204
|
return roi
|
|
205
205
|
|
|
206
206
|
|
|
207
|
+
def expand_bbox(bbox, image_shape, fraction):
|
|
208
|
+
'''Expand a bounding box by a fraction of its width and height, clamped to image bounds.
|
|
209
|
+
|
|
210
|
+
The expansion is split evenly on each side, so a fraction of 0.10 grows the
|
|
211
|
+
bounding box by 5% on each side (total +10% width, +10% height). Coordinates
|
|
212
|
+
are clamped to remain inside the image. Useful for adding visual context
|
|
213
|
+
around exported particle ROIs without altering the underlying regionprops
|
|
214
|
+
measurements.
|
|
215
|
+
|
|
216
|
+
Parameters
|
|
217
|
+
----------
|
|
218
|
+
bbox : array-like of int
|
|
219
|
+
[min_row, min_col, max_row, max_col], following the skimage regionprops
|
|
220
|
+
convention where ``max_row`` and ``max_col`` are exclusive.
|
|
221
|
+
image_shape : tuple
|
|
222
|
+
Shape of the full image. Only the first two elements (H, W) are used,
|
|
223
|
+
so passing ``imc.shape`` works for both 2-D and 3-D images.
|
|
224
|
+
fraction : float
|
|
225
|
+
Total fractional expansion of width and height. ``0.1`` = +10%.
|
|
226
|
+
``0`` (or ``None``) returns the bbox unchanged. Must be non-negative.
|
|
227
|
+
|
|
228
|
+
Returns
|
|
229
|
+
-------
|
|
230
|
+
expanded : ndarray of int, shape (4,)
|
|
231
|
+
Expanded and clamped bounding box, integer-valued.
|
|
232
|
+
|
|
233
|
+
Raises
|
|
234
|
+
------
|
|
235
|
+
ValueError
|
|
236
|
+
If ``fraction`` is negative.
|
|
237
|
+
'''
|
|
238
|
+
bbox_int = np.asarray(bbox, dtype=int)
|
|
239
|
+
if fraction is None or fraction == 0:
|
|
240
|
+
return bbox_int
|
|
241
|
+
if fraction < 0:
|
|
242
|
+
raise ValueError(f'bbox_expansion must be non-negative, got {fraction}')
|
|
243
|
+
|
|
244
|
+
r1, c1, r2, c2 = bbox_int
|
|
245
|
+
H, W = image_shape[0], image_shape[1]
|
|
246
|
+
|
|
247
|
+
h = r2 - r1
|
|
248
|
+
w = c2 - c1
|
|
249
|
+
pad_r = int(round(h * fraction / 2.0))
|
|
250
|
+
pad_c = int(round(w * fraction / 2.0))
|
|
251
|
+
|
|
252
|
+
return np.array([
|
|
253
|
+
max(0, r1 - pad_r),
|
|
254
|
+
max(0, c1 - pad_c),
|
|
255
|
+
min(H, r2 + pad_r),
|
|
256
|
+
min(W, c2 + pad_c),
|
|
257
|
+
], dtype=int)
|
|
258
|
+
|
|
259
|
+
|
|
207
260
|
def put_roi_in_h5(export_outputpath, HDF5File, roi, filename, i):
|
|
208
261
|
'''Adds rois to an open hdf file if export_outputpath is not None.
|
|
209
262
|
For use within {func}`pyopia.process.export_particles`
|
|
@@ -232,7 +285,8 @@ def put_roi_in_h5(export_outputpath, HDF5File, roi, filename, i):
|
|
|
232
285
|
|
|
233
286
|
def extract_particles(imc, timestamp, Classification, region_properties,
|
|
234
287
|
export_outputpath=None, min_length=0, propnames=['major_axis_length', 'minor_axis_length',
|
|
235
|
-
'equivalent_diameter']
|
|
288
|
+
'equivalent_diameter'],
|
|
289
|
+
bbox_expansion=0.0):
|
|
236
290
|
'''Extracts the particles to build stats and export particle rois to HDF5 files
|
|
237
291
|
|
|
238
292
|
Parameters
|
|
@@ -253,6 +307,13 @@ def extract_particles(imc, timestamp, Classification, region_properties,
|
|
|
253
307
|
Specifies list of skimage regionprops to export to the output file.
|
|
254
308
|
Must contain default values that can be appended to,
|
|
255
309
|
by default ['major_axis_length', 'minor_axis_length', 'equivalent_diameter']
|
|
310
|
+
bbox_expansion : float, optional
|
|
311
|
+
Fractional expansion of the bounding box used when cropping each ROI for
|
|
312
|
+
export. ``0.0`` (default) preserves prior behaviour. ``0.1`` grows the
|
|
313
|
+
crop by 10% in width and height (5% on each side), clamped to image
|
|
314
|
+
bounds. Only the exported ROI image is affected; the ``minr/minc/maxr/
|
|
315
|
+
maxc`` columns saved in stats continue to report the un-expanded
|
|
316
|
+
regionprops bbox so that measurements are unchanged.
|
|
256
317
|
|
|
257
318
|
Returns
|
|
258
319
|
-------
|
|
@@ -304,8 +365,10 @@ def extract_particles(imc, timestamp, Classification, region_properties,
|
|
|
304
365
|
if ((data[i, 0] > min_length) & (data[i, 1] > 2)):
|
|
305
366
|
|
|
306
367
|
nb_extractable_part += 1
|
|
307
|
-
# extract the region of interest from the corrected colour image
|
|
308
|
-
|
|
368
|
+
# extract the region of interest from the corrected colour image,
|
|
369
|
+
# optionally with the bbox expanded by `bbox_expansion` to add context
|
|
370
|
+
roi_bbox = expand_bbox(bboxes[i, :], imc.shape, bbox_expansion)
|
|
371
|
+
roi = extract_roi(imc, roi_bbox)
|
|
309
372
|
|
|
310
373
|
if Classification is not None:
|
|
311
374
|
# run a prediction on what type of particle this might be
|
|
@@ -426,7 +489,8 @@ def statextract(imbw, timestamp, imc,
|
|
|
426
489
|
max_particles=5000,
|
|
427
490
|
export_outputpath=None,
|
|
428
491
|
min_length=0,
|
|
429
|
-
propnames=['major_axis_length', 'minor_axis_length', 'equivalent_diameter']
|
|
492
|
+
propnames=['major_axis_length', 'minor_axis_length', 'equivalent_diameter'],
|
|
493
|
+
bbox_expansion=0.0):
|
|
430
494
|
'''Extracts statistics of particles in a binary images (imbw)
|
|
431
495
|
|
|
432
496
|
Parameters
|
|
@@ -452,6 +516,9 @@ def statextract(imbw, timestamp, imc,
|
|
|
452
516
|
Specifies list of skimage regionprops to export to the output file.
|
|
453
517
|
Must contain default values that can be appended to,
|
|
454
518
|
by default ['major_axis_length', 'minor_axis_length', 'equivalent_diameter']
|
|
519
|
+
bbox_expansion : float, optional
|
|
520
|
+
Fractional expansion of bounding boxes when cropping ROI images for export.
|
|
521
|
+
See :func:`extract_particles`. Defaults to 0.0 (no expansion).
|
|
455
522
|
|
|
456
523
|
Returns
|
|
457
524
|
-------
|
|
@@ -479,7 +546,8 @@ def statextract(imbw, timestamp, imc,
|
|
|
479
546
|
|
|
480
547
|
stats = extract_particles(imc, timestamp, Classification, region_properties,
|
|
481
548
|
export_outputpath=export_outputpath, min_length=min_length,
|
|
482
|
-
propnames=propnames
|
|
549
|
+
propnames=propnames,
|
|
550
|
+
bbox_expansion=bbox_expansion)
|
|
483
551
|
|
|
484
552
|
return stats, saturation
|
|
485
553
|
|
|
@@ -558,6 +626,19 @@ class CalculateStats():
|
|
|
558
626
|
roi_source: (str, optional)
|
|
559
627
|
Key of an image in Pipeline.data that is used for outputting ROIs and passing to the classifier.
|
|
560
628
|
Defaults to 'im_corrected'
|
|
629
|
+
bbox_expansion: (float, optional)
|
|
630
|
+
Fractional expansion applied to each particle bounding box before the
|
|
631
|
+
ROI is cropped and exported, e.g. ``0.1`` enlarges the crop by 10% in
|
|
632
|
+
width and height (5% on each side, clamped to image bounds). The
|
|
633
|
+
regionprops measurements and the ``minr/minc/maxr/maxc`` columns
|
|
634
|
+
written into stats are unaffected. Defaults to ``0.0`` (no expansion).
|
|
635
|
+
|
|
636
|
+
Configure from a TOML pipeline as::
|
|
637
|
+
|
|
638
|
+
[steps.statextract]
|
|
639
|
+
pipeline_class = "pyopia.process.CalculateStats"
|
|
640
|
+
export_outputpath = "/path/to/rois"
|
|
641
|
+
bbox_expansion = 0.1
|
|
561
642
|
|
|
562
643
|
Returns
|
|
563
644
|
-------
|
|
@@ -572,7 +653,8 @@ class CalculateStats():
|
|
|
572
653
|
export_outputpath=None,
|
|
573
654
|
min_length=0,
|
|
574
655
|
propnames=['major_axis_length', 'minor_axis_length', 'equivalent_diameter'],
|
|
575
|
-
roi_source='im_corrected'
|
|
656
|
+
roi_source='im_corrected',
|
|
657
|
+
bbox_expansion=0.0):
|
|
576
658
|
|
|
577
659
|
self.max_coverage = max_coverage
|
|
578
660
|
self.max_particles = max_particles
|
|
@@ -580,6 +662,7 @@ class CalculateStats():
|
|
|
580
662
|
self.min_length = min_length
|
|
581
663
|
self.propnames = propnames
|
|
582
664
|
self.roi_source = roi_source
|
|
665
|
+
self.bbox_expansion = bbox_expansion
|
|
583
666
|
|
|
584
667
|
self.calc_image_stats = CalculateImageStats()
|
|
585
668
|
|
|
@@ -591,7 +674,8 @@ class CalculateStats():
|
|
|
591
674
|
max_particles=self.max_particles,
|
|
592
675
|
export_outputpath=self.export_outputpath,
|
|
593
676
|
min_length=self.min_length,
|
|
594
|
-
propnames=self.propnames
|
|
677
|
+
propnames=self.propnames,
|
|
678
|
+
bbox_expansion=self.bbox_expansion)
|
|
595
679
|
stats['timestamp'] = data['timestamp']
|
|
596
680
|
stats['saturation'] = saturation
|
|
597
681
|
|
pyopia-2.16.4/pyopia/__init__.py
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
__version__ = "2.16.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
|
|
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
|