21
21
22
22
import hashlib
23
23
import numpy as np
24
- from typing import TYPE_CHECKING
24
+ from typing import TYPE_CHECKING , Union
25
25
if TYPE_CHECKING :
26
26
from ..core .structure import BrainStructure
27
27
from nibabel import Nifti1Image
28
+ from ..core .space import Space
28
29
29
30
30
31
class BoundingBox (location .Location ):
@@ -35,7 +36,14 @@ class BoundingBox(location.Location):
35
36
from the two corner points.
36
37
"""
37
38
38
- def __init__ (self , point1 , point2 , space = None , minsize : float = None , sigma_mm = None ):
39
+ def __init__ (
40
+ self ,
41
+ point1 ,
42
+ point2 ,
43
+ space : Union [str , 'Space' ] = None ,
44
+ minsize : float = None ,
45
+ sigma_mm = None
46
+ ):
39
47
"""
40
48
Construct a new bounding box spanned by two 3D coordinates
41
49
in the given reference space.
@@ -99,24 +107,6 @@ def shape(self) -> float:
99
107
def is_planar (self ) -> bool :
100
108
return any (d == 0 for d in self .shape )
101
109
102
- @staticmethod
103
- def _determine_bounds (A , threshold = 0 ):
104
- """
105
- Bounding box of nonzero values in a 3D array.
106
- https://stackoverflow.com/questions/31400769/bounding-box-of-numpy-array
107
- """
108
- x = np .any (A > threshold , axis = (1 , 2 ))
109
- y = np .any (A > threshold , axis = (0 , 2 ))
110
- z = np .any (A > threshold , axis = (0 , 1 ))
111
- nzx , nzy , nzz = [np .where (v ) for v in (x , y , z )]
112
- if any (len (nz [0 ]) == 0 for nz in [nzx , nzy , nzz ]):
113
- # empty array
114
- return None
115
- xmin , xmax = nzx [0 ][[0 , - 1 ]]
116
- ymin , ymax = nzy [0 ][[0 , - 1 ]]
117
- zmin , zmax = nzz [0 ][[0 , - 1 ]]
118
- return np .array ([[xmin , xmax + 1 ], [ymin , ymax + 1 ], [zmin , zmax + 1 ], [1 , 1 ]])
119
-
120
110
def __str__ (self ):
121
111
if self .space is None :
122
112
return (
@@ -390,3 +380,35 @@ def __eq__(self, other: 'BoundingBox'):
390
380
391
381
def __hash__ (self ):
392
382
return super ().__hash__ ()
383
+
384
+
385
+ def _determine_bounds (array : np .ndarray , threshold = 0 ):
386
+ """
387
+ Bounding box of nonzero values in a 3D array.
388
+ https://stackoverflow.com/questions/31400769/bounding-box-of-numpy-array
389
+ """
390
+ x = np .any (array > threshold , axis = (1 , 2 ))
391
+ y = np .any (array > threshold , axis = (0 , 2 ))
392
+ z = np .any (array > threshold , axis = (0 , 1 ))
393
+ nzx , nzy , nzz = [np .where (v ) for v in (x , y , z )]
394
+ if any (len (nz [0 ]) == 0 for nz in [nzx , nzy , nzz ]):
395
+ # empty array
396
+ return None
397
+ xmin , xmax = nzx [0 ][[0 , - 1 ]]
398
+ ymin , ymax = nzy [0 ][[0 , - 1 ]]
399
+ zmin , zmax = nzz [0 ][[0 , - 1 ]]
400
+ return np .array ([[xmin , xmax + 1 ], [ymin , ymax + 1 ], [zmin , zmax + 1 ], [1 , 1 ]])
401
+
402
+
403
+ def from_array (array : np .ndarray , threshold = 0 , space : "Space" = None ) -> "BoundingBox" :
404
+ """
405
+ Find the bounding box of an array.
406
+
407
+ Parameters
408
+ ----------
409
+ array : np.ndarray
410
+ threshold : int, default: 0
411
+ space : Space, default: None
412
+ """
413
+ bounds = _determine_bounds (array , threshold )
414
+ return BoundingBox (bounds [:3 , 0 ], bounds [:3 , 1 ], space = space )
0 commit comments