| |
| """ |
| Water Surface Segmentation Evaluation Script |
| Evaluate the trained model on a validation dataset. |
| """ |
|
|
| import argparse |
| import os |
| import sys |
| from pathlib import Path |
| from ultralytics import YOLO |
|
|
|
|
| def parse_arguments() -> argparse.Namespace: |
| """Parse command line arguments.""" |
| parser = argparse.ArgumentParser( |
| description="Evaluate water surface segmentation model", |
| formatter_class=argparse.ArgumentDefaultsHelpFormatter |
| ) |
|
|
| parser.add_argument( |
| "--data", |
| type=str, |
| required=True, |
| help="Path to validation dataset or data.yaml file" |
| ) |
|
|
| parser.add_argument( |
| "--weights", |
| type=str, |
| default="model/nwsd-v2.pt", |
| help="Path to model weights file" |
| ) |
|
|
| parser.add_argument( |
| "--img", |
| type=int, |
| default=640, |
| help="Image size for evaluation" |
| ) |
|
|
| parser.add_argument( |
| "--batch", |
| type=int, |
| default=16, |
| help="Batch size for evaluation" |
| ) |
|
|
| parser.add_argument( |
| "--conf", |
| type=float, |
| default=0.25, |
| help="Confidence threshold" |
| ) |
|
|
| parser.add_argument( |
| "--iou", |
| type=float, |
| default=0.45, |
| help="IoU threshold for NMS" |
| ) |
|
|
| parser.add_argument( |
| "--device", |
| type=str, |
| default="", |
| help="Device to use for evaluation (cpu, cuda, mps)" |
| ) |
|
|
| parser.add_argument( |
| "--project", |
| type=str, |
| default="runs/segment", |
| help="Project directory for results" |
| ) |
|
|
| parser.add_argument( |
| "--name", |
| type=str, |
| default="nwsd_eval", |
| help="Experiment name" |
| ) |
|
|
| parser.add_argument( |
| "--save-json", |
| action="store_true", |
| help="Save results in JSON format" |
| ) |
|
|
| parser.add_argument( |
| "--save-txt", |
| action="store_true", |
| help="Save results in TXT format" |
| ) |
|
|
| parser.add_argument( |
| "--plots", |
| action="store_true", |
| help="Generate evaluation plots" |
| ) |
|
|
| return parser.parse_args() |
|
|
|
|
| def validate_inputs(args: argparse.Namespace) -> None: |
| """Validate input arguments.""" |
| if not os.path.exists(args.data): |
| raise FileNotFoundError(f"Data path not found: {args.data}") |
|
|
| if not os.path.exists(args.weights): |
| raise FileNotFoundError(f"Model weights not found: {args.weights}") |
|
|
|
|
| def main(): |
| """Main evaluation function.""" |
| args = parse_arguments() |
|
|
| try: |
| validate_inputs(args) |
|
|
| print(f"Loading model: {args.weights}") |
| model = YOLO(args.weights) |
|
|
| eval_params = { |
| 'data': args.data, |
| 'imgsz': args.img, |
| 'batch': args.batch, |
| 'conf': args.conf, |
| 'iou': args.iou, |
| 'device': args.device, |
| 'project': args.project, |
| 'name': args.name, |
| 'save_json': args.save_json, |
| 'save_txt': args.save_txt, |
| 'plots': args.plots, |
| 'verbose': True, |
| } |
|
|
| print("Starting evaluation with parameters:") |
| for key, value in eval_params.items(): |
| print(f" {key}: {value}") |
|
|
| results = model.val(**eval_params) |
|
|
| print("\n" + "="*50) |
| print("EVALUATION RESULTS SUMMARY") |
| print("="*50) |
|
|
| if hasattr(results, 'box') and results.box is not None: |
| print(f"mAP50: {results.box.map50:.4f}") |
| print(f"mAP50-95: {results.box.map:.4f}") |
|
|
| if hasattr(results, 'seg') and results.seg is not None: |
| print(f"Segmentation mAP50: {results.seg.map50:.4f}") |
| print(f"Segmentation mAP50-95: {results.seg.map:.4f}") |
|
|
| print("\nEvaluation completed successfully!") |
|
|
| except Exception as e: |
| print(f"Error: {str(e)}", file=sys.stderr) |
| sys.exit(1) |
|
|
|
|
| if __name__ == "__main__": |
| main() |
|
|