Skip to content
549 changes: 549 additions & 0 deletions notebooks/700_metrics/701a_aupimo.ipynb

Large diffs are not rendered by default.

690 changes: 690 additions & 0 deletions notebooks/700_metrics/roc_pro_pimo.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
14 changes: 13 additions & 1 deletion src/anomalib/data/utils/path.py
Original file line number Diff line number Diff line change
Expand Up @@ -142,13 +142,20 @@ def contains_non_printable_characters(path: str | Path) -> bool:
return not printable_pattern.match(str(path))


def validate_path(path: str | Path, base_dir: str | Path | None = None, should_exist: bool = True) -> Path:
def validate_path(
path: str | Path,
base_dir: str | Path | None = None,
should_exist: bool = True,
extensions: tuple[str, ...] | None = None,
) -> Path:
"""Validate the path.

Args:
path (str | Path): Path to validate.
base_dir (str | Path): Base directory to restrict file access.
should_exist (bool): If True, do not raise an exception if the path does not exist.
extensions (tuple[str, ...] | None): Accepted extensions for the path. An exception is raised if the
path does not have one of the accepted extensions. If None, no check is performed. Defaults to None.

Returns:
Path: Validated path.
Expand Down Expand Up @@ -213,6 +220,11 @@ def validate_path(path: str | Path, base_dir: str | Path | None = None, should_e
msg = f"Read or execute permissions denied for the path: {path}"
raise PermissionError(msg)

# Check if the path has one of the accepted extensions
if extensions is not None and path.suffix not in extensions:
msg = f"Path extension is not accepted. Accepted extensions: {extensions}. Path: {path}"
raise ValueError(msg)

return path


Expand Down
3 changes: 3 additions & 0 deletions src/anomalib/metrics/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
from .f1_max import F1Max
from .f1_score import F1Score
from .min_max import MinMax
from .pimo import AUPIMO, PIMO
from .precision_recall_curve import BinaryPrecisionRecallCurve
from .pro import PRO
from .threshold import F1AdaptiveThreshold, ManualThreshold
Expand All @@ -35,6 +36,8 @@
"ManualThreshold",
"MinMax",
"PRO",
"PIMO",
"AUPIMO",
]

logger = logging.getLogger(__name__)
Expand Down
23 changes: 23 additions & 0 deletions src/anomalib/metrics/pimo/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
"""Per-Image Metrics."""

# Original Code
# https://github.com/jpcbertoldo/aupimo
#
# Modified
# Copyright (C) 2024 Intel Corporation
# SPDX-License-Identifier: Apache-2.0

from .binary_classification_curve import ThresholdMethod
from .pimo import AUPIMO, PIMO, AUPIMOResult, PIMOResult

__all__ = [
# constants
"ThresholdMethod",
# result classes
"PIMOResult",
"AUPIMOResult",
# torchmetrics interfaces
"PIMO",
"AUPIMO",
"StatsOutliersPolicy",
]
Loading