File size: 1,437 Bytes
5ddd413
 
 
 
 
08572f5
 
5ddd413
 
 
 
 
 
 
 
 
 
08572f5
 
 
 
 
 
 
5ddd413
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
39
40
41
42
43
44
45
46
"""
Seamless check for 2:1 equirectangular skybox: compare left vs right edge.
Returns MSE and a simple pass/fail (low MSE = more seamless).
"""

from pathlib import Path

import numpy as np
from PIL import Image


def check_seamless(image_path: str, column_width: int = 5) -> dict:
    """
    Load image, compare left and right edge columns. Equirectangular wraps,
    so left and right should match for a seamless skybox.
    Returns dict with mse, passed (bool), and message.
    """
    path = Path(image_path)
    if not path.is_file():
        return {
            "mse": float("inf"),
            "passed": False,
            "message": f"Image file not found: {path.name}",
        }
    img = np.array(Image.open(image_path).convert("RGB"))
    h, w = img.shape[:2]

    if w < 2 * column_width:
        return {
            "mse": float("inf"),
            "passed": False,
            "message": f"Image width {w} too small for column width {column_width}",
        }

    left = img[:, :column_width].astype(np.float32)
    right = img[:, -column_width:].astype(np.float32)
    mse = float(np.mean((left - right) ** 2))

    # Heuristic: MSE < 100 often looks reasonably seamless
    passed = mse < 100
    message = (
        f"Left/right edge MSE = {mse:.2f}. "
        + ("Seamless (edges match)." if passed else "Edges differ (consider 360° model).")
    )
    return {"mse": mse, "passed": passed, "message": message}