from __future__ import annotations import argparse import logging import sys from .pipeline import ScoliosisPipeline if __name__ == "__main__": parser = argparse.ArgumentParser(description="Scoliosis Detection Pipeline") parser.add_argument( "--source", type=str, required=True, help="Video source path or camera ID" ) parser.add_argument( "--checkpoint", type=str, required=True, help="Model checkpoint path" ) parser.add_argument( "--config", type=str, default="configs/sconet/sconet_scoliosis1k.yaml", help="Config file path", ) parser.add_argument("--device", type=str, default="cuda:0", help="Device to run on") parser.add_argument( "--yolo-model", type=str, default="ckpt/yolo11n-seg.pt", help="YOLO model name" ) parser.add_argument( "--window", type=int, default=30, help="Window size for classification" ) parser.add_argument("--stride", type=int, default=30, help="Stride for window") parser.add_argument( "--nats-url", type=str, default=None, help="NATS URL for result publishing" ) parser.add_argument( "--nats-subject", type=str, default="scoliosis.result", help="NATS subject" ) parser.add_argument( "--max-frames", type=int, default=None, help="Maximum frames to process" ) parser.add_argument( "--preprocess-only", action="store_true", help="Only preprocess silhouettes" ) parser.add_argument( "--silhouette-export-path", type=str, default=None, help="Path to export silhouettes", ) parser.add_argument( "--silhouette-export-format", type=str, default="pickle", help="Export format" ) parser.add_argument( "--silhouette-visualize-dir", type=str, default=None, help="Directory for silhouette visualizations", ) parser.add_argument( "--result-export-path", type=str, default=None, help="Path to export results" ) parser.add_argument( "--result-export-format", type=str, default="json", help="Result export format" ) parser.add_argument( "--visualize", action="store_true", help="Enable real-time visualization" ) args = parser.parse_args() logging.basicConfig( level=logging.INFO, format="%(asctime)s %(levelname)s %(name)s: %(message)s", ) # Validate preprocess-only mode requires silhouette export path if args.preprocess_only and not args.silhouette_export_path: print( "Error: --silhouette-export-path is required when using --preprocess-only", file=sys.stderr, ) raise SystemExit(2) try: # Import here to avoid circular imports from .pipeline import validate_runtime_inputs validate_runtime_inputs( source=args.source, checkpoint=args.checkpoint, config=args.config ) # Build kwargs based on what ScoliosisPipeline accepts pipeline_kwargs = { "source": args.source, "checkpoint": args.checkpoint, "config": args.config, "device": args.device, "yolo_model": args.yolo_model, "window": args.window, "stride": args.stride, "nats_url": args.nats_url, "nats_subject": args.nats_subject, "max_frames": args.max_frames, "preprocess_only": args.preprocess_only, "silhouette_export_path": args.silhouette_export_path, "silhouette_export_format": args.silhouette_export_format, "silhouette_visualize_dir": args.silhouette_visualize_dir, "result_export_path": args.result_export_path, "result_export_format": args.result_export_format, "visualize": args.visualize, } pipeline = ScoliosisPipeline(**pipeline_kwargs) raise SystemExit(pipeline.run()) except ValueError as err: print(f"Error: {err}", file=sys.stderr) raise SystemExit(2) from err except RuntimeError as err: print(f"Runtime error: {err}", file=sys.stderr) raise SystemExit(1) from err