19
19
from monai .config import NdarrayOrTensor
20
20
21
21
22
- def compute_fp_tp_probs (
22
+ def compute_fp_tp_probs_nd (
23
23
probs : NdarrayOrTensor ,
24
- y_coord : NdarrayOrTensor ,
25
- x_coord : NdarrayOrTensor ,
24
+ coords : NdarrayOrTensor ,
26
25
evaluation_mask : NdarrayOrTensor ,
27
26
labels_to_exclude : list | None = None ,
28
- resolution_level : int = 0 ,
29
27
) -> tuple [NdarrayOrTensor , NdarrayOrTensor , int ]:
30
28
"""
31
29
This function is modified from the official evaluation code of
@@ -36,29 +34,28 @@ def compute_fp_tp_probs(
36
34
Args:
37
35
probs: an array with shape (n,) that represents the probabilities of the detections.
38
36
Where, n is the number of predicted detections.
39
- y_coord : an array with shape (n,) that represents the Y- coordinates of the detections.
40
- x_coord: an array with shape (n,) that represents the X-coordinates of the detections .
37
+ coords : an array with shape (n, n_dim ) that represents the coordinates of the detections.
38
+ The dimensions must be in the same order as in `evaluation_mask` .
41
39
evaluation_mask: the ground truth mask for evaluation.
42
40
labels_to_exclude: labels in this list will not be counted for metric calculation.
43
- resolution_level: the level at which the evaluation mask is made.
44
41
45
42
Returns:
46
43
fp_probs: an array that contains the probabilities of the false positive detections.
47
44
tp_probs: an array that contains the probabilities of the True positive detections.
48
45
num_targets: the total number of targets (excluding `labels_to_exclude`) for all images under evaluation.
49
46
50
47
"""
51
- if not (probs .shape == y_coord .shape == x_coord .shape ):
48
+ if not (len (probs ) == len (coords )):
49
+ raise ValueError (f"the length of probs { probs .shape } , should be the same as of coords { coords .shape } ." )
50
+ if not (len (coords .shape ) > 1 and coords .shape [1 ] == len (evaluation_mask .shape )):
52
51
raise ValueError (
53
- f"the shapes between probs { probs .shape } , y_coord { y_coord . shape } and x_coord { x_coord . shape } should be the same ."
52
+ f"coords { coords .shape } need to represent the same number of dimensions as mask { evaluation_mask . shape } ."
54
53
)
55
54
56
55
if isinstance (probs , torch .Tensor ):
57
56
probs = probs .detach ().cpu ().numpy ()
58
- if isinstance (y_coord , torch .Tensor ):
59
- y_coord = y_coord .detach ().cpu ().numpy ()
60
- if isinstance (x_coord , torch .Tensor ):
61
- x_coord = x_coord .detach ().cpu ().numpy ()
57
+ if isinstance (coords , torch .Tensor ):
58
+ coords = coords .detach ().cpu ().numpy ()
62
59
if isinstance (evaluation_mask , torch .Tensor ):
63
60
evaluation_mask = evaluation_mask .detach ().cpu ().numpy ()
64
61
@@ -68,10 +65,7 @@ def compute_fp_tp_probs(
68
65
max_label = np .max (evaluation_mask )
69
66
tp_probs = np .zeros ((max_label ,), dtype = np .float32 )
70
67
71
- y_coord = (y_coord / pow (2 , resolution_level )).astype (int )
72
- x_coord = (x_coord / pow (2 , resolution_level )).astype (int )
73
-
74
- hittedlabel = evaluation_mask [y_coord , x_coord ]
68
+ hittedlabel = evaluation_mask [tuple (coords .T )]
75
69
fp_probs = probs [np .where (hittedlabel == 0 )]
76
70
for i in range (1 , max_label + 1 ):
77
71
if i not in labels_to_exclude and i in hittedlabel :
@@ -81,6 +75,50 @@ def compute_fp_tp_probs(
81
75
return fp_probs , tp_probs , cast (int , num_targets )
82
76
83
77
78
+ def compute_fp_tp_probs (
79
+ probs : NdarrayOrTensor ,
80
+ y_coord : NdarrayOrTensor ,
81
+ x_coord : NdarrayOrTensor ,
82
+ evaluation_mask : NdarrayOrTensor ,
83
+ labels_to_exclude : list | None = None ,
84
+ resolution_level : int = 0 ,
85
+ ) -> tuple [NdarrayOrTensor , NdarrayOrTensor , int ]:
86
+ """
87
+ This function is modified from the official evaluation code of
88
+ `CAMELYON 16 Challenge <https://camelyon16.grand-challenge.org/>`_, and used to distinguish
89
+ true positive and false positive predictions. A true positive prediction is defined when
90
+ the detection point is within the annotated ground truth region.
91
+
92
+ Args:
93
+ probs: an array with shape (n,) that represents the probabilities of the detections.
94
+ Where, n is the number of predicted detections.
95
+ y_coord: an array with shape (n,) that represents the Y-coordinates of the detections.
96
+ x_coord: an array with shape (n,) that represents the X-coordinates of the detections.
97
+ evaluation_mask: the ground truth mask for evaluation.
98
+ labels_to_exclude: labels in this list will not be counted for metric calculation.
99
+ resolution_level: the level at which the evaluation mask is made.
100
+
101
+ Returns:
102
+ fp_probs: an array that contains the probabilities of the false positive detections.
103
+ tp_probs: an array that contains the probabilities of the True positive detections.
104
+ num_targets: the total number of targets (excluding `labels_to_exclude`) for all images under evaluation.
105
+
106
+ """
107
+ if isinstance (y_coord , torch .Tensor ):
108
+ y_coord = y_coord .detach ().cpu ().numpy ()
109
+ if isinstance (x_coord , torch .Tensor ):
110
+ x_coord = x_coord .detach ().cpu ().numpy ()
111
+
112
+ y_coord = (y_coord / pow (2 , resolution_level )).astype (int )
113
+ x_coord = (x_coord / pow (2 , resolution_level )).astype (int )
114
+
115
+ stacked = np .stack ([y_coord , x_coord ], axis = 1 )
116
+
117
+ return compute_fp_tp_probs_nd (
118
+ probs = probs , coords = stacked , evaluation_mask = evaluation_mask , labels_to_exclude = labels_to_exclude
119
+ )
120
+
121
+
84
122
def compute_froc_curve_data (
85
123
fp_probs : np .ndarray | torch .Tensor , tp_probs : np .ndarray | torch .Tensor , num_targets : int , num_images : int
86
124
) -> tuple [np .ndarray , np .ndarray ]:
0 commit comments