Skip to main content

Object detection ensemble toolkit with ground truth validation

Project description

DetectionFusion

DetectionFusion Logo

An Object Detection Ensemble Toolkit

Python 3.8+ License: MIT Version

DetectionFusion is a Python toolkit for fusing multiple object detection results with ground truth validation and error analysis.

Perfect for scenarios where you have multiple object detection models - leverage the wisdom of crowds to improve detection quality through consensus-based ensemble learning, and evaluate performance with rigorous ground truth analysis.

Author: Abhik Sarkar

Key Features

  • 16 Ensemble Strategies: From simple voting to adaptive multi-scale methods
  • Extensible Format Support: YOLO, VOC XML, COCO - with easy extension for new formats
  • Pipeline API: Fluent interface for chaining load -> ensemble -> evaluate operations
  • Modern CLI: Click-based CLI with Rich output (detection-fusion / dfusion)
  • Ground Truth Evaluation: Complete evaluation framework with standard metrics
  • GT Rectification: Identify potential annotation errors using ensemble consensus
  • Pydantic Models: Type-safe configuration and detection classes
  • PyPI Ready: Modern pyproject.toml packaging

How It Works

DetectionFusion combines predictions from multiple object detection models into a single, more accurate result.

Before Fusion After Fusion
Multiple models produce different boxes DetectionFusion merges into one result

Installation

# Clone the repository
git clone https://github.com/abhiksark/detection-fusion
cd detection-fusion

# Install in development mode
pip install -e ".[dev]"

# Or install with specific extras
pip install -e ".[cli]"      # CLI with Rich output
pip install -e ".[viz]"      # Visualization support
pip install -e ".[full]"     # Everything

Quick Start

Command Line Interface

# List available strategies
detection-fusion list-strategies

# List with category filter
detection-fusion list-strategies --category voting -v

# Merge detections from multiple models
detection-fusion merge -d labels/ -s weighted_vote -o unified/

# Validate against ground truth
detection-fusion validate -d labels/ --gt-dir GT/ -s weighted_vote

# Convert annotation formats
detection-fusion convert --input annotations.xml --output labels/ --input-format voc_xml --output-format yolo

# Rectify ground truth annotations
detection-fusion rectify --labels-dir labels/ --gt-dir GT/ --images-dir images/ --output rectified/

# List supported formats
detection-fusion list-formats

Python API

from detection_fusion import (
    Detection,
    DetectionSet,
    merge_detections,
    evaluate_detections,
    convert_annotations,
)

# Quick merge with convenience function
results = merge_detections("labels/", strategy="weighted_vote")

# Or use the Pipeline API for more control
from detection_fusion.pipeline import DetectionPipeline

pipeline = (
    DetectionPipeline()
    .load("labels/", format="yolo")
    .ensemble("weighted_vote", iou_threshold=0.5)
    .evaluate("GT/")
)
ctx = pipeline.run()

print(f"Merged {len(ctx.ensemble_result)} detections")
print(f"Precision: {ctx.evaluation_result.precision:.3f}")
print(f"Recall: {ctx.evaluation_result.recall:.3f}")

Working with Detections

from detection_fusion import Detection, DetectionSet

# Create a detection (Pydantic model - immutable)
det = Detection(
    class_id=0,
    x=0.5, y=0.5,  # Center coordinates (normalized)
    w=0.2, h=0.3,  # Width/height (normalized)
    confidence=0.95,
    model_source="yolov8n",
    image_name="image_001"
)

# Access properties
print(det.bbox)    # [0.5, 0.5, 0.2, 0.3]
print(det.xyxy)    # [0.4, 0.35, 0.6, 0.65]
print(det.area)    # 0.06
print(det.center)  # (0.5, 0.5)

# Create modified copies (immutable)
det2 = det.with_confidence(0.8)
det3 = det.with_source("yolov8s")

# Calculate IoU
iou = det.iou_with(det2)

# Work with DetectionSet for filtering/grouping
detections = {
    "model1": [det1, det2],
    "model2": [det3, det4],
}
ds = DetectionSet(detections)

# Filter and group
high_conf = ds.filter_by_confidence(0.8)
by_class = ds.group_by_class()
by_image = ds.group_by_image()

# Statistics
stats = ds.confidence_stats()
print(f"Mean confidence: {stats['mean']:.3f}")

Using Strategies Directly

from detection_fusion.strategies import StrategyRegistry, create_strategy

# List all strategies
strategies = StrategyRegistry.list_all()
print(f"Available: {strategies}")

# Get strategy info
info = StrategyRegistry.get_info("weighted_vote")
print(f"Category: {info.category}")
print(f"Parameters: {info.parameters}")

# Create and use a strategy
strategy = create_strategy("weighted_vote", iou_threshold=0.6)
results = strategy.merge(detections)

# Validate parameters with schema
validated = strategy.validate_params(iou_threshold=0.5, use_model_weights=True)

Format Conversion

from detection_fusion.data.formats import FormatRegistry

# List available formats
formats = FormatRegistry.list_formats()
print(f"Readers: {formats['readers']}")
print(f"Writers: {formats['writers']}")

# Auto-detect format
reader = FormatRegistry.auto_detect_reader("annotations/")
detections = reader.read_directory("annotations/")

# Convert formats
from detection_fusion import convert_annotations

convert_annotations(
    input_path="annotations.xml",
    output_path="labels/",
    input_format="voc_xml",
    output_format="yolo"
)

Available Strategies (16)

Category Strategies Description
Voting majority_vote, weighted_vote Consensus-based merging
NMS nms, affirmative_nms Non-maximum suppression variants
Clustering dbscan Density-based spatial clustering
Probabilistic soft_voting, bayesian Probabilistic fusion methods
Distance-Based distance_weighted, centroid_clustering Spatial relationship methods
Confidence-Based confidence_threshold, confidence_weighted_nms, high_confidence_first Confidence-aware processing
Adaptive adaptive_threshold, density_adaptive, multi_scale, consensus_ranking Context-aware strategies

Supported Formats

Format Read Write Auto-Detect
YOLO (.txt) Yes Yes Yes
VOC XML (.xml) Yes Yes Yes
COCO JSON (.json) Yes Yes Yes

Configuration

Strategy Config (Pydantic)

from detection_fusion.config import StrategyConfig

# Builder pattern for config
config = (
    StrategyConfig()
    .with_overlap(threshold=0.6, method="iou")
    .with_voting(min_votes=3, use_weights=True)
    .with_confidence(min_threshold=0.3)
)

# Use with strategy
from detection_fusion.strategies import create_strategy
strategy = create_strategy("weighted_vote", config=config)

YAML Configuration

# configs/ensemble/default.yaml - Must match StrategyConfig Pydantic model
overlap:
  threshold: 0.5
  method: "iou"

voting:
  min_votes: 2
  use_weights: true

confidence:
  min_threshold: 0.1
  temperature: 1.0

extra: {}
# configs/gt_rectification/balanced.yaml - Must match RectificationConfig model
mode: "minimize_error"

paths:
  labels_dir: "labels"
  gt_dir: "GT"
  images_dir: "images"
  output_dir: "rectified_balanced"

thresholds:
  iou: 0.5
  confidence: 0.5
  min_agreement: 3

output:
  most_correct: 50
  most_incorrect: 50
  copy_images: true

Load configs via CLI or Python:

# Rectify supports --config option
detection-fusion rectify --config configs/gt_rectification/balanced.yaml

# Merge uses CLI options directly
detection-fusion merge -d labels/ -s weighted_vote -o unified/ --iou-threshold 0.5
from detection_fusion.config import ConfigLoader

# Load ensemble config for Python API
config = ConfigLoader.from_yaml("configs/ensemble/default.yaml")

# Load rectification config
rect_config = ConfigLoader.load_rectification("configs/gt_rectification/balanced.yaml")

Testing

# Run all tests
pytest

# With coverage
pytest --cov=detection_fusion --cov-report=html

# Run specific test file
pytest tests/strategies/test_registry.py -v

Development

# Install dev dependencies
pip install -e ".[dev]"

# Set up pre-commit hooks
make hooks

# Format and lint
make format
make lint

# Type checking
mypy detection_fusion

Citation

@software{detection_fusion,
  title={DetectionFusion: Object Detection Ensemble Toolkit},
  author={Sarkar, Abhik},
  year={2025},
  version={1.0.0},
  url={https://github.com/abhiksark/detection-fusion}
}

Contributing

Contributions are welcome! Please see CONTRIBUTING.md for guidelines.

Documentation

License

MIT License - see LICENSE for details.

Author

Abhik Sarkar - GitHub

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

detection_fusion-1.1.0.tar.gz (72.1 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

detection_fusion-1.1.0-py3-none-any.whl (91.6 kB view details)

Uploaded Python 3

File details

Details for the file detection_fusion-1.1.0.tar.gz.

File metadata

  • Download URL: detection_fusion-1.1.0.tar.gz
  • Upload date:
  • Size: 72.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for detection_fusion-1.1.0.tar.gz
Algorithm Hash digest
SHA256 6d34f8d3158bce87edbd6afe379f845a405cab1822fb4d7f1cad0969112a432d
MD5 c9eed704aac4db93f21bb69959137d8c
BLAKE2b-256 ae87a930189f981e77fb83bef74b932cab1753257e63cdd141433c87637e4ec6

See more details on using hashes here.

Provenance

The following attestation bundles were made for detection_fusion-1.1.0.tar.gz:

Publisher: ci.yaml on abhiksark/detection-fusion

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file detection_fusion-1.1.0-py3-none-any.whl.

File metadata

File hashes

Hashes for detection_fusion-1.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 64b8868019266a008eb07c4081a467e7a3138388cf2bed65379a7e1db86ace45
MD5 f792f648466c74f1bd0cf9c5c38d535f
BLAKE2b-256 c4df5975e49a6645eb3ef54b0d2fa2b23629c199cefb21a2eaf89f5d7fb9aef2

See more details on using hashes here.

Provenance

The following attestation bundles were made for detection_fusion-1.1.0-py3-none-any.whl:

Publisher: ci.yaml on abhiksark/detection-fusion

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page