U Ph-; @sddlmZddlmZddlmZddlZddlZddl m Z m Z m Z m Z ddlmZddlmZGd d d eZdd d dddddd dddZdS)) annotations)Sequence)AnyN)do_metric_reductionget_edge_surface_distanceignore_backgroundprepare_spacing)MetricReduction)CumulativeIterationMetricc sfeZdZdZddejddfdddddddd fd d Zd d d d dddZddddddZZ S)SurfaceDiceMetrica Computes the Normalized Surface Dice (NSD) for each batch sample and class of predicted segmentations `y_pred` and corresponding reference segmentations `y` according to equation :eq:`nsd`. This implementation is based on https://arxiv.org/abs/2111.05408 and supports 2D and 3D images. Be aware that by default (`use_subvoxels=False`), the computation of boundaries is different from DeepMind's implementation https://github.com/deepmind/surface-distance. In this implementation, the length/area of a segmentation boundary is interpreted as the number of its edge pixels. In DeepMind's implementation, the length of a segmentation boundary depends on the local neighborhood (cf. https://arxiv.org/abs/1809.04430). This issue is discussed here: https://github.com/Project-MONAI/MONAI/issues/4103. The class- and batch sample-wise NSD values can be aggregated with the function `aggregate`. Example of the typical execution steps of this metric class follows :py:class:`monai.metrics.metric.Cumulative`. Args: class_thresholds: List of class-specific thresholds. The thresholds relate to the acceptable amount of deviation in the segmentation boundary in pixels. Each threshold needs to be a finite, non-negative number. include_background: Whether to include NSD computation on the first channel of the predicted output. Defaults to ``False``. distance_metric: The metric used to compute surface distances. One of [``"euclidean"``, ``"chessboard"``, ``"taxicab"``]. Defaults to ``"euclidean"``. reduction: define mode of reduction to the metrics, will only apply reduction on `not-nan` values, available reduction modes: {``"none"``, ``"mean"``, ``"sum"``, ``"mean_batch"``, ``"sum_batch"``, ``"mean_channel"``, ``"sum_channel"``}, default to ``"mean"``. if "none", will not do reduction. get_not_nans: whether to return the `not_nans` count. Defaults to ``False``. `not_nans` is the number of batch samples for which not all class-specific NSD values were nan values. If set to ``True``, the function `aggregate` will return both the aggregated NSD and the `not_nans` count. If set to ``False``, `aggregate` will only return the aggregated NSD. use_subvoxels: Whether to use subvoxel distances. Defaults to ``False``. F euclidean list[float]boolstrzMetricReduction | strNone)class_thresholdsinclude_backgrounddistance_metric reduction get_not_nans use_subvoxelsreturncs2t||_||_||_||_||_||_dS)N)super__init__rrrrrr)selfrrrrrr __class__O/home/dell461/cl/sdc2/HISourceFinder-master-l/src/monai/metrics/surface_dice.pyr>s zSurfaceDiceMetric.__init__ torch.Tensorr)y_predykwargsrc Ks$t|||j|j|j|d|jdS)a Args: y_pred: Predicted segmentation, typically segmentation model output. It must be a one-hot encoded, batch-first tensor [B,C,H,W] or [B,C,H,W,D]. y: Reference segmentation. It must be a one-hot encoded, batch-first tensor [B,C,H,W] or [B,C,H,W,D]. kwargs: additional parameters: ``spacing`` should be passed to correctly compute the metric. ``spacing``: spacing of pixel (or voxel). This parameter is relevant only if ``distance_metric`` is set to ``"euclidean"``. If a single number, isotropic spacing with that value is used for all images in the batch. If a sequence of numbers, the length of the sequence must be equal to the image dimensions. This spacing will be used for all images in the batch. If a sequence of sequences, the length of the outer sequence must be equal to the batch size. If inner sequence has length 1, isotropic spacing with that value is used for all images in the batch, else the inner sequence length must be equal to the image dimensions. If ``None``, spacing of unity is used for all images in batch. Defaults to ``None``. use_subvoxels: Whether to use subvoxel distances. Defaults to ``False``. Returns: Pytorch Tensor of shape [B,C], containing the NSD values :math:`\operatorname {NSD}_{b,c}` for each batch index :math:`b` and class :math:`c`. spacing)r!r"rrrr$r)compute_surface_dicerrrgetr)rr!r"r#rrr_compute_tensorOsz!SurfaceDiceMetric._compute_tensorNzMetricReduction | str | Nonez0torch.Tensor | tuple[torch.Tensor, torch.Tensor])rrcCsB|}t|tjstdt||p(|j\}}|jr>||fS|S)a Aggregates the output of `_compute_tensor`. Args: reduction: define mode of reduction to the metrics, will only apply reduction on `not-nan` values, available reduction modes: {``"none"``, ``"mean"``, ``"sum"``, ``"mean_batch"``, ``"sum_batch"``, ``"mean_channel"``, ``"sum_channel"``}, default to `self.reduction`. if "none", will not do reduction. Returns: If `get_not_nans` is set to ``True``, this function returns the aggregated NSD and the `not_nans` count. If `get_not_nans` is set to ``False``, this function returns only the aggregated NSD. z-the data to aggregate must be PyTorch Tensor.) get_buffer isinstancetorchTensor ValueErrorrrr)rrdatafnot_nansrrr aggregateqs  zSurfaceDiceMetric.aggregate)N) __name__ __module__ __qualname____doc__r MEANrr'r0 __classcell__rrrrr s& #r Fr r rrrz\int | float | np.ndarray | Sequence[int | float | np.ndarray | Sequence[int | float]] | None)r!r"rrrr$rrc CsT|st||d\}}t|tjr,t|tjs4td|dksL|dkrTtd|j|jkrztd|jd|jd|jdd \}}|t|krtd |d t|d tt |rtd tt |dkrtdtj ||f|j tjd} |jd } t||| d} t ||D],\} } t|| | f|| | f|| | |d| d\\}}\}}}|st|t|}t||| kt||| k}n~|\}}||||}}||}t|dkr|||| knd}t|dkr|||| knd}||}|dkr= 0.)devicedtype)r$ batch_sizeimg_dimT)rr$r symmetric class_indexg)rr)r*r+r, ndimensionshapelenanynpisfinitearrayemptyr:floatndimrndindexrsumtensornan)r!r"rrrr$rr<n_classZnsdr= spacing_listbc edges_prededges_gtZdistances_pred_gtZdistances_gt_predareasZboundary_completeZboundary_correct areas_predareas_gtZgt_trueZ pred_truerrrr%s^P       && r%)Fr NF) __future__rcollections.abcrtypingrnumpyrDr*monai.metrics.utilsrrrr monai.utilsr metricr r r%rrrr s     s