Skip to content

Make OpenCV an optional dependency to support contrib variants#2139

Draft
Copilot wants to merge 11 commits intodevelopfrom
copilot/fix-opencv-dependency-issue
Draft

Make OpenCV an optional dependency to support contrib variants#2139
Copilot wants to merge 11 commits intodevelopfrom
copilot/fix-opencv-dependency-issue

Conversation

Copy link
Contributor

Copilot AI commented Feb 6, 2026

Summary

All tasks completed successfully!

This PR makes OpenCV an optional dependency for supervision, resolving the issue where opencv-python would override opencv-contrib-python.

Implementation Checklist

  • Remove opencv-python>=4.5.5.64 from main dependencies
  • Add optional dependency groups (headless, desktop, desktop-contrib, headless-contrib)
  • Update pyproject.toml with the new structure
  • Update README.md with installation instructions
  • Update docs/index.md with detailed installation instructions
  • Add changelog entry documenting the breaking change
  • Wrap all cv2 imports with try/except blocks
  • Add ensure_cv2_installed() function with helpful error messages
  • Add ensure_cv2_installed() calls to all functions/methods using cv2
  • Fix cv2 constants used at module level (CV2_FONT, FONT_HERSHEY_SIMPLEX)
  • Update CI workflows to install opencv-python-headless
  • Complete installation documentation for all package managers
  • Add warning about mutually exclusive OpenCV variants
  • Clarify runtime vs install-time dependency behavior
  • Test the changes
  • Run code review (no issues found)
  • Run CodeQL checker (no issues found)

Changes Made

1. Core dependency management

  • pyproject.toml: Removed opencv-python from core dependencies, added 4 optional extras
  • CI workflows: Updated ci-tests.yml and ci-build-docs.yml to install [headless] extra

2. Import wrapping (16 files)

All cv2 imports wrapped with try/except:

  • src/supervision/annotators/core.py
  • src/supervision/detection/line_zone.py
  • src/supervision/detection/tools/polygon_zone.py
  • src/supervision/detection/utils/polygons.py
  • src/supervision/detection/utils/masks.py
  • src/supervision/detection/utils/converters.py
  • src/supervision/detection/utils/internal.py
  • src/supervision/dataset/core.py
  • src/supervision/dataset/utils.py
  • src/supervision/dataset/formats/pascal_voc.py
  • src/supervision/draw/utils.py
  • src/supervision/key_points/annotators.py
  • src/supervision/utils/conversion.py
  • src/supervision/utils/image.py
  • src/supervision/utils/video.py
  • src/supervision/utils/notebook.py

3. Error handling

  • Added ensure_cv2_installed() function in utils/internal.py with installation instructions
  • Added ensure_cv2_installed() calls to all public functions/methods using cv2
  • Fixed cv2 constants used at module level (CV2_FONT → _get_cv2_font())
  • Fixed function default parameters (cv2.FONT_HERSHEY_SIMPLEX → None with lazy init)

4. Documentation

  • README.md: Installation instructions for each OpenCV variant
  • docs/index.md:
    • Comprehensive installation examples for pip, poetry, uv, and rye
    • All 4 OpenCV variants documented for each package manager
    • Warning about mutually exclusive OpenCV packages
  • docs/changelog.md:
    • Breaking change notice clarifying runtime vs install-time dependency
    • Clear explanation that OpenCV is still required to use the library

Testing

✅ Verified supervision can be imported without OpenCV installed
✅ Verified helpful ImportError raised when cv2 functions are called
✅ Verified full functionality works with opencv-python-headless installed
✅ Tested basic operations: pillow_to_cv2, cv2_to_pillow, Detections, BoxAnnotator

Installation Examples

# For servers (no GUI) - recommended
pip install supervision[headless]

# For desktop (with GUI)
pip install supervision[desktop]

# For desktop with extra modules (e.g., CSRT tracker)
pip install supervision[desktop-contrib]

# For servers with extra modules (no GUI)
pip install supervision[headless-contrib]

# If OpenCV already installed
pip install supervision

⚠️ Important: Only install one OpenCV variant at a time. The different opencv-python packages are mutually exclusive.

Original prompt

This section details on the original issue you should resolve

<issue_title>[Bug]: opencv-python dependency of supervision overrides opencv-contrib-python dependency</issue_title>
<issue_description>### Search before asking

  • I have searched the issues and discussions and found no similar bug report.

Bug

supervision package directly depends on opencv-python which means it's being included when installing supervision.
If your project depends on opencv-contrib-python as well then it will cause both opencv-python (as supervision dependency) and opencv-contrib-python to be downloaded.
And opencv-python will override opencv-contrib-python in that scenarion, which will remove access to extra modules from opencv-contrib-python.

Proposition to resolve it is to make opencv-python an optional dependency and another opencv-contrib-python optional dependency, so that user can choose which install.

Environment

  • Supervision: 0.27.0rc4
  • Python: 3.12
  • OS: Linux

Minimal Reproducible Example

In pyproject.toml add both dependencies:

dependencies = [
    "supervision==0.27.0rc4",
    "opencv-contrib-python-headless>=4.13.0.90",
]

And try to access extra CSRTTracker from contrib package:

import logging

import cv2

def main():
    logging.basicConfig(level=logging.INFO)
    logger = logging.getLogger(__name__)

    try:
        logger.info(f"OpenCV version: {cv2.__version__}")
        logger.info(f"OpenCV path: {cv2.__file__}")
        logger.info(cv2.getBuildInformation())
    except Exception as e:
        logger.error(f"Failed to get OpenCV version: {e}")
        return

    try:
        tracker = cv2.TrackerCSRT_create()
        logger.info("✓ CSRT tracker is available")
        logger.info(f"Tracker type: {type(tracker)}")
    except AttributeError:
        logger.error("✗ CSRT tracker not available - cv2.TrackerCSRT_create missing")
    except Exception as e:
        logger.error(f"✗ Failed to create CSRT tracker: {e}")

if __name__ == "__main__":
    main()

Are you willing to submit a PR?

  • Yes I'd like to help by submitting a PR!</issue_description>

Comments on the Issue (you are @copilot in this section)


💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more Copilot coding agent tips in the docs.

Copilot AI and others added 2 commits February 6, 2026 11:57
Co-authored-by: Borda <6035284+Borda@users.noreply.github.com>
Co-authored-by: Borda <6035284+Borda@users.noreply.github.com>
Copilot AI changed the title [WIP] Fix opencv-python dependency override in supervision Make OpenCV an optional dependency to support contrib variants Feb 6, 2026
Copilot AI requested a review from Borda February 6, 2026 12:04
@Borda Borda added the dependencies Pull requests that update a dependency file label Feb 6, 2026
@Borda Borda requested a review from Copilot February 6, 2026 12:08
Copy link
Member

@Borda Borda left a comment

Choose a reason for hiding this comment

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

@copilot, you need to reflect the base dep. drop and move to extra in CI so to also install it there and in the code path all cv2 imports with try/except and raise relevant message what is missing and what to add, in case it is not critical to use it in the module, move the imports to local in class or function
Also, reconsider if some of the cv2 functions can be replaced with other base dependencies, for example, read image can be used from matplotlib.pyplot.imread, etc.

Copy link
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

This PR addresses issue #2114 by making OpenCV an optional install-time dependency to support different OpenCV variants (standard, contrib, headless) and prevent conflicts. Previously, supervision depended on opencv-python, which would override opencv-contrib-python when both were installed, preventing access to contrib modules like CSRT tracker.

Changes:

  • Removed opencv-python from core dependencies in pyproject.toml
  • Added 4 optional extras for different OpenCV variants: headless, desktop, desktop-contrib, headless-contrib
  • Updated installation documentation in README.md, docs/index.md, and docs/changelog.md to explain the new installation options and document the breaking change

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 7 comments.

File Description
pyproject.toml Removed opencv-python from core dependencies and added 4 optional extras for different OpenCV variants
README.md Added installation instructions for choosing OpenCV variants and clarified that OpenCV is required
docs/index.md Added comprehensive installation instructions across pip, poetry, uv, and rye for different OpenCV variants
docs/changelog.md Documented the breaking change with migration instructions for version 0.28.0rc0

Comment on lines 103 to 112
```bash
uv pip install supervision
# With headless OpenCV (recommended for servers)
uv pip install supervision[headless]
```

For uv projects:

```bash
uv add supervision
uv add supervision --extra headless
```
Copy link

Copilot AI Feb 6, 2026

Choose a reason for hiding this comment

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

The uv installation instructions are incomplete compared to the pip section. The pip section shows all four OpenCV variants with descriptive comments, but the uv section only shows the headless variant. For consistency and to help users make informed choices, add the other variants:

# For desktop applications (includes GUI support)
uv pip install supervision[desktop]
# For desktop with extra modules (e.g., CSRT tracker)
uv pip install supervision[desktop-contrib]
# For servers with extra modules (no GUI)
uv pip install supervision[headless-contrib]

Also add: "If you already have OpenCV installed: uv pip install supervision"

Copilot uses AI. Check for mistakes.
Copy link
Member

Choose a reason for hiding this comment

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

@copilot apply changes based on this feedback

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done in commit 2b67b3d. Added all 4 OpenCV variants to the uv installation section with descriptive comments, plus instructions for when OpenCV is already installed.

Comment on lines 121 to 123
```bash
rye add supervision
rye add supervision --features headless
```
Copy link

Copilot AI Feb 6, 2026

Choose a reason for hiding this comment

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

The rye installation instructions are incomplete compared to other installation methods. Only the headless variant is shown. For consistency and to help users make informed choices, add examples for the other variants:

# For desktop applications (includes GUI support)
rye add supervision --features desktop
# For desktop with extra modules (e.g., CSRT tracker)
rye add supervision --features desktop-contrib
# For servers with extra modules (no GUI)
rye add supervision --features headless-contrib

Copilot uses AI. Check for mistakes.
Copy link
Member

Choose a reason for hiding this comment

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

@copilot apply changes based on this feedback

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done in commit 2b67b3d. Added all 4 OpenCV variants to the rye installation section with descriptive comments matching the other package managers.

Comment on lines 5 to 15
!!! breaking "Breaking Change"
**OpenCV is now an optional dependency.** To ensure compatibility with different OpenCV variants (standard, contrib, headless), `opencv-python` has been removed from the core dependencies. Users must now explicitly choose their preferred OpenCV package:

- `pip install supervision[headless]` - Installs `opencv-python-headless` (recommended for servers)
- `pip install supervision[desktop]` - Installs `opencv-python` (includes GUI support)
- `pip install supervision[desktop-contrib]` - Installs `opencv-contrib-python` (extra modules + GUI)
- `pip install supervision[headless-contrib]` - Installs `opencv-contrib-python-headless` (extra modules, no GUI)

If you already have OpenCV installed, you can install supervision without extras: `pip install supervision`

This change resolves conflicts where `opencv-python` would override `opencv-contrib-python`, preventing access to extra modules like CSRT tracker.
Copy link

Copilot AI Feb 6, 2026

Choose a reason for hiding this comment

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

The breaking change notice should clarify the runtime behavior more explicitly. Currently it states "OpenCV is now an optional dependency" which could be interpreted as "supervision works without OpenCV."

Consider rephrasing to be more explicit about the requirement:

"OpenCV is required at runtime but is now an optional install-time dependency. To ensure compatibility with different OpenCV variants (standard, contrib, headless), opencv-python has been removed from the core dependencies. Users must now have OpenCV installed either by:

  • Explicitly choosing an OpenCV extra when installing supervision (recommended)
  • Having a compatible OpenCV package already installed

Without OpenCV installed, import supervision will fail with an ImportError."

This makes it clear that OpenCV is still required to use the library, just not automatically installed.

Copilot uses AI. Check for mistakes.
Copy link
Member

Choose a reason for hiding this comment

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

@copilot apply changes based on this feedback

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done in commit 2b67b3d. Clarified that "OpenCV is required at runtime but is now an optional install-time dependency" and added a note explaining that functions will raise ImportError without OpenCV installed. This makes it clear OpenCV is still required to use the library.

Comment on lines 51 to 77
Supervision requires OpenCV. Choose the variant that best fits your needs:

```bash
# Recommended for servers (no GUI)
pip install supervision[headless]
```

```bash
# For desktop applications (includes GUI support)
pip install supervision[desktop]
```

```bash
# For desktop with extra modules (e.g., CSRT tracker)
pip install supervision[desktop-contrib]
```

```bash
# For servers with extra modules (no GUI)
pip install supervision[headless-contrib]
```

If you already have OpenCV installed:

```bash
pip install supervision
```
Copy link

Copilot AI Feb 6, 2026

Choose a reason for hiding this comment

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

Consider adding a warning in the installation documentation that users should only install ONE OpenCV variant at a time. The different opencv-python packages are mutually exclusive and installing multiple extras that include different OpenCV variants will cause conflicts.

For example, add a note like:
"⚠️ Important: Only install one OpenCV variant at a time. The different opencv-python packages (standard, contrib, headless, etc.) are mutually exclusive and cannot coexist in the same environment."

Copilot uses AI. Check for mistakes.
Copy link
Member

Choose a reason for hiding this comment

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

@copilot apply changes based on this feedback

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Done in commit 2b67b3d. Added warning in the pip installation section:

⚠️ Important: Only install one OpenCV variant at a time. The different opencv-python packages (standard, contrib, headless, etc.) are mutually exclusive and cannot coexist in the same environment.

Copilot AI and others added 2 commits February 6, 2026 12:24
…alls

- Wrapped import cv2 with try/except in 16 files across detection, dataset, key_points, draw, and utils modules
- Added ensure_cv2_installed() import and calls to all __init__ methods, public functions, and classmethods that use cv2
- Follows pattern established in utils/internal.py, conversion.py, video.py, and image.py
- Files updated: line_zone.py, polygon_zone.py, polygons.py, masks.py, converters.py, internal.py, dataset/core.py, dataset/utils.py, pascal_voc.py, key_points/annotators.py, draw/utils.py, utils/notebook.py
- All files compile successfully with py_compile

Co-authored-by: Borda <6035284+Borda@users.noreply.github.com>
Co-authored-by: Borda <6035284+Borda@users.noreply.github.com>
Copy link
Contributor Author

Copilot AI commented Feb 6, 2026

@copilot, you need to reflect the base dep. drop and move to extra in CI so to also install it there and in the code path all cv2 imports with try/except and raise relevant message what is missing a...

Done in commits b4b3422 and b7aba15:

CI workflows updated - Added --extra headless to ci-tests.yml and ci-build-docs.yml

All cv2 imports wrapped - 16 files updated with try/except blocks and ensure_cv2_installed() calls with helpful error messages

Module-level cv2 constants fixed - Replaced CV2_FONT = cv2.FONT_HERSHEY_SIMPLEX with lazy _get_cv2_font() function, fixed function default parameters

The package now:

  • ✅ Imports successfully without OpenCV installed
  • ✅ Raises clear ImportError with installation instructions when cv2 functions are called
  • ✅ Works fully when installed with any OpenCV variant

Regarding replacing cv2 functions with base dependencies: Most cv2 usage is for core functionality (image processing, video I/O, drawing) that doesn't have direct equivalents in matplotlib. The cv2.imread in examples/docstrings don't need changes as they're just documentation.

Copilot AI requested a review from Borda February 6, 2026 12:30
@codecov
Copy link

codecov bot commented Feb 6, 2026

Codecov Report

❌ Patch coverage is 63.56589% with 47 lines in your changes missing coverage. Please review.
✅ Project coverage is 72%. Comparing base (cd0aac2) to head (b7aba15).
⚠️ Report is 3 commits behind head on develop.

❌ Your patch check has failed because the patch coverage (64%) is below the target coverage (95%). You can increase the patch coverage or adjust the target coverage.
❌ Your project check has failed because the head coverage (72%) 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   #2139    +/-   ##
========================================
- Coverage       72%     72%    -0%     
========================================
  Files           61      61            
  Lines         7249    7359   +110     
========================================
+ Hits          5246    5309    +63     
- Misses        2003    2050    +47     
🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

Borda and others added 3 commits February 12, 2026 19:01
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
@Borda
Copy link
Member

Borda commented Feb 12, 2026

@copilot, overall, the nesure method seems overengineering, what about just local imports?

…ntime behavior

Co-authored-by: Borda <6035284+Borda@users.noreply.github.com>
Copy link
Contributor Author

Copilot AI commented Feb 12, 2026

@copilot, overall, the nesure method seems overengineering, what about just local imports?

The ensure_cv2_installed() approach provides helpful error messages with installation instructions (showing all 4 extras options). With just local imports, users would only get Python's default ModuleNotFoundError: No module named 'cv2' without guidance on how to install it.

Should I simplify to local imports and remove the helper function, accepting less helpful error messages? Or keep the current approach for better UX?

Current error:

ImportError: OpenCV is required but not installed. 
Install supervision with one of the following options:
  pip install supervision[headless]           # For servers (no GUI)
  pip install supervision[desktop]            # For desktop (with GUI)
  ...

vs. simplified error:

ModuleNotFoundError: No module named 'cv2'

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

dependencies Pull requests that update a dependency file

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: opencv-python dependency of supervision overrides opencv-contrib-python dependency

2 participants