import sys from pathlib import Path import cv2 import uvicorn from bookmark.camera import CameraSource from bookmark.capture_strategies.manual_button import ManualButtonStrategy from bookmark.capture_strategies.motion_stop import MotionStopStrategy from bookmark.capture_strategies.stable_centered import StableCenteredStrategy from bookmark.catalogue import Catalogue from bookmark.config import AppConfig from bookmark.main import create_app from bookmark.session import IntakeSession def build_strategy(config: AppConfig, reference_frame): if config.trigger_strategy == "manual": return ManualButtonStrategy() if config.trigger_strategy == "motion_stop": return MotionStopStrategy() if config.trigger_strategy == "stable_centered": return StableCenteredStrategy(reference_frame=reference_frame, guide_box=config.guide_box) raise ValueError(f"Unknown trigger_strategy: {config.trigger_strategy}") def main() -> None: config_path = Path(sys.argv[1]) if len(sys.argv) > 1 else Path("config.json") config = AppConfig.load(config_path) reference_frame = cv2.imread(str(config.reference_frame_path)) if reference_frame is None: raise RuntimeError( f"Could not load reference frame from {config.reference_frame_path}. " "Run calibrate.py first to capture an empty-platform reference image." ) catalogue = Catalogue(config.catalogue_path) strategy = build_strategy(config, reference_frame) session = IntakeSession( catalogue=catalogue, strategy=strategy, reference_frame=reference_frame, markers=config.markers, captures_dir=config.captures_dir, ) camera = CameraSource(device_index=config.device_index) camera.open() app = create_app(session, camera) uvicorn.run(app, host="0.0.0.0", port=8000) if __name__ == "__main__": main()