1919from monai .config import NdarrayOrTensor
2020
2121
22- def compute_fp_tp_probs (
22+ def compute_fp_tp_probs_nd (
2323 probs : NdarrayOrTensor ,
24- y_coord : NdarrayOrTensor ,
25- x_coord : NdarrayOrTensor ,
24+ coords : NdarrayOrTensor ,
2625 evaluation_mask : NdarrayOrTensor ,
2726 labels_to_exclude : list | None = None ,
28- resolution_level : int = 0 ,
2927) -> tuple [NdarrayOrTensor , NdarrayOrTensor , int ]:
3028 """
3129 This function is modified from the official evaluation code of
@@ -36,29 +34,28 @@ def compute_fp_tp_probs(
3634 Args:
3735 probs: an array with shape (n,) that represents the probabilities of the detections.
3836 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` .
4139 evaluation_mask: the ground truth mask for evaluation.
4240 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.
4441
4542 Returns:
4643 fp_probs: an array that contains the probabilities of the false positive detections.
4744 tp_probs: an array that contains the probabilities of the True positive detections.
4845 num_targets: the total number of targets (excluding `labels_to_exclude`) for all images under evaluation.
4946
5047 """
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 )):
5251 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 } ."
5453 )
5554
5655 if isinstance (probs , torch .Tensor ):
5756 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 ()
6259 if isinstance (evaluation_mask , torch .Tensor ):
6360 evaluation_mask = evaluation_mask .detach ().cpu ().numpy ()
6461
@@ -68,10 +65,7 @@ def compute_fp_tp_probs(
6865 max_label = np .max (evaluation_mask )
6966 tp_probs = np .zeros ((max_label ,), dtype = np .float32 )
7067
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 )]
7569 fp_probs = probs [np .where (hittedlabel == 0 )]
7670 for i in range (1 , max_label + 1 ):
7771 if i not in labels_to_exclude and i in hittedlabel :
@@ -81,6 +75,50 @@ def compute_fp_tp_probs(
8175 return fp_probs , tp_probs , cast (int , num_targets )
8276
8377
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+
84122def compute_froc_curve_data (
85123 fp_probs : np .ndarray | torch .Tensor , tp_probs : np .ndarray | torch .Tensor , num_targets : int , num_images : int
86124) -> tuple [np .ndarray , np .ndarray ]:
0 commit comments