46 lines
1.7 KiB
Python
46 lines
1.7 KiB
Python
"""Shared helpers for command-line signature evaluation scripts."""
|
|
|
|
from collections import defaultdict
|
|
from pathlib import Path
|
|
|
|
from sigverify.evaluation.metrics import verification_metrics
|
|
from sigverify.evaluation.protocols import enrollment_test_split
|
|
from sigverify.io.loaders import load_csv_directory, load_mobisig
|
|
from sigverify.io.schema import Signature
|
|
from sigverify.matching.models import DTWVerifier
|
|
from sigverify.preprocessing import preprocess_signature
|
|
|
|
|
|
def evaluate_directory(
|
|
directory: str | Path,
|
|
*,
|
|
enrollment_count: int = 3,
|
|
include_pressure: bool = False,
|
|
include_area: bool = False,
|
|
seed: int = 0,
|
|
mobisig: bool = False,
|
|
) -> dict[str, object]:
|
|
"""Load, preprocess, split, and score known-identity attempts."""
|
|
raw = load_mobisig(directory) if mobisig else load_csv_directory(directory)
|
|
samples = [
|
|
preprocess_signature(signature)
|
|
for signature in raw
|
|
]
|
|
enrollment, test = enrollment_test_split(
|
|
samples, enrollment_count=enrollment_count, seed=seed
|
|
)
|
|
templates: dict[str, list[Signature]] = defaultdict(list)
|
|
for signature in enrollment:
|
|
templates[signature.user_id].append(signature)
|
|
|
|
labels: list[int] = []
|
|
scores: list[float] = []
|
|
for sample in test:
|
|
if sample.user_id not in templates:
|
|
raise ValueError(f"test identity {sample.user_id!r} has no enrollment samples")
|
|
verifier = DTWVerifier(include_pressure=include_pressure, include_area=include_area)
|
|
verifier.enroll(templates[sample.user_id])
|
|
scores.append(verifier.score(sample))
|
|
labels.append(int(sample.label.lower() in {"genuine", "g", "1"}))
|
|
return verification_metrics(labels, scores)
|