File size: 1,100 Bytes
574aa8f | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 | """Simple full-reference metrics for the bundled short/long M51 pair."""
from __future__ import annotations
import argparse
import math
from pathlib import Path
import numpy as np
from PIL import Image
def load_rgb(path: Path) -> np.ndarray:
with Image.open(path) as image:
return np.asarray(image.convert("RGB"), dtype=np.float32) / 255.0
def psnr(reference: np.ndarray, candidate: np.ndarray) -> float:
mse = float(np.mean((reference - candidate) ** 2))
return math.inf if mse == 0 else 10.0 * math.log10(1.0 / mse)
def main() -> None:
parser = argparse.ArgumentParser()
parser.add_argument("reference", type=Path)
parser.add_argument("candidate", type=Path)
args = parser.parse_args()
reference, candidate = load_rgb(args.reference), load_rgb(args.candidate)
if reference.shape != candidate.shape:
raise ValueError(f"Shape mismatch: {reference.shape} vs {candidate.shape}")
print(f"PSNR: {psnr(reference, candidate):.3f} dB")
print(f"MAE: {np.mean(np.abs(reference - candidate)):.6f}")
if __name__ == "__main__":
main()
|