Skip to content

Latest commit

Β 

History

7 Commits

Folders and files

NameName
Last commit message
Last commit date
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

Satellite Inference Pipeline

A production-grade, headless satellite image processing pipeline that automatically detects objects in large geospatial imagery using YOLO deep learning models. The system watches directories for new satellite images, processes them automatically with multiple AI models in parallel across GPUs, and outputs geospatial detection results in GeoJSON format.

πŸš€ Features

  • Automated Processing: Watches directories and processes images as they arrive
  • Multi-Model Support: Run multiple YOLO/YOLO-OBB models on the same image
  • Multi-GPU Support: Distribute models across GPUs for parallel processing
  • Geospatial Output: Generates GeoJSON files with precise geographic coordinates
  • Projection Support: Handles any projection system (WGS84, UTM, custom projections)
  • Intelligent Tiling: Automatically tiles large images for efficient processing
  • Batch Processing: Process multiple images concurrently
  • Retry Mechanism: Automatic retry for transient failures
  • Health Monitoring: Real-time dashboard and health status JSON
  • Docker Support: Full Docker containerization for easy deployment
  • Persistent Queue: Job queue persists across restarts

πŸ“‹ Table of Contents

⚑ Quick Start

1. Install Dependencies

pip install ultralytics torch numpy pillow pyproj pyyaml watchdog

2. Configure

Edit config/pipeline.yaml:

  • Set input_dir to watch for images
  • Update model paths (weights_path)
  • Assign models to GPUs

3. Run

python run_pipeline.py --config config/pipeline.yaml

4. Monitor

In another terminal:

python dashboard_server.py
# Open http://localhost:8080

πŸ› οΈ Installation

Prerequisites

  • Python 3.8+
  • CUDA-capable GPU (recommended) or CPU fallback
  • GDAL (for geospatial data processing)
    • Windows: Install via OSGeo4W or conda
    • Linux: sudo apt-get install gdal-bin python3-gdal
    • Mac: brew install gdal

Step-by-Step Installation

  1. Clone the repository:

    git clone https://github.com/sid342001/inference_Script_final.git
    cd inference_Script_final
  2. Install Python dependencies:

    pip install ultralytics torch numpy pillow pyproj pyyaml watchdog
  3. Verify GPU support (optional):

    python -c "import torch; print(f'CUDA available: {torch.cuda.is_available()}')"
  4. Verify GDAL installation:

    python -c "from osgeo import gdal; print('GDAL OK')"
  5. Create required directories:

    mkdir -p data/incoming models artifacts state logs
  6. Place your model files (.pt files) in the models/ directory

βš™οΈ Configuration

The pipeline is configured via config/pipeline.yaml. Key sections:

Region of Interest (ROI) per model

The ROI feature lets you restrict inference to specific geographic regions per model.

  • Per-model setting: Add roi_geojson_path to any model block that should use an ROI.
  • One GeoJSON per model: Each file can contain one or more polygons; all polygons are treated as the model’s ROI.
  • CRS: Define ROI polygons in WGS84 (EPSG:4326) unless you know they match the image CRS.
  • Behavior:
    • If an image does not intersect the ROI β†’ that model is skipped for that image.
    • If an image partially intersects the ROI β†’ only the intersecting part is processed.
    • If no ROI is configured β†’ the model processes the full image (existing behavior).
    • If an image intersects multiple ROI polygons in the same file β†’ intersections are unioned into a single processing region and processed once.

Update your config/pipeline.yaml like this:

models:
  - name: "Yolo_plane_x"
    weights_path: "D:/aks/sat-annotator-main/inference_Script/models/Yolo_plane_x.pt"
    type: "yolo"
    device: "cuda:0"
    confidence_threshold: 0.5

    # NEW: optional ROI for this model
    roi_geojson_path: "D:/aks/sat-annotator-main/inference_Script/config/roi_Yolo_plane_x.geojson"

    all_folders: false
    folder_identities: ["qgis", "SAR", "jp2"]
    tile:
      tile_size: 256
      overlap: 128
      normalization_mode: "auto"
      allow_resample: true
      iou_threshold: 0.8
      ioma_threshold: 0.75

    outputs:
      write_tile_previews: false
      summary_csv: true

  - name: "yolo11n-obb"
    weights_path: "D:/aks/sat-annotator-main/inference_Script/models/yolo11n-obb.pt"
    type: "yolo_obb"
    device: "cuda:0"
    confidence_threshold: 0.6

    # Optional ROI for this model (can be different from above)
    roi_geojson_path: "D:/aks/sat-annotator-main/inference_Script/config/roi_yolo11n_obb.geojson"

    all_folders: false
    folder_identities: ["carto", "maxar", "jp2"]
    tile:
      tile_size: 1024
      overlap: 512
      normalization_mode: "auto"
      allow_resample: true
      iou_threshold: 0.75
      ioma_threshold: 0.7

    outputs:
      write_tile_previews: false
      summary_csv: true

Place the ROI GeoJSON files in config/ (or any path you prefer) and point roi_geojson_path to the full path. Each GeoJSON should contain one or more rectangular (or arbitrary) polygons covering the regions where you want inference to run.

ROI GeoJSON structure

The ROI GeoJSON is a standard GeoJSON file. Only the geometry is used; any properties are ignored.

  • Recommended CRS: WGS84 (EPSG:4326) with coordinates as [longitude, latitude].
  • Supported geometries:
    • Polygon
    • MultiPolygon (inside a Feature)
    • Multiple Features in a FeatureCollection

Minimal example with a single rectangular ROI:

{
  "type": "FeatureCollection",
  "features": [
    {
      "type": "Feature",
      "properties": {
        "name": "roi_example"
      },
      "geometry": {
        "type": "Polygon",
        "coordinates": [[
          [72.8000, 18.9000],
          [73.0000, 18.9000],
          [73.0000, 19.1000],
          [72.8000, 19.1000],
          [72.8000, 18.9000]
        ]]
      }
    }
  ]
}

You can also include multiple polygons in the same file; all are treated as ROI for that model. If an image intersects more than one polygon, the pipeline unions the intersections and processes that unioned region once.

Watcher Configuration

watcher:
  input_dir: "data/incoming"        # Directory to watch for images
  recursive: true                   # Watch subdirectories
  include_extensions: [".tif", ".tiff", ".jp2", ".img"]
  settle_time_seconds: 10           # Wait for file to finish copying
  max_inflight_jobs: 32             # Max jobs in queue
  folder_identities: ["carto", "maxar", "qgis", "SAR", "jp2"]  # Optional folder filtering

Model Configuration

models:
  - name: "yolo_main"
    weights_path: "models/yolo_main.pt"
    device: "cuda:0"                # Assign to GPU 0
    confidence_threshold: 0.25
    iou_threshold: 0.45
    # Optional: Per-model tiling overrides
    tile:
      tile_size: 512
      overlap: 256
  
  - name: "yolo_obb"
    weights_path: "models/yolo_obb.pt"
    device: "cuda:1"                # Assign to GPU 1 for parallelization

Worker Configuration

workers:
  max_concurrent_jobs: 8           # Process 8 images simultaneously
  batch_size: 12                    # Process 12 tiles per batch
  hybrid_mode: true                 # Enable dynamic GPU assignment
  gpu_balancing_strategy: "least_busy"  # Options: "least_busy", "round_robin", "least_queued"

Queue Configuration

queue:
  persistence_path: "state/queue.json"  # Queue state file
  max_retries: 3                    # Retry failed jobs 3 times
  retry_backoff_seconds: 60        # Wait between retries
  quarantine_dir: "state/quarantine"   # Permanently failed jobs

Output Configuration

artifacts:
  success_dir: "artifacts/success"      # Successful job outputs
  failure_dir: "artifacts/failure"      # Failed job outputs
  combined_dir: "artifacts/combined"    # Combined model results
  logs_dir: "artifacts/logs"            # Per-image logs

See config/pipeline.yaml for complete configuration options.

πŸ“– Usage

Basic Usage

  1. Start the pipeline:

    python run_pipeline.py --config config/pipeline.yaml
  2. Add images to process:

    • Copy satellite images (.tif, .tiff, .jp2, .img) to data/incoming/
    • The pipeline will automatically detect and process them
  3. View results:

    • Successful outputs: artifacts/success/<job_id>/
    • Combined results: artifacts/combined/<job_id>/
    • Failed jobs: artifacts/failure/<job_id>/

Advanced Usage

Folder-Based Processing

Organize images by folder to maintain identity:

data/incoming/
  β”œβ”€β”€ carto/
  β”‚   └── image1.tif
  β”œβ”€β”€ maxar/
  β”‚   └── image2.tif
  └── SAR/
      └── image3.tif

Configure folder_identities in pipeline.yaml to filter specific folders.

Multiple Models per Image

Configure multiple models in pipeline.yaml:

models:
  - name: "ships"
    weights_path: "models/ship_detector.pt"
    device: "cuda:0"
  - name: "aircraft"
    weights_path: "models/aircraft_detector.pt"
    device: "cuda:1"

Each image will be processed by all models, with combined results in artifacts/combined/.

GPU Parallelization

Distribute models across GPUs for maximum throughput:

models:
  - name: "model1"
    device: "cuda:0"    # GPU 0
  - name: "model2"
    device: "cuda:1"    # GPU 1
  - name: "model3"
    device: "cuda:0"    # GPU 0 (can share GPUs)

Enable hybrid mode for dynamic GPU assignment:

workers:
  hybrid_mode: true
  gpu_balancing_strategy: "least_busy"

πŸ“Š Output Formats

Per-Model Outputs

Each model produces results in artifacts/success/<job_id>/<model_name>/:

  • <model_name>.geojson: GeoJSON file with detected objects
  • <model_name>.csv: CSV summary with detection statistics
  • tiles/: Optional tile preview images (if enabled)

Combined Outputs

Combined results from all models in artifacts/combined/<job_id>/:

  • combined.geojson: All detections from all models
  • combined.csv: Summary statistics
  • manifest.json: Processing metadata

GeoJSON Format

{
  "type": "FeatureCollection",
  "features": [
    {
      "type": "Feature",
      "geometry": {
        "type": "Polygon",
        "coordinates": [[[lon1, lat1], [lon2, lat2], ...]]
      },
      "properties": {
        "model": "yolo_main",
        "confidence": 0.95,
        "class": "ship",
        "class_id": 0
      }
    }
  ]
}

CSV Format

model,class,confidence,area_m2,centroid_lon,centroid_lat
yolo_main,ship,0.95,1234.5,-122.123,37.456

🐳 Docker Deployment

Quick Start with Docker

  1. Build the image:

    docker build -t satellite-inference .
  2. Run with docker-compose:

    docker-compose up -d
  3. View logs:

    docker-compose logs -f

Docker Configuration

Edit docker-compose.yml to configure:

  • Volume mounts for data, models, and outputs
  • GPU access (nvidia-docker)
  • Environment variables
  • Port mappings

See DOCKER_QUICK_START.md for detailed Docker setup instructions.

πŸ“ˆ Monitoring

Web Dashboard

Start the dashboard server:

python dashboard_server.py

Access at: http://localhost:8080

Features:

  • Real-time pipeline status
  • Queue monitoring (pending, processing, completed)
  • GPU utilization across all devices
  • Worker status
  • Recent job history

Health Status JSON

Real-time status available at artifacts/health/status.json:

{
  "status": "running",
  "queue": {
    "pending": 5,
    "processing": 2,
    "completed": 100,
    "failed": 3
  },
  "gpus": [
    {
      "device": "cuda:0",
      "utilization": 85.5,
      "memory_used_mb": 8192,
      "memory_total_mb": 12288
    }
  ],
  "workers": {
    "alive": 8,
    "active": 2
  }
}

Logs

  • Pipeline logs: logs/pipeline/
  • Per-image logs: artifacts/logs/<job_id>.log
  • Dashboard logs: Console output from dashboard_server.py

πŸ—οΈ Architecture

System Components

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚                  Orchestrator (Main Controller)          β”‚
β”‚  - Manages workers, queue, watcher, health monitor      β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
         β”‚              β”‚              β”‚              β”‚
         β–Ό              β–Ό              β–Ό              β–Ό
    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”
    β”‚ Watcherβ”‚    β”‚ Queue  β”‚    β”‚Workers β”‚    β”‚ Health β”‚
    β”‚        β”‚    β”‚        β”‚    β”‚        β”‚    β”‚Monitor β”‚
    β””β”€β”€β”€β”€β”€β”€β”€β”€β”˜    β””β”€β”€β”€β”€β”€β”€β”€β”€β”˜    β””β”€β”€β”€β”€β”€β”€β”€β”€β”˜    β””β”€β”€β”€β”€β”€β”€β”€β”€β”˜
         β”‚              β”‚              β”‚
         β–Ό              β–Ό              β–Ό
    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
    β”‚         Job Processing Pipeline       β”‚
    β”‚  1. Tile Image                        β”‚
    β”‚  2. Run Models (GPU)                  β”‚
    β”‚  3. Merge Results                     β”‚
    β”‚  4. Generate GeoJSON/CSV             β”‚
    β”‚  5. Write Artifacts                  β”‚
    β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

Processing Flow

  1. File Detection: Watcher detects new image in input_dir
  2. Job Enqueue: Image added to persistent queue
  3. Tiling: Large image split into overlapping tiles
  4. Inference: Tiles processed by YOLO models on GPUs
  5. NMS: Non-maximum suppression removes duplicates
  6. Reprojection: Coordinates converted to WGS84
  7. Output: GeoJSON and CSV files generated
  8. Cleanup: Temporary files removed

GPU Modes

  • Dedicated Mode: Each model pinned to specific GPU
  • Hybrid Mode: Models loaded on all GPUs, dynamic assignment
  • CPU Fallback: Automatic fallback if no GPU available

πŸ”§ Troubleshooting

Common Issues

Pipeline Not Processing Images

  1. Check input directory:

    ls data/incoming/  # Verify images are present
  2. Check file extensions: Ensure images have supported extensions (.tif, .tiff, .jp2, .img)

  3. Check logs: Review logs/pipeline/ for errors

  4. Verify configuration: Check config/pipeline.yaml paths are correct

GPU Not Detected

  1. Verify CUDA installation:

    python -c "import torch; print(torch.cuda.is_available())"
    nvidia-smi
  2. Check PyTorch CUDA version:

    python -c "import torch; print(torch.version.cuda)"
  3. Use CPU fallback: Set device: "cpu" in model config

Out of Memory Errors

  1. Reduce batch size:

    workers:
      batch_size: 4  # Reduce from default
  2. Reduce concurrent jobs:

    workers:
      max_concurrent_jobs: 2  # Reduce from default
  3. Reduce tile size:

    tiling:
      tile_size: 256  # Reduce from 512

Projection Errors

  1. Verify GDAL installation:

    python -c "from osgeo import gdal; print('GDAL OK')"
  2. Check PROJ data: Ensure PROJ database is accessible

  3. Review logs: Check for specific projection errors in logs

Getting Help

  • Check HOW_TO_RUN.md for detailed troubleshooting
  • Review logs in logs/pipeline/ and artifacts/logs/
  • Check health status: artifacts/health/status.json
  • Open an issue on GitHub with:
    • Error messages
    • Configuration file (sanitized)
    • Log excerpts

πŸ“ Project Structure

inference_Script/
β”œβ”€β”€ config/
β”‚   β”œβ”€β”€ pipeline.yaml          # Main configuration file
β”‚   └── pipeline.yaml.docker   # Docker-specific config
β”œβ”€β”€ data/
β”‚   └── incoming/              # Input directory (watched)
β”œβ”€β”€ models/                    # YOLO model files (.pt)
β”œβ”€β”€ artifacts/                 # Output directory
β”‚   β”œβ”€β”€ success/              # Successful job outputs
β”‚   β”œβ”€β”€ failure/              # Failed job outputs
β”‚   β”œβ”€β”€ combined/             # Combined model results
β”‚   β”œβ”€β”€ logs/                 # Per-image logs
β”‚   └── health/               # Health status JSON
β”œβ”€β”€ state/                     # State files
β”‚   β”œβ”€β”€ queue.json            # Persistent job queue
β”‚   └── quarantine/           # Permanently failed jobs
β”œβ”€β”€ logs/                      # Pipeline logs
β”œβ”€β”€ run_pipeline.py            # Main entry point
β”œβ”€β”€ orchestrator.py            # Core orchestrator
β”œβ”€β”€ watcher.py                 # File watcher
β”œβ”€β”€ job_queue.py               # Job queue manager
β”œβ”€β”€ inference_runner.py       # Inference execution
β”œβ”€β”€ tiler.py                   # Image tiling
β”œβ”€β”€ infer.py                   # YOLO inference
β”œβ”€β”€ dashboard_server.py        # Web dashboard
└── README.md                  # This file

🀝 Contributing

Contributions are welcome! Please follow these steps:

  1. Fork the repository
  2. Create a feature branch (git checkout -b feature/amazing-feature)
  3. Commit your changes (git commit -m 'Add amazing feature')
  4. Push to the branch (git push origin feature/amazing-feature)
  5. Open a Pull Request

πŸ“„ License

This project is licensed under the MIT License - see the LICENSE file for details.

πŸ™ Acknowledgments

πŸ“ž Support

For support and questions:

  • Open an issue on GitHub
  • Check the documentation in the docs/ directory
  • Review troubleshooting guides in the repository

Ready to process satellite imagery? Start with the Quick Start section above! πŸš€

About

Inference script automatic inference

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages