11import os
22import multiprocessing as mp
3- from typing import Dict , List , Optional , Tuple
3+ from typing import Dict , List , Optional , Tuple , Union
44
55import numpy as np
66
1818 skfmm = None
1919
2020
21- def compute_geodesic_distances (segmentation , distance_to , resolution = None , unsigned = True ):
21+ def compute_geodesic_distances (
22+ segmentation : np .ndarray ,
23+ distance_to : np .ndarray ,
24+ resolution : Optional [Union [int , float , Tuple [int , int , int ]]] = None ,
25+ unsigned : bool = True ,
26+ ) -> np .ndarray :
27+ """Compute the geodesic distances between a segmentation and a distance target.
28+
29+ This function require scikit-fmm to be installed.
30+
31+ Args:
32+ segmentation: The binary segmentation.
33+ distance_to: The binary distance target.
34+ resolution: The voxel size of the data, used to scale the distances.
35+ unsigned: Whether to return the unsigned or signed distances.
36+
37+ Returns:
38+ Array with the geodesic distance values.
39+ """
2240 assert skfmm is not None , "Please install scikit-fmm to use compute_geodesic_distance."
2341
2442 invalid = segmentation == 0
@@ -43,14 +61,12 @@ def compute_geodesic_distances(segmentation, distance_to, resolution=None, unsig
4361 return distances
4462
4563
46- # TODO update this
4764def _compute_centroid_distances (segmentation , resolution , n_neighbors ):
48- # TODO enable eccentricity centers instead
4965 props = regionprops (segmentation )
5066 centroids = np .array ([prop .centroid for prop in props ])
5167 if resolution is not None :
52- pass # TODO scale the centroids
53-
68+ scale_factor = np . array ( resolution )[:, None ]
69+ centroids *= scale_factor
5470 pair_distances = pairwise_distances (centroids )
5571 return pair_distances
5672
@@ -313,11 +329,13 @@ def create_pairwise_distance_lines(
313329 endpoints1: One set of distance end points.
314330 endpoints2: The other set of distance end points.
315331 seg_ids: The segmentation pair corresponding to each distance.
316- n_neighbors: ...
317- pairs: ...
318- bb: ....
319- scale: ...
320- remove_duplicates: ...
332+ n_neighbors: The number of nearest neighbors to take into consideration
333+ for creating the distance lines.
334+ pairs: Optional list of ids to use for creating the distance lines.
335+ bb: Bounding box for restricing the distance line creation.
336+ scale: Scale factor for resizing the distance lines.
337+ Use this if the corresponding segmentations were downscaled for visualization.
338+ remove_duplicates: Remove duplicate id pairs from the distance lines.
321339
322340 Returns:
323341 The lines for plotting in napari.
@@ -386,8 +404,10 @@ def create_object_distance_lines(
386404 endpoints1: One set of distance end points.
387405 endpoints2: The other set of distance end points.
388406 seg_ids: The segmentation ids corresponding to each distance.
389- max_distance: ...
390- scale: ...
407+ max_distance: Maximal distance for drawing the distance line.
408+ filter_seg_ids: Segmentation ids to restrict the distance lines.
409+ scale: Scale factor for resizing the distance lines.
410+ Use this if the corresponding segmentations were downscaled for visualization.
391411
392412 Returns:
393413 The lines for plotting in napari.
@@ -416,13 +436,32 @@ def create_object_distance_lines(
416436 return lines , properties
417437
418438
419- def keep_direct_distances (segmentation , measurement_path , line_dilation = 0 , scale = None ):
420- """Filter out all distances that are not direct.
421- I.e. distances that cross another segmented object.
422- """
439+ def keep_direct_distances (
440+ segmentation : np .ndarray ,
441+ distances : np .ndarray ,
442+ endpoints1 : np .ndarray ,
443+ endpoints2 : np .ndarray ,
444+ seg_ids : np .ndarray ,
445+ line_dilation : int = 0 ,
446+ scale : Optional [Tuple [int , int , int ]] = None ,
447+ ) -> List [List [int , int ]]:
448+ """Filter out all distances that are not direct; distances that are occluded by another segmented object.
423449
424- distances , ep1 , ep2 , seg_ids = load_distances (measurement_path )
425- distance_lines , properties = create_object_distance_lines (distances , ep1 , ep2 , seg_ids , scale = scale )
450+ Args:
451+ segmentation: The segmentation from which the distances are derived.
452+ distances: The measurd distances.
453+ endpoints1: One set of distance end points.
454+ endpoints2: The other set of distance end points.
455+ seg_ids: The segmentation ids corresponding to each distance.
456+ line_dilation: Dilation factor of the distance lines for determining occlusions.
457+ scale: Scaling factor of the segmentation compared to the distance measurements.
458+
459+ Returns:
460+ The list of id pairs that are kept.
461+ """
462+ distance_lines , properties = create_object_distance_lines (
463+ distances , endpoints1 , endpoints2 , seg_ids , scale = scale
464+ )
426465
427466 ids_a , ids_b = properties ["id_a" ], properties ["id_b" ]
428467 filtered_ids_a , filtered_ids_b = [], []
@@ -459,10 +498,35 @@ def keep_direct_distances(segmentation, measurement_path, line_dilation=0, scale
459498
460499
461500def filter_blocked_segmentation_to_object_distances (
462- segmentation , measurement_path , line_dilation = 0 , scale = None , seg_ids = None , verbose = False ,
463- ):
464- distances , ep1 , ep2 , seg_ids = load_distances (measurement_path )
465- distance_lines , properties = create_object_distance_lines (distances , ep1 , ep2 , seg_ids , scale = scale )
501+ segmentation : np .ndarray ,
502+ distances : np .ndarray ,
503+ endpoints1 : np .ndarray ,
504+ endpoints2 : np .ndarray ,
505+ seg_ids : np .ndarray ,
506+ line_dilation : int = 0 ,
507+ scale : Optional [Tuple [int , int , int ]] = None ,
508+ filter_seg_ids : Optional [List [int ]] = None ,
509+ verbose : bool = False ,
510+ ) -> List [int ]:
511+ """Filter out all distances that are not direct; distances that are occluded by another segmented object.
512+
513+ Args:
514+ segmentation: The segmentation from which the distances are derived.
515+ distances: The measurd distances.
516+ endpoints1: One set of distance end points.
517+ endpoints2: The other set of distance end points.
518+ seg_ids: The segmentation ids corresponding to each distance.
519+ line_dilation: Dilation factor of the distance lines for determining occlusions.
520+ scale: Scaling factor of the segmentation compared to the distance measurements.
521+ filter_seg_ids: Segmentation ids to restrict the distance lines.
522+ verbose: Whether to print progressbar.
523+
524+ Returns:
525+ The list of id pairs that are kept.
526+ """
527+ distance_lines , properties = create_object_distance_lines (
528+ distances , endpoints1 , endpoints2 , seg_ids , scale = scale
529+ )
466530 all_seg_ids = properties ["id" ]
467531
468532 filtered_ids = []
0 commit comments