Skip to content

Create prediction_visualizer.py#345

Draft
catsmells wants to merge 4 commits intoroboflow:developfrom
catsmells:patch-1
Draft

Create prediction_visualizer.py#345
catsmells wants to merge 4 commits intoroboflow:developfrom
catsmells:patch-1

Conversation

@catsmells
Copy link
Copy Markdown

Description

Added visualize_predictions.py to the RF-DETR repository (https://github.com/roboflow/rf-detr/tree/develop/rfdetr) to enable visualization of model predictions on sample images, improving user onboarding and debugging. The script loads a pre-trained RF-DETR model, runs inference on images in a specified directory, and saves annotated outputs with bounding boxes and labels using supervision. Motivation: enhance usability for developers testing RF-DETR performance. Dependencies: numpy, opencv-python, supervision, pillow, rfdetr.

Type of change

  • New feature (non-breaking change which adds functionality)
  • This change requires a documentation update

How has this change been tested, please provide a testcase or example of how you tested the change?

Tested by running python visualize_predictions.py --weights path/to/weights.pth --input-dir sample_images --output-dir output --confidence 0.5 with a COCO sample dataset. Verified annotated images in the output directory displayed correct bounding boxes and labels for detected objects.

Any specific deployment considerations

Requires pre-trained RF-DETR model weights and a directory with supported image formats (.jpg, .jpeg, .png). No additional costs or secrets required.

Docs

  • Docs updated? What were the changes:
    Added section for visualize_predictions.py, detailing usage, command-line arguments (--weights, --input-dir, --output-dir, --confidence), and example command: python visualize_predictions.py --weights weights.pth --input-dir images/ --output-dir output/.

I have read the CLA Document and I sign the CLA.

Adding testing visualizer.
@CLAassistant
Copy link
Copy Markdown

CLAassistant commented Sep 7, 2025

CLA assistant check
All committers have signed the CLA.

@catsmells
Copy link
Copy Markdown
Author

I have read the CLA Document and I sign the CLA.

@Borda Borda requested review from Copilot and removed request for isaacrob-roboflow March 23, 2026 21:13
@Borda Borda added the enhancement New feature or request label Mar 23, 2026
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds a helper script intended to visualize RF-DETR prediction outputs on local images to aid onboarding/debugging.

Changes:

  • Introduces a new prediction-visualization script that loads weights, runs RFDETRBase.predict() over a directory of images, and writes annotated images.
  • Implements basic CLI argument parsing for weights/input/output/confidence.

Comment on lines +1 to +8
# ------------------------------------------------------------------------
# RF-DETR
# Copyright (c) 2025 Roboflow. All Rights Reserved.
# Licensed under the Apache License, Version 2.0 [see LICENSE for details]
# ------------------------------------------------------------------------

import argparse
import os
Copy link

Copilot AI Mar 23, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This file is added under the top-level rfdetr/ directory, but the package is configured as a src/ layout ([tool.setuptools.packages.find] where = ["src"]), so rfdetr/util/prediction_visualizer.py will not be included in the installed distribution or importable via python -m rfdetr. If this is meant to be part of the library, it should live under src/rfdetr/...; if it’s meant to be a runnable helper script (as the PR description suggests), consider placing it in a scripts/ (or similar) directory and documenting that path instead. Also note the PR description references visualize_predictions.py, but this change introduces prediction_visualizer.py.

Copilot uses AI. Check for mistakes.
Comment on lines +7 to +15
import argparse
import os
from typing import List

import cv2
import numpy as np
import supervision as sv
from PIL import Image

Copy link

Copilot AI Mar 23, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This module imports cv2 at import time, but opencv-python is not a declared core dependency in pyproject.toml. If this file is moved under src/rfdetr (so it ships), importing it will raise ImportError in minimal installs and potentially in CI. Consider moving the cv2 dependency behind an optional import inside main()/save_annotated_image, or avoid OpenCV entirely (PIL can save NumPy arrays).

Copilot uses AI. Check for mistakes.
Comment on lines +19 to +47
def parse_args():
parser = argparse.ArgumentParser(description="Visualize RF-DETR predictions on sample images.")
parser.add_argument("--weights", type=str, required=True, help="Path to pre-trained RF-DETR model weights.")
parser.add_argument("--input-dir", type=str, required=True, help="Directory containing input images.")
parser.add_argument("--output-dir", type=str, default="output", help="Directory to save annotated images.")
parser.add_argument("--confidence", type=float, default=0.5, help="Confidence threshold for predictions.")
return parser.parse_args()


def load_images(input_dir: str) -> List[Image.Image]:
supported_extensions = (".jpg", ".jpeg", ".png")
return [
Image.open(os.path.join(input_dir, f))
for f in os.listdir(input_dir)
if f.lower().endswith(supported_extensions)
]


def save_annotated_image(image: Image.Image, detections: sv.Detections, output_path: str):
annotated_image = np.array(image)
annotated_image = sv.BoxAnnotator().annotate(annotated_image, detections)
labels = [f"{pred.class_name} {pred.confidence:.2f}" for pred in detections]
annotated_image = sv.LabelAnnotator().annotate(annotated_image, detections, labels)
cv2.imwrite(output_path, cv2.cvtColor(annotated_image, cv2.COLOR_RGB2BGR))


def main():
args = parse_args()

Copy link

Copilot AI Mar 23, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Several new functions are missing return type hints and docstrings (parse_args, save_annotated_image, main). The repository generally uses full typing + docstrings for functions; adding them here will keep this consistent and help downstream users understand expected types/behavior.

Copilot uses AI. Check for mistakes.
Comment on lines +30 to +34
return [
Image.open(os.path.join(input_dir, f))
for f in os.listdir(input_dir)
if f.lower().endswith(supported_extensions)
]
Copy link

Copilot AI Mar 23, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

load_images() returns PIL.Image objects in whatever mode the source file has (e.g. "RGBA", "L"). RFDETR.predict() expects RGB (3 channels) and will raise for non-3-channel images. Consider converting each loaded image to RGB (and forcing image data to be loaded so file handles don’t remain open).

Suggested change
return [
Image.open(os.path.join(input_dir, f))
for f in os.listdir(input_dir)
if f.lower().endswith(supported_extensions)
]
images: List[Image.Image] = []
for filename in os.listdir(input_dir):
if not filename.lower().endswith(supported_extensions):
continue
image_path = os.path.join(input_dir, filename)
with Image.open(image_path) as img:
rgb_image = img.convert("RGB")
rgb_image.load()
images.append(rgb_image)
return images

Copilot uses AI. Check for mistakes.
Comment on lines +37 to +42
def save_annotated_image(image: Image.Image, detections: sv.Detections, output_path: str):
annotated_image = np.array(image)
annotated_image = sv.BoxAnnotator().annotate(annotated_image, detections)
labels = [f"{pred.class_name} {pred.confidence:.2f}" for pred in detections]
annotated_image = sv.LabelAnnotator().annotate(annotated_image, detections, labels)
cv2.imwrite(output_path, cv2.cvtColor(annotated_image, cv2.COLOR_RGB2BGR))
Copy link

Copilot AI Mar 23, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

labels = [f"{pred.class_name} {pred.confidence:.2f}" for pred in detections] is unlikely to work with sv.Detections returned by RFDETR.predict(). That method constructs sv.Detections with class_id and confidence arrays (no class_name field), so this will raise at runtime or produce incorrect labels. Build labels from detections.class_id/detections.confidence and map class IDs via model.class_names if you want human-readable names.

Copilot uses AI. Check for mistakes.
Comment on lines +39 to +41
annotated_image = sv.BoxAnnotator().annotate(annotated_image, detections)
labels = [f"{pred.class_name} {pred.confidence:.2f}" for pred in detections]
annotated_image = sv.LabelAnnotator().annotate(annotated_image, detections, labels)
Copy link

Copilot AI Mar 23, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sv.BoxAnnotator().annotate(annotated_image, detections) and LabelAnnotator().annotate(annotated_image, detections, labels) are called positionally here, but in the codebase the supervision annotators are used with keyword arguments (scene=..., detections=..., labels=...). Using keywords avoids accidental argument-order mismatches across supervision versions and improves readability.

Suggested change
annotated_image = sv.BoxAnnotator().annotate(annotated_image, detections)
labels = [f"{pred.class_name} {pred.confidence:.2f}" for pred in detections]
annotated_image = sv.LabelAnnotator().annotate(annotated_image, detections, labels)
annotated_image = sv.BoxAnnotator().annotate(scene=annotated_image, detections=detections)
labels = [f"{pred.class_name} {pred.confidence:.2f}" for pred in detections]
annotated_image = sv.LabelAnnotator().annotate(scene=annotated_image, detections=detections, labels=labels)

Copilot uses AI. Check for mistakes.
@codecov
Copy link
Copy Markdown

codecov bot commented Mar 30, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 0%. Comparing base (f2b5d21) to head (3f86db3).
⚠️ Report is 17 commits behind head on develop.

❌ Your project check has failed because the head coverage (0%) is below the target coverage (95%). You can increase the head coverage or adjust the target coverage.

Additional details and impacted files
@@           Coverage Diff            @@
##           develop   #345     +/-   ##
========================================
- Coverage       76%      0    -76%     
========================================
  Files           97      0     -97     
  Lines         7368      0   -7368     
========================================
- Hits          5609      0   -5609     
+ Misses        1759      0   -1759     
🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@Borda Borda marked this pull request as draft March 30, 2026 13:05
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

enhancement New feature or request waiting on author

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants