bioimage_py.evaluation.cremi_score
CREMI score: the geometric mean of the variation of information and the adapted rand error.
This was the evaluation metric of the CREMI challenge. It reuses a single contingency table to compute both the variation of information and the adapted rand error.
1"""CREMI score: the geometric mean of the variation of information and the adapted rand error. 2 3This was the evaluation metric of the CREMI challenge. It reuses a single contingency table to compute 4both the variation of information and the adapted rand error. 5""" 6from __future__ import annotations 7 8from typing import Optional, Sequence, Tuple 9 10import numpy as np 11 12from ..runner.config import RunnerConfig 13from ..sources import SourceLike 14from ._common import build_table 15from .contingency_table import ContingencyTable 16from .rand_index import rand_scores 17from .variation_of_information import vi_scores 18 19__all__ = ["cremi_scores", "cremi_score"] 20 21 22def cremi_scores(table: ContingencyTable, *, use_log2: bool = True) -> Tuple[float, float, float, float]: 23 """Compute the CREMI score and its components from a single contingency table. 24 25 Args: 26 table: A contingency table built as ``contingency_table(segmentation, groundtruth)``. 27 use_log2: Whether to use ``log2`` (bits) or natural ``log`` (nats) for the VI part. 28 29 Returns: 30 The split variation of information, the merge variation of information, the adapted rand error, 31 and the CREMI score (``sqrt(adapted_rand_error * (vi_split + vi_merge))``). 32 """ 33 vi_split, vi_merge = vi_scores(table, use_log2=use_log2) 34 adapted_rand_error, _ = rand_scores(table) 35 cremi = float(np.sqrt(adapted_rand_error * (vi_split + vi_merge))) 36 return vi_split, vi_merge, adapted_rand_error, cremi 37 38 39def cremi_score( 40 segmentation: SourceLike, 41 groundtruth: SourceLike, 42 *, 43 ignore_seg: Optional[Sequence[int]] = None, 44 ignore_gt: Optional[Sequence[int]] = None, 45 use_log2: bool = True, 46 num_workers: int = 1, 47 block_shape: Optional[Tuple[int, ...]] = None, 48 job_type: str = "local", 49 job_config: Optional[RunnerConfig] = None, 50 mask: Optional[SourceLike] = None, 51) -> Tuple[float, float, float, float]: 52 """Compute the CREMI score between two segmentations. 53 54 Args: 55 segmentation: Candidate segmentation to evaluate (a numpy/zarr/n5 array or a `Source`). 56 groundtruth: The groundtruth segmentation; same shape as ``segmentation``. 57 ignore_seg: Labels to ignore in the segmentation (their voxels are excluded). 58 ignore_gt: Labels to ignore in the groundtruth (their voxels are excluded). 59 use_log2: Whether to use ``log2`` (bits) or natural ``log`` (nats) for the VI part. 60 num_workers: Number of parallel workers used to build the contingency table. 61 block_shape: Shape of the processing blocks. Defaults to the input chunk shape. 62 job_type: Execution backend: one of ``"local"``, ``"subprocess"`` or ``"slurm"``. 63 job_config: Backend configuration (a `RunnerConfig` / `SlurmConfig`). 64 mask: Optional binary mask; voxels outside the mask are excluded. 65 66 Returns: 67 The split variation of information, the merge variation of information, the adapted rand error, 68 and the CREMI score. 69 """ 70 table = build_table(segmentation, groundtruth, ignore_seg=ignore_seg, ignore_gt=ignore_gt, 71 num_workers=num_workers, block_shape=block_shape, job_type=job_type, 72 job_config=job_config, mask=mask) 73 return cremi_scores(table, use_log2=use_log2)
23def cremi_scores(table: ContingencyTable, *, use_log2: bool = True) -> Tuple[float, float, float, float]: 24 """Compute the CREMI score and its components from a single contingency table. 25 26 Args: 27 table: A contingency table built as ``contingency_table(segmentation, groundtruth)``. 28 use_log2: Whether to use ``log2`` (bits) or natural ``log`` (nats) for the VI part. 29 30 Returns: 31 The split variation of information, the merge variation of information, the adapted rand error, 32 and the CREMI score (``sqrt(adapted_rand_error * (vi_split + vi_merge))``). 33 """ 34 vi_split, vi_merge = vi_scores(table, use_log2=use_log2) 35 adapted_rand_error, _ = rand_scores(table) 36 cremi = float(np.sqrt(adapted_rand_error * (vi_split + vi_merge))) 37 return vi_split, vi_merge, adapted_rand_error, cremi
Compute the CREMI score and its components from a single contingency table.
Args:
table: A contingency table built as contingency_table(segmentation, groundtruth).
use_log2: Whether to use log2 (bits) or natural log (nats) for the VI part.
Returns:
The split variation of information, the merge variation of information, the adapted rand error,
and the CREMI score (sqrt(adapted_rand_error * (vi_split + vi_merge))).
40def cremi_score( 41 segmentation: SourceLike, 42 groundtruth: SourceLike, 43 *, 44 ignore_seg: Optional[Sequence[int]] = None, 45 ignore_gt: Optional[Sequence[int]] = None, 46 use_log2: bool = True, 47 num_workers: int = 1, 48 block_shape: Optional[Tuple[int, ...]] = None, 49 job_type: str = "local", 50 job_config: Optional[RunnerConfig] = None, 51 mask: Optional[SourceLike] = None, 52) -> Tuple[float, float, float, float]: 53 """Compute the CREMI score between two segmentations. 54 55 Args: 56 segmentation: Candidate segmentation to evaluate (a numpy/zarr/n5 array or a `Source`). 57 groundtruth: The groundtruth segmentation; same shape as ``segmentation``. 58 ignore_seg: Labels to ignore in the segmentation (their voxels are excluded). 59 ignore_gt: Labels to ignore in the groundtruth (their voxels are excluded). 60 use_log2: Whether to use ``log2`` (bits) or natural ``log`` (nats) for the VI part. 61 num_workers: Number of parallel workers used to build the contingency table. 62 block_shape: Shape of the processing blocks. Defaults to the input chunk shape. 63 job_type: Execution backend: one of ``"local"``, ``"subprocess"`` or ``"slurm"``. 64 job_config: Backend configuration (a `RunnerConfig` / `SlurmConfig`). 65 mask: Optional binary mask; voxels outside the mask are excluded. 66 67 Returns: 68 The split variation of information, the merge variation of information, the adapted rand error, 69 and the CREMI score. 70 """ 71 table = build_table(segmentation, groundtruth, ignore_seg=ignore_seg, ignore_gt=ignore_gt, 72 num_workers=num_workers, block_shape=block_shape, job_type=job_type, 73 job_config=job_config, mask=mask) 74 return cremi_scores(table, use_log2=use_log2)
Compute the CREMI score between two segmentations.
Args:
segmentation: Candidate segmentation to evaluate (a numpy/zarr/n5 array or a Source).
groundtruth: The groundtruth segmentation; same shape as segmentation.
ignore_seg: Labels to ignore in the segmentation (their voxels are excluded).
ignore_gt: Labels to ignore in the groundtruth (their voxels are excluded).
use_log2: Whether to use log2 (bits) or natural log (nats) for the VI part.
num_workers: Number of parallel workers used to build the contingency table.
block_shape: Shape of the processing blocks. Defaults to the input chunk shape.
job_type: Execution backend: one of "local", "subprocess" or "slurm".
job_config: Backend configuration (a RunnerConfig / SlurmConfig).
mask: Optional binary mask; voxels outside the mask are excluded.
Returns: The split variation of information, the merge variation of information, the adapted rand error, and the CREMI score.