Skip to content

Add YOLO OD inference plugin - #12

Merged
LeonardoRosaa merged 15 commits into
mainfrom
yolo-implementation
Jun 24, 2026
Merged

Add YOLO OD inference plugin#12
LeonardoRosaa merged 15 commits into
mainfrom
yolo-implementation

Conversation

@LeonardoRosaa

@LeonardoRosaa LeonardoRosaa commented Jun 23, 2026

Copy link
Copy Markdown
Contributor

What has changed and why?

Adds a YOLO object detection plugin.

How has it been tested?

Manual testing.

You can also install it locally:

pip install git+https://github.com/lightly-ai/lightly-studio-plugins.git@yolo-implementation#subdirectory=plugins/yolo_object_detection/

Did you update Readme.md and plugins.toml?

  • Yes
  • Not needed

YOLO Object Detection Plugin

Adds a new YOLO object detection inference plugin (lightly_plugins_yolo_object_detection) to lightly-studio-plugins.

  • Registers the plugin in plugins.toml (source = local:plugins/yolo_object_detection) and adds docs to the main README.md and plugins/yolo_object_detection/README.md.
  • Introduces YoloObjectDetectionOperator that runs Ultralytics YOLO inference on image samples in the current view/filter and writes bounding box annotations.
    • Parameters: model_path (default yolov8n.pt), confidence (default 0.25, validated to [0, 1]), and optional annotation_source (stripped; defaults to yolo_auto_label__{model_path}).
    • Ensures the target label/collection exists by creating missing annotation labels for each YOLO class and mapping YOLO class indices to label IDs.
    • Batches annotation writes (_WRITE_BATCH_SIZE = 100) via annotation_resolver.create_many, and returns a “No samples found…” message when applicable.
  • Adds supporting plugin packaging/build files:
    • plugins/yolo_object_detection/pyproject.toml (package metadata, dependencies lightly_studio>=1.0.0, sqlmodel, ultralytics, and the operator entry point)
    • plugins/yolo_object_detection/Makefile (install, format, type-check)
    • Apache 2.0 LICENSE
  • Documented install command:
    • pip install git+https://github.com/lightly-ai/lightly-studio-plugins.git#subdirectory=plugins/yolo_object_detection/

@coderabbitai

coderabbitai Bot commented Jun 23, 2026

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@LeonardoRosaa, we couldn't start this review because you've reached your PR review rate limit.

More reviews will be available in 54 minutes and 29 seconds. Learn how PR review limits work.

Your organization has used up its prepaid credits, and credit purchases are no longer available. Enable the review add-on in the billing tab to keep reviews running — you're only billed for reviews past your plan's rate limits ($0.25/file).

⌛ How to resolve this issue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based credits.

🚦 How do rate limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please see our Fair Usage Limits Policy for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 03ae2da7-025e-41bb-ac89-4ebcc71b1936

📥 Commits

Reviewing files that changed from the base of the PR and between edbc55c and 4b31b2d.

📒 Files selected for processing (1)
  • plugins/yolo_object_detection/src/lightly_plugins_yolo_object_detection/operator.py
📝 Walkthrough

Walkthrough

A new YOLO object detection plugin package is added, along with its registry entry, packaging metadata, documentation, and an operator that runs YOLO inference and writes bounding-box annotations.

Changes

YOLO Object Detection Plugin

Layer / File(s) Summary
Package registration and scaffolding
plugins.toml, plugins/yolo_object_detection/pyproject.toml, plugins/yolo_object_detection/Makefile, plugins/yolo_object_detection/LICENSE, plugins/yolo_object_detection/src/lightly_plugins_yolo_object_detection/__init__.py, plugins/yolo_object_detection/README.md, README.md
Adds the plugin registry entry, package metadata and entry point, build and development targets, license text, package docstring, and plugin/user-facing documentation.
YoloObjectDetectionOperator implementation
plugins/yolo_object_detection/src/lightly_plugins_yolo_object_detection/operator.py
Defines the operator parameters and scope, loads the YOLO model, resolves image samples, maps YOLO classes to annotation labels, creates bounding-box annotations, and persists them in batches.

Sequence Diagram(s)

sequenceDiagram
  participant Lightly Studio
  participant YoloObjectDetectionOperator
  participant YOLO
  participant annotation_resolver

  Lightly Studio->>YoloObjectDetectionOperator: execute(session, context, parameters)
  YoloObjectDetectionOperator->>YOLO: load model_path
  loop per image sample
    YoloObjectDetectionOperator->>YOLO: predict(image, conf=confidence)
    YOLO-->>YoloObjectDetectionOperator: boxes with class, xywh, conf
  end
  YoloObjectDetectionOperator->>annotation_resolver: create_many(annotations, collection_name)
  annotation_resolver-->>YoloObjectDetectionOperator: persisted annotations
  YoloObjectDetectionOperator-->>Lightly Studio: OperatorResult
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Suggested reviewers

  • michal-lightly
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title is concise and accurately summarizes the main change: adding a YOLO object detection inference plugin.
Description check ✅ Passed The description covers the change, testing, a reproducible install command, and confirms README and plugins.toml updates.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch yolo-implementation

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@CLAassistant

CLAassistant commented Jun 23, 2026

Copy link
Copy Markdown

CLA assistant check
All committers have signed the CLA.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 3

🧹 Nitpick comments (1)
plugins/yolo_object_detection/Makefile (1)

1-13: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Add standard all, clean, and test targets to satisfy Makefile conventions.

This file currently misses targets flagged by checkmake; adding thin wrappers keeps lint/tools happy and improves developer ergonomics.

Suggested refactor
 .PHONY: install format type-check
+.PHONY: all clean test

+all: install
+
 install:
 	uv venv
 	uv pip install -r ../../dev-requirements.txt
 	uv pip install -e .
@@
 type-check:
 	uv run mypy --config-file ../../mypy.ini .
+
+test:
+	uv run pytest
+
+clean:
+	rm -rf .venv .mypy_cache .ruff_cache
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@plugins/yolo_object_detection/Makefile` around lines 1 - 13, Add the standard
Makefile targets `all`, `clean`, and `test` to comply with Makefile conventions.
Update the `.PHONY` declaration at the top to include all, clean, and test
targets. Create an all target that runs install, format, and type-check in
sequence. Create a clean target that removes build artifacts and virtual
environment files. Create a test target that runs any available test suite or
coordinate existing validation targets. These thin wrapper targets will satisfy
checkmake requirements and improve developer ergonomics.

Source: Linters/SAST tools

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In
`@plugins/yolo_object_detection/src/lightly_plugins_yolo_object_detection/operator.py`:
- Around line 124-133: The bounding box dimensions (width and height) are being
rounded but not clamped, which can result in zero values for very small boxes
when passed to AnnotationCreate. After rounding the w and h values in the
bounding box extraction logic near the AnnotationCreate call, clamp both the
rounded width and height to ensure they have a minimum value of 1 to prevent
zero-area annotations from being persisted.
- Around line 116-143: The code accumulates all annotations from all samples in
a single annotations_to_create list before writing them to the database, which
can consume excessive memory on large datasets. Instead of collecting all
annotations in one list throughout the entire loop over samples, implement
chunked writes by writing annotations to the database after processing a
reasonable batch size (for example, every N samples or every N annotations),
then clearing the annotations_to_create list and continuing. This approach will
reduce peak memory usage and enable earlier database writes by calling
annotation_resolver.create_many at intervals rather than waiting until all
samples are processed.
- Around line 81-83: The operator lacks exception handling for three critical
failure points that currently crash instead of returning a controlled
OperatorResult. First, wrap the float() conversion for PARAM_CONFIDENCE with a
try-except block to handle non-numeric confidence values gracefully. Second,
wrap the YOLO() model loading call with a try-except block to catch model
resolution failures like HUBModelError or FileNotFoundError. Third, wrap the
inference call around line 118 with a try-except block to handle file read
failures or corrupted image data. For each failure point, log an appropriate
error message and return an OperatorResult with failure status instead of
allowing the exception to propagate and crash the operator.

---

Nitpick comments:
In `@plugins/yolo_object_detection/Makefile`:
- Around line 1-13: Add the standard Makefile targets `all`, `clean`, and `test`
to comply with Makefile conventions. Update the `.PHONY` declaration at the top
to include all, clean, and test targets. Create an all target that runs install,
format, and type-check in sequence. Create a clean target that removes build
artifacts and virtual environment files. Create a test target that runs any
available test suite or coordinate existing validation targets. These thin
wrapper targets will satisfy checkmake requirements and improve developer
ergonomics.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 9081da59-c23d-4503-baa4-27ad7873be9b

📥 Commits

Reviewing files that changed from the base of the PR and between 4c01686 and ab06805.

📒 Files selected for processing (6)
  • plugins.toml
  • plugins/yolo_object_detection/LICENSE
  • plugins/yolo_object_detection/Makefile
  • plugins/yolo_object_detection/pyproject.toml
  • plugins/yolo_object_detection/src/lightly_plugins_yolo_object_detection/__init__.py
  • plugins/yolo_object_detection/src/lightly_plugins_yolo_object_detection/operator.py

@LeonardoRosaa

Copy link
Copy Markdown
Contributor Author

/review

@JonasWurst JonasWurst left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Lets give the user the option to define the source

Comment thread plugins/yolo_object_detection/README.md Outdated
Comment thread plugins/yolo_object_detection/README.md Outdated
Comment thread plugins/yolo_object_detection/pyproject.toml Outdated

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
plugins/yolo_object_detection/src/lightly_plugins_yolo_object_detection/operator.py (1)

111-115: 🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

Defer label creation until after confirming samples exist.

_get_or_create_label_map() is invoked before the no-samples early return, so an empty view can still create YOLO class labels in the dataset and then return “No samples found”. This is an unintended data mutation path.

Proposed fix
-        label_map = _get_or_create_label_map(
-            session=session,
-            root_collection_id=context.collection_id,
-            class_map=model.names,
-        )
-
         context_filter = None
@@
         samples = list(samples_result.samples)
         if not samples:
             return OperatorResult(
                 success=True,
                 message="No samples found for current view.",
             )
+
+        label_map = _get_or_create_label_map(
+            session=session,
+            root_collection_id=context.collection_id,
+            class_map=model.names,
+        )

Also applies to: 130-134

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@plugins/yolo_object_detection/src/lightly_plugins_yolo_object_detection/operator.py`
around lines 111 - 115, Move the _get_or_create_label_map() call in operator.py
so it runs only after the no-samples check has passed, using the existing YOLO
operator flow around the sample-query/early-return logic. Update the relevant
paths in the main execution method so empty views return “No samples found”
before any label_map creation or writes happen, preventing label mutations when
there are no samples. If the same pattern appears in the other affected block,
apply the same reordering there as well.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In
`@plugins/yolo_object_detection/src/lightly_plugins_yolo_object_detection/operator.py`:
- Around line 92-94: The collection name assignment in operator.py currently
calls str(parameters.get(...)) directly, which can turn missing or blank
annotation_source values into unintended names like "None" or empty strings.
Update the collection_name logic in the operator’s parameter handling to read
annotation_source first, trim/normalize it, and only then convert or fall back
to the default yolo_auto_label__{model_path} value when the result is empty or
missing.

---

Outside diff comments:
In
`@plugins/yolo_object_detection/src/lightly_plugins_yolo_object_detection/operator.py`:
- Around line 111-115: Move the _get_or_create_label_map() call in operator.py
so it runs only after the no-samples check has passed, using the existing YOLO
operator flow around the sample-query/early-return logic. Update the relevant
paths in the main execution method so empty views return “No samples found”
before any label_map creation or writes happen, preventing label mutations when
there are no samples. If the same pattern appears in the other affected block,
apply the same reordering there as well.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: b125d247-f966-4ba8-8623-1ab8d18af3a9

📥 Commits

Reviewing files that changed from the base of the PR and between ab06805 and ebced94.

📒 Files selected for processing (4)
  • README.md
  • plugins/yolo_object_detection/README.md
  • plugins/yolo_object_detection/pyproject.toml
  • plugins/yolo_object_detection/src/lightly_plugins_yolo_object_detection/operator.py
✅ Files skipped from review due to trivial changes (2)
  • plugins/yolo_object_detection/README.md
  • plugins/yolo_object_detection/pyproject.toml

@LeonardoRosaa
LeonardoRosaa merged commit f0ba60b into main Jun 24, 2026
8 checks passed
@LeonardoRosaa
LeonardoRosaa deleted the yolo-implementation branch June 24, 2026 15:23
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants