Initial commit: Speckle-Scanner 3D pipeline with setup README

This commit is contained in:
2026-06-10 03:09:05 +05:00
commit 1765934846
375 changed files with 123081 additions and 0 deletions
@@ -0,0 +1,72 @@
"""Calibration session path resolution and camera folder discovery."""
from __future__ import annotations
import os
from dataclasses import dataclass
from pathlib import Path
from typing import Dict, List, Optional, Tuple
IMAGE_EXTENSIONS = (".bmp", ".png", ".jpg", ".jpeg")
# Logical camera name -> folder aliases on disk
CAMERA_FOLDER_ALIASES: Dict[str, Tuple[str, ...]] = {
"lc": ("lc",),
"lc-ir": ("lc-ir", "lc_ir", "LC-IR"),
"rc": ("rc",),
"rg": ("rg", "rgb"),
"ir": ("ir", "IR"),
}
STEREO_PARTNERS = ("rc", "rg", "ir")
@dataclass(frozen=True)
class CameraFolder:
logical_name: str
path: Path
folder_name: str
def resolve_session_root(input_path: str | Path) -> Path:
"""Return flat or nested `images/` root containing camera folders."""
input_path = Path(input_path)
images_dir = input_path / "images"
if images_dir.is_dir():
return images_dir
return input_path
def discover_camera_folder(
session_root: Path, logical_name: str
) -> Optional[CameraFolder]:
aliases = CAMERA_FOLDER_ALIASES.get(logical_name)
if not aliases:
return None
for folder in aliases:
path = session_root / folder
if path.is_dir():
return CameraFolder(logical_name, path, folder)
return None
def list_image_paths(camera_dir: Path) -> List[Path]:
paths = [
camera_dir / name
for name in os.listdir(camera_dir)
if name.lower().endswith(IMAGE_EXTENSIONS)
]
return sorted(paths)
def json_path_for_image(image_path: Path) -> Path:
return image_path.with_suffix(".json")
def list_cameras_present(session_root: Path) -> List[CameraFolder]:
found = []
for logical in CAMERA_FOLDER_ALIASES:
cam = discover_camera_folder(session_root, logical)
if cam is not None:
found.append(cam)
return found