Compare commits

...
506 Commits
Author SHA1 Message Date
Piotr Skalski 55f93a85b6 Merge pull request #991 from roboflow/develop
`supervision-0.19.0` release
2024-03-15 11:15:24 +01:00
SkalskiP a0f7bb76bd bump version from 0.19.0rc5 to 0.19.0 2024-03-15 11:10:01 +01:00
Piotr Skalski 7e72ad13f7 Merge pull request #1000 from roboflow/0.19.0-changelog
`supervision-0.19.0` release changelog
2024-03-15 10:59:31 +01:00
Piotr Skalski 5b6713f197 Merge pull request #996 from roboflow/fix/doc_syntax_fix
doc: 📚 json and csv example code syntax fix
2024-03-15 10:59:08 +01:00
SkalskiP 8d7f18cc22 supervision-0.19.0 release changelog 2024-03-15 10:48:01 +01:00
Onuralp SEZER 012ff2bbe2 Merge pull request #997 from roboflow/dependabot/pip/notebook-7.1.2
⬆️ Bump notebook from 7.1.1 to 7.1.2
2024-03-15 11:20:11 +03:00
dependabot[bot] 594c9958a4 ⬆️ Bump notebook from 7.1.1 to 7.1.2
Bumps [notebook](https://github.com/jupyter/notebook) from 7.1.1 to 7.1.2.
- [Release notes](https://github.com/jupyter/notebook/releases)
- [Changelog](https://github.com/jupyter/notebook/blob/main/CHANGELOG.md)
- [Commits](https://github.com/jupyter/notebook/compare/@jupyter-notebook/tree@7.1.1...@jupyter-notebook/tree@7.1.2)

---
updated-dependencies:
- dependency-name: notebook
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-03-15 00:57:18 +00:00
Onuralp SEZER 917b4c0fe4 doc: 📚 json and csv example code syntax fix
Signed-off-by: Onuralp SEZER <thunderbirdtr@gmail.com>
2024-03-14 22:33:30 +03:00
Piotr Skalski d669619f2d Merge pull request #888 from xaristeidou/develop
Add `sv.CropAnnotator` which annotates a cropped part of detections
2024-03-14 14:47:43 +01:00
SkalskiP 22d97b8a46 add CropAnnotator docs 2024-03-14 14:43:19 +01:00
SkalskiP 0c04647d00 Improved docstrings 2024-03-14 14:37:26 +01:00
pre-commit-ci[bot] d6589443d7 fix(pre_commit): 🎨 auto format pre-commit hooks 2024-03-14 13:13:09 +00:00
SkalskiP 4ba3780d86 CropAnnotator updates and fixes 2024-03-14 14:12:50 +01:00
pre-commit-ci[bot] d1003d420c fix(pre_commit): 🎨 auto format pre-commit hooks 2024-03-14 12:33:18 +00:00
SkalskiP c7a6b38275 initial version of refactored CropAnnotator 2024-03-14 13:32:52 +01:00
Onuralp SEZER 0d352bde92 Merge pull request #913 from stellasphere/develop
Add occupancy analytics cookbook
2024-03-14 14:31:17 +03:00
Onuralp SEZER 4a6c0a9fa3 fix: 🐞 dirty outputs are removed and formatting fix
Signed-off-by: Onuralp SEZER <thunderbirdtr@gmail.com>
2024-03-14 14:28:28 +03:00
Onuralp SEZER 423783a8ff Merge branch 'develop' into develop 2024-03-14 14:08:38 +03:00
Piotr Skalski 162a4828e8 Merge pull request #970 from roboflow/config/ruff
ci: 👷 update ruff config and group lint
2024-03-14 11:35:52 +01:00
Piotr Skalski 0b810817e3 Merge pull request #969 from roboflow/fix/depricated
fix: 🐞 update PolygonZone test and update traffic-analysis depricated codes are updated
2024-03-13 14:26:28 +01:00
SkalskiP 6ade84f057 Updated deprecated.md to include deprecations introduced in the supervision-0.19.0 release. 2024-03-13 13:47:39 +01:00
Piotr Skalski 655e5a7709 Merge pull request #994 from roboflow/fix/993_ImageDetectionPrediction_object_is_not_subscriptable
Fix for #993 TypeError: 'ImageDetectionPrediction' object is not subscriptable
2024-03-13 11:10:59 +01:00
pre-commit-ci[bot] dfb52633dc fix(pre_commit): 🎨 auto format pre-commit hooks 2024-03-13 10:08:31 +00:00
SkalskiP bc74e1c366 added the same fix to quickstart.ipynb 2024-03-13 11:08:13 +01:00
pre-commit-ci[bot] aacad59fd9 fix(pre_commit): 🎨 auto format pre-commit hooks 2024-03-13 10:04:09 +00:00
SkalskiP 879d48048c ready for review 2024-03-13 11:02:11 +01:00
Onuralp SEZER c0c346b04b Merge pull request #992 from roboflow/pre-commit-ci-update-config
chore(pre_commit): ⬆ pre_commit autoupdate
2024-03-12 23:45:08 +03:00
pre-commit-ci[bot] 8ea1148f75 fix(pre_commit): 🎨 auto format pre-commit hooks 2024-03-12 20:30:21 +00:00
pre-commit-ci[bot] 2c55d1796f chore(pre_commit): ⬆ pre_commit autoupdate
updates:
- [github.com/PyCQA/bandit: 1.7.7 → 1.7.8](https://github.com/PyCQA/bandit/compare/1.7.7...1.7.8)
- [github.com/astral-sh/ruff-pre-commit: v0.2.2 → v0.3.2](https://github.com/astral-sh/ruff-pre-commit/compare/v0.2.2...v0.3.2)
2024-03-12 20:30:09 +00:00
Onuralp SEZER b68e7c2059 Merge pull request #989 from roboflow/dependabot/pip/wheel-0.43.0
⬆️ Bump wheel from 0.42.0 to 0.43.0
2024-03-12 05:32:31 +03:00
dependabot[bot] 4c426f5e82 ⬆️ Bump wheel from 0.42.0 to 0.43.0
Bumps [wheel](https://github.com/pypa/wheel) from 0.42.0 to 0.43.0.
- [Release notes](https://github.com/pypa/wheel/releases)
- [Changelog](https://github.com/pypa/wheel/blob/main/docs/news.rst)
- [Commits](https://github.com/pypa/wheel/compare/0.42.0...0.43.0)

---
updated-dependencies:
- dependency-name: wheel
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-03-12 00:23:55 +00:00
Onuralp SEZER fb82d32355 Merge pull request #987 from roboflow/dependabot/pip/pytest-8.1.1
⬆️ Bump pytest from 8.1.0 to 8.1.1
2024-03-11 04:07:33 +03:00
Onuralp SEZER fd6cf36685 Merge pull request #986 from roboflow/dependabot/pip/mypy-1.9.0
⬆️ Bump mypy from 1.8.0 to 1.9.0
2024-03-11 04:07:18 +03:00
Onuralp SEZER f41781015e Merge pull request #985 from roboflow/dependabot/pip/ruff-0.3.2
⬆️ Bump ruff from 0.3.1 to 0.3.2
2024-03-11 04:07:05 +03:00
dependabot[bot] b85222690b ⬆️ Bump pytest from 8.1.0 to 8.1.1
Bumps [pytest](https://github.com/pytest-dev/pytest) from 8.1.0 to 8.1.1.
- [Release notes](https://github.com/pytest-dev/pytest/releases)
- [Changelog](https://github.com/pytest-dev/pytest/blob/main/CHANGELOG.rst)
- [Commits](https://github.com/pytest-dev/pytest/compare/8.1.0...8.1.1)

---
updated-dependencies:
- dependency-name: pytest
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-03-11 01:01:54 +00:00
dependabot[bot] 8ef3c0eb00 ⬆️ Bump mypy from 1.8.0 to 1.9.0
Bumps [mypy](https://github.com/python/mypy) from 1.8.0 to 1.9.0.
- [Changelog](https://github.com/python/mypy/blob/master/CHANGELOG.md)
- [Commits](https://github.com/python/mypy/compare/v1.8.0...1.9.0)

---
updated-dependencies:
- dependency-name: mypy
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-03-11 00:59:37 +00:00
dependabot[bot] 645a1ec7af ⬆️ Bump ruff from 0.3.1 to 0.3.2
Bumps [ruff](https://github.com/astral-sh/ruff) from 0.3.1 to 0.3.2.
- [Release notes](https://github.com/astral-sh/ruff/releases)
- [Changelog](https://github.com/astral-sh/ruff/blob/main/CHANGELOG.md)
- [Commits](https://github.com/astral-sh/ruff/compare/v0.3.1...v0.3.2)

---
updated-dependencies:
- dependency-name: ruff
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-03-11 00:52:12 +00:00
Piotr Skalski cadb259214 Merge pull request #980 from roboflow/add-retention
Script updates
2024-03-07 14:22:35 +00:00
James 26de63a09a Update main.html 2024-03-07 14:19:42 +00:00
Onuralp SEZER b38234babe Merge pull request #979 from roboflow/dependabot/pip/ruff-0.3.1
⬆️ Bump ruff from 0.3.0 to 0.3.1
2024-03-07 04:46:06 +03:00
Onuralp SEZER 26201862f1 Merge pull request #978 from roboflow/dependabot/pip/mkdocs-material-9.5.13
⬆️ Bump mkdocs-material from 9.5.12 to 9.5.13
2024-03-07 04:22:31 +03:00
dependabot[bot] c6f0b5753a ⬆️ Bump ruff from 0.3.0 to 0.3.1
Bumps [ruff](https://github.com/astral-sh/ruff) from 0.3.0 to 0.3.1.
- [Release notes](https://github.com/astral-sh/ruff/releases)
- [Changelog](https://github.com/astral-sh/ruff/blob/main/CHANGELOG.md)
- [Commits](https://github.com/astral-sh/ruff/compare/v0.3.0...v0.3.1)

---
updated-dependencies:
- dependency-name: ruff
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-03-07 00:46:53 +00:00
Onuralp SEZER 427c91baa6 Merge pull request #977 from roboflow/dependabot/pip/tox-4.14.1
⬆️ Bump tox from 4.14.0 to 4.14.1
2024-03-07 03:45:22 +03:00
dependabot[bot] dc39852a5b ⬆️ Bump mkdocs-material from 9.5.12 to 9.5.13
Bumps [mkdocs-material](https://github.com/squidfunk/mkdocs-material) from 9.5.12 to 9.5.13.
- [Release notes](https://github.com/squidfunk/mkdocs-material/releases)
- [Changelog](https://github.com/squidfunk/mkdocs-material/blob/master/CHANGELOG)
- [Commits](https://github.com/squidfunk/mkdocs-material/compare/9.5.12...9.5.13)

---
updated-dependencies:
- dependency-name: mkdocs-material
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-03-07 00:44:39 +00:00
dependabot[bot] 52a059ffd9 ⬆️ Bump tox from 4.14.0 to 4.14.1
Bumps [tox](https://github.com/tox-dev/tox) from 4.14.0 to 4.14.1.
- [Release notes](https://github.com/tox-dev/tox/releases)
- [Changelog](https://github.com/tox-dev/tox/blob/main/docs/changelog.rst)
- [Commits](https://github.com/tox-dev/tox/compare/4.14.0...4.14.1)

---
updated-dependencies:
- dependency-name: tox
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-03-07 00:42:57 +00:00
Onuralp SEZER 8900986775 Merge pull request #976 from roboflow/dependabot/pip/tox-4.14.0
⬆️ Bump tox from 4.13.0 to 4.14.0
2024-03-06 16:56:11 +03:00
Piotr Skalski 4abef15069 Update README.md 2024-03-06 11:20:43 +00:00
dependabot[bot] f1e596a058 ⬆️ Bump tox from 4.13.0 to 4.14.0
Bumps [tox](https://github.com/tox-dev/tox) from 4.13.0 to 4.14.0.
- [Release notes](https://github.com/tox-dev/tox/releases)
- [Changelog](https://github.com/tox-dev/tox/blob/main/docs/changelog.rst)
- [Commits](https://github.com/tox-dev/tox/compare/4.13.0...4.14.0)

---
updated-dependencies:
- dependency-name: tox
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-03-06 01:00:05 +00:00
Onuralp SEZER cd20887d26 Merge pull request #974 from roboflow/dependabot/pip/nbconvert-7.16.2
⬆️ Bump nbconvert from 7.16.1 to 7.16.2
2024-03-05 23:31:16 +03:00
dependabot[bot] e1a950f691 ⬆️ Bump nbconvert from 7.16.1 to 7.16.2
Bumps [nbconvert](https://github.com/jupyter/nbconvert) from 7.16.1 to 7.16.2.
- [Release notes](https://github.com/jupyter/nbconvert/releases)
- [Changelog](https://github.com/jupyter/nbconvert/blob/main/CHANGELOG.md)
- [Commits](https://github.com/jupyter/nbconvert/compare/v7.16.1...v7.16.2)

---
updated-dependencies:
- dependency-name: nbconvert
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-03-05 00:33:56 +00:00
Onuralp SEZER b0a64751d0 Merge pull request #973 from roboflow/dependabot/pip/pytest-8.1.0
⬆️ Bump pytest from 8.0.2 to 8.1.0
2024-03-04 21:42:59 +03:00
dependabot[bot] 34648871ab ⬆️ Bump pytest from 8.0.2 to 8.1.0
Bumps [pytest](https://github.com/pytest-dev/pytest) from 8.0.2 to 8.1.0.
- [Release notes](https://github.com/pytest-dev/pytest/releases)
- [Changelog](https://github.com/pytest-dev/pytest/blob/main/CHANGELOG.rst)
- [Commits](https://github.com/pytest-dev/pytest/compare/8.0.2...8.1.0)

---
updated-dependencies:
- dependency-name: pytest
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-03-04 01:23:55 +00:00
Onuralp SEZER 823adb3867 ci: 👷 update ruff config and group lint
Signed-off-by: Onuralp SEZER <thunderbirdtr@gmail.com>
2024-03-02 03:57:13 +03:00
Onuralp SEZER 56825423dc fix: 🐞 update PolygonZone test and update traffic-analysis depricated codes are updated
Signed-off-by: Onuralp SEZER <thunderbirdtr@gmail.com>
2024-03-02 03:25:59 +03:00
Onuralp SEZER e86fc592c7 Merge pull request #968 from roboflow/dependabot/pip/mkdocs-material-9.5.12
⬆️ Bump mkdocs-material from 9.5.11 to 9.5.12
2024-03-01 12:27:34 +03:00
Onuralp SEZER 3e05057ee4 Merge pull request #967 from roboflow/dependabot/pip/build-1.1.1
⬆️ Bump build from 1.0.3 to 1.1.1
2024-03-01 04:14:26 +03:00
dependabot[bot] a3e39bdb6f ⬆️ Bump mkdocs-material from 9.5.11 to 9.5.12
Bumps [mkdocs-material](https://github.com/squidfunk/mkdocs-material) from 9.5.11 to 9.5.12.
- [Release notes](https://github.com/squidfunk/mkdocs-material/releases)
- [Changelog](https://github.com/squidfunk/mkdocs-material/blob/master/CHANGELOG)
- [Commits](https://github.com/squidfunk/mkdocs-material/compare/9.5.11...9.5.12)

---
updated-dependencies:
- dependency-name: mkdocs-material
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-03-01 01:10:04 +00:00
dependabot[bot] 199d26aa72 ⬆️ Bump build from 1.0.3 to 1.1.1
Bumps [build](https://github.com/pypa/build) from 1.0.3 to 1.1.1.
- [Release notes](https://github.com/pypa/build/releases)
- [Changelog](https://github.com/pypa/build/blob/main/CHANGELOG.rst)
- [Commits](https://github.com/pypa/build/compare/1.0.3...1.1.1)

---
updated-dependencies:
- dependency-name: build
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-03-01 01:01:54 +00:00
Onuralp SEZER ed3c6d1fbd Merge pull request #966 from roboflow/dependabot/pip/ruff-0.3.0
⬆️ Bump ruff from 0.2.2 to 0.3.0
2024-03-01 03:59:32 +03:00
dependabot[bot] f29bdec62e ⬆️ Bump ruff from 0.2.2 to 0.3.0
Bumps [ruff](https://github.com/astral-sh/ruff) from 0.2.2 to 0.3.0.
- [Release notes](https://github.com/astral-sh/ruff/releases)
- [Changelog](https://github.com/astral-sh/ruff/blob/main/CHANGELOG.md)
- [Commits](https://github.com/astral-sh/ruff/compare/v0.2.2...v0.3.0)

---
updated-dependencies:
- dependency-name: ruff
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-03-01 00:50:01 +00:00
Onuralp SEZER f55ef90716 Merge pull request #819 from AdonaiVera/allowing_serialise_detections_json
New function [JSONSink] - Allowing to serialise Detections to a JSON file
2024-03-01 03:23:46 +03:00
Adonai Vera d9496316bc remove the json output after finish the unit test 2024-03-01 03:14:42 +03:00
Adonai Vera 4509608a5d Apply documentation, unit test with mutliple scenarios, and improvement 2024-03-01 03:14:35 +03:00
Piotr Skalski 6eeb1c4ae3 Merge pull request #965 from roboflow/ci/doc-test
feat: 📚 add docs test workflow
2024-02-29 22:43:39 +01:00
Onuralp SEZER 4803ab26e5 feat: 📚 add docs test workflow
Signed-off-by: Onuralp SEZER <thunderbirdtr@gmail.com>
2024-03-01 00:41:24 +03:00
Onuralp SEZER 852d518d7c fix: 🐞 evaluating-alignment-of-text-to-image-diffusion-model widget fix for docs to render (#964)
Signed-off-by: Onuralp SEZER <thunderbirdtr@gmail.com>
2024-03-01 00:28:51 +03:00
Onuralp SEZER b78b3913fc Merge pull request #907 from iamhatesz/docs/alignment-cookbook
Add a cookbook about alignment evaluation
2024-03-01 00:04:59 +03:00
Onuralp SEZER 2407fad07e fix: 🐞 swap ultralytics to inference-gpu[yolo-world] usage and constants added
Signed-off-by: Onuralp SEZER <thunderbirdtr@gmail.com>
2024-03-01 00:03:55 +03:00
SkalskiP 73013d6e47 bump version from 0.19.0rc4 to 0.19.0rc5 2024-02-29 21:17:33 +01:00
Onuralp SEZER 41c78cceed Merge pull request #963 from roboflow/feat/plot_image/pillow
feat(ImageType): 🚀 sv.plot_images_grid and sv.plot_image can accept ImageType
2024-02-29 23:11:22 +03:00
Onuralp SEZER ce3356287e feat(ImageType): 🚀 sv.plot_images_grid and sv.plot_image can accept ImageType
Signed-off-by: Onuralp SEZER <thunderbirdtr@gmail.com>
2024-02-29 23:09:01 +03:00
SkalskiP 0aff293841 bump version from 0.19.0rc3 to 0.19.0rc4 2024-02-29 20:04:24 +01:00
Onuralp SEZER b13e3e0b8e Merge pull request #962 from roboflow/feat/supervision/warnings
fix: 🐞 Custom warning type 'SupervisionWarning' added
2024-02-29 19:27:04 +03:00
Onuralp SEZER 18085340e2 feat: ⚠️ cleaner warning format added
Signed-off-by: Onuralp SEZER <thunderbirdtr@gmail.com>
2024-02-29 19:25:10 +03:00
Onuralp SEZER 7d65a9445a fix: 🐞 Custom warning type 'SupervisionWarning' added
Signed-off-by: Onuralp SEZER <thunderbirdtr@gmail.com>
2024-02-29 18:52:38 +03:00
Onuralp SEZER a68e5b4a6d Merge pull request #886 from Kadermiyanyedi/update-byte-track-class-argument-names
[ByteTrack] - change the names and documenting input arguments #787
2024-02-29 14:45:50 +03:00
Onuralp SEZER d3383fc02f feat: ✨ deprecated_parameters ⚠️ added and warning filter for show ALL warnings
Signed-off-by: Onuralp SEZER <thunderbirdtr@gmail.com>
2024-02-29 14:42:38 +03:00
Piotr Skalski 6613f57a81 Merge pull request #961 from roboflow/ci/pypi/regex
ci: 👷 remove duplicated publish tag regex
2024-02-29 11:38:53 +01:00
Onuralp SEZER 00c84d4530 Merge branch 'develop' into update-byte-track-class-argument-names 2024-02-29 13:35:49 +03:00
Onuralp SEZER cefd9e100c ci: 👷 remove duplicated publish tag regex
Signed-off-by: Onuralp SEZER <thunderbirdtr@gmail.com>
2024-02-29 12:54:22 +03:00
Piotr Skalski 07763bb2d0 Merge pull request #935 from NickHerrig/cookbooks/add-visuals
Cookbooks/add visuals
2024-02-29 10:36:16 +01:00
Piotr Skalski af03010a07 Merge pull request #960 from roboflow/small_deprecated_parameter_cleanup
update `deprecated_parameter` docs
2024-02-29 10:19:36 +01:00
pre-commit-ci[bot] f12182b016 fix(pre_commit): 🎨 auto format pre-commit hooks 2024-02-29 09:15:25 +00:00
SkalskiP 25deda23f2 ready for test in colab 2024-02-29 10:11:29 +01:00
Onuralp SEZER a790040c84 Merge pull request #910 from LeviVasconcelos/polygonzone-add-multiple-anchors-support
Polygonzone add multiple anchors support
2024-02-28 22:23:54 +03:00
Onuralp SEZER d0ad5fe1d4 fix: 🐞 depricated supervision version add and abbreviation dropped
Signed-off-by: Onuralp SEZER <thunderbirdtr@gmail.com>
2024-02-28 22:10:06 +03:00
Piotr Skalski 0c0685987a Merge pull request #942 from roboflow/feat/PolygonZoneAnnotator/LabelVisibility
feat(PolygonZoneAnnotator): ✨ make display of zone label optional default is true
2024-02-28 14:54:55 +01:00
Onuralp SEZER 5f85339851 feat(PolygonZoneAnnotator): ✨ make display of zone label optional default is true
Signed-off-by: Onuralp SEZER <thunderbirdtr@gmail.com>
2024-02-28 16:36:31 +03:00
Piotr Skalski 13cb923541 Merge pull request #944 from LinasKo/fix/smoother-removes-detections-tracker-id
Fix smoother removing tracking_id from detections
2024-02-28 14:25:31 +01:00
Linas Kondrackis 5e1d9bbd40 smoother: check len of detections - not tracked_detections 2024-02-28 15:22:15 +02:00
James cb8f4af8bf Merge pull request #955 from roboflow/fix/doc/percentage
fix(docs): 🐞 PercentageBarAnnotator example doc code usage fixed
2024-02-28 12:31:28 +00:00
Onuralp SEZER 165ed424bf fix(docs): 🐞 PercentageBarAnnotator example doc code usage fixed
Signed-off-by: Onuralp SEZER <thunderbirdtr@gmail.com>
2024-02-28 15:27:18 +03:00
Onuralp SEZER 96225cda0c Merge pull request #875 from LinasKo/feature/annotators-accept-PIL-images
Decorators around annotate functions, convert PIL images to np.ndarray
2024-02-28 14:34:14 +03:00
Piotr Skalski c039a90053 Merge pull request #952 from roboflow/fix/mask_iou_batch_memory_limit
Bugfix mask_iou_batch memory limit 5MB -> 5GB
2024-02-28 12:18:44 +01:00
PacificDou d9ccbda0a2 change memory limit unit to MB 2024-02-28 10:40:32 +00:00
PacificDou 49d4a4a9fd memory limit 5MB -> 5GB 2024-02-28 09:52:25 +00:00
Onuralp SEZER 97c01aa1a7 Merge pull request #951 from roboflow/dependabot/pip/mkdocstrings-0.24.1
⬆️ Bump mkdocstrings from 0.24.0 to 0.24.1
2024-02-28 03:57:53 +03:00
dependabot[bot] 3f9f87f645 ⬆️ Bump mkdocstrings from 0.24.0 to 0.24.1
Bumps [mkdocstrings](https://github.com/mkdocstrings/mkdocstrings) from 0.24.0 to 0.24.1.
- [Release notes](https://github.com/mkdocstrings/mkdocstrings/releases)
- [Changelog](https://github.com/mkdocstrings/mkdocstrings/blob/main/CHANGELOG.md)
- [Commits](https://github.com/mkdocstrings/mkdocstrings/compare/0.24.0...0.24.1)

---
updated-dependencies:
- dependency-name: mkdocstrings
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-02-28 00:56:45 +00:00
Onuralp SEZER 2ba70f644c Merge branch 'develop' into feature/annotators-accept-PIL-images 2024-02-27 12:51:33 +03:00
Onuralp SEZER fa65d5f34e ci: 👷 minimum pillow and poetry version adjusted for min ver
Signed-off-by: Onuralp SEZER <thunderbirdtr@gmail.com>
2024-02-27 12:50:21 +03:00
Onuralp SEZER a9f0154ca3 Merge pull request #949 from roboflow/dependabot/pip/notebook-7.1.1
⬆️ Bump notebook from 7.1.0 to 7.1.1
2024-02-27 12:33:43 +03:00
James b6f67e607e Merge pull request #889 from roboflow/ruff/config-updates
ci: 👷 ruff name rules updated
2024-02-27 09:33:01 +00:00
dependabot[bot] a5bb5a6aa8 ⬆️ Bump notebook from 7.1.0 to 7.1.1
Bumps [notebook](https://github.com/jupyter/notebook) from 7.1.0 to 7.1.1.
- [Release notes](https://github.com/jupyter/notebook/releases)
- [Changelog](https://github.com/jupyter/notebook/blob/main/CHANGELOG.md)
- [Commits](https://github.com/jupyter/notebook/compare/@jupyter-notebook/tree@7.1.0...@jupyter-notebook/tree@7.1.1)

---
updated-dependencies:
- dependency-name: notebook
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-02-27 00:19:02 +00:00
Levi Vasconcelos 8b443d1b45 pre-commit
pre-commit
2024-02-26 17:41:58 -03:00
Levi Vasconcelos 61adff2c9a review: fix @deprecated_parameter parameter names 2024-02-26 17:41:10 -03:00
Levi Vasconcelos d4cee86e2b reviews: add custom message option to @deprecated_parameter; add docstring 2024-02-26 17:41:10 -03:00
Levi Vasconcelos cb46751c9a reviews: use test_utils.mock_detections 2024-02-26 17:41:10 -03:00
Levi Vasconcelos 5e7463dc73 reviews: removing test for deprecation 2024-02-26 17:41:10 -03:00
Levi Vasconcelos 9b50c92ec0 pre-commit on tests 2024-02-26 17:41:10 -03:00
Levi Vasconcelos 7ebbcd6c8e add polygon_zone unit tests 2024-02-26 17:41:10 -03:00
Levi Vasconcelos 069f6f22ca pre-commit reformatting
pre-commit reformatting
2024-02-26 17:41:10 -03:00
Levi Vasconcelos 5bfd8429a8 update documentation
add polygon_zone unit tests
2024-02-26 17:41:10 -03:00
Levi Vasconcelos e8ab777dfd add multiple anchors support: use np.all 2024-02-26 17:41:10 -03:00
Levi Vasconcelos d63837181f allow API backward compatibility 2024-02-26 17:41:10 -03:00
Levi Vasconcelos c523fc163a add multiple anchors support
add multiple anchors support

remove old trigger
2024-02-26 17:41:10 -03:00
Linas Kondrackis 2e6e61b778 Re-add Pillow 2024-02-26 21:09:02 +02:00
Linas Kondrackis 4ee56be8a0 Merge branch 'develop' into feature/annotators-accept-PIL-images 2024-02-26 21:01:16 +02:00
Onuralp SEZER e5dfc4c221 Merge pull request #946 from roboflow/dependabot/pip/mkdocs-git-committers-plugin-2-2.3.0
⬆️ Bump mkdocs-git-committers-plugin-2 from 2.2.3 to 2.3.0
2024-02-26 21:15:48 +03:00
Onuralp SEZER 02c1cb001c Merge pull request #945 from roboflow/dependabot/pip/mkdocs-material-9.5.11
⬆️ Bump mkdocs-material from 9.5.10 to 9.5.11
2024-02-26 21:14:08 +03:00
Onuralp SEZER 86a309d255 Merge pull request #947 from roboflow/dependabot/pip/pytest-8.0.2
⬆️ Bump pytest from 8.0.1 to 8.0.2
2024-02-26 21:13:34 +03:00
Linas Kondrackis fefd3386c1 Fix formatting 2024-02-26 20:06:57 +02:00
dependabot[bot] 54a4a3606f ⬆️ Bump pytest from 8.0.1 to 8.0.2
Bumps [pytest](https://github.com/pytest-dev/pytest) from 8.0.1 to 8.0.2.
- [Release notes](https://github.com/pytest-dev/pytest/releases)
- [Changelog](https://github.com/pytest-dev/pytest/blob/main/CHANGELOG.rst)
- [Commits](https://github.com/pytest-dev/pytest/compare/8.0.1...8.0.2)

---
updated-dependencies:
- dependency-name: pytest
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-02-26 01:50:41 +00:00
dependabot[bot] d8396c10ea ⬆️ Bump mkdocs-git-committers-plugin-2 from 2.2.3 to 2.3.0
Bumps [mkdocs-git-committers-plugin-2](https://github.com/ojacques/mkdocs-git-committers-plugin-2) from 2.2.3 to 2.3.0.
- [Release notes](https://github.com/ojacques/mkdocs-git-committers-plugin-2/releases)
- [Commits](https://github.com/ojacques/mkdocs-git-committers-plugin-2/compare/2.2.3...2.3.0)

---
updated-dependencies:
- dependency-name: mkdocs-git-committers-plugin-2
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-02-26 01:43:58 +00:00
dependabot[bot] 5255a25f03 ⬆️ Bump mkdocs-material from 9.5.10 to 9.5.11
Bumps [mkdocs-material](https://github.com/squidfunk/mkdocs-material) from 9.5.10 to 9.5.11.
- [Release notes](https://github.com/squidfunk/mkdocs-material/releases)
- [Changelog](https://github.com/squidfunk/mkdocs-material/blob/master/CHANGELOG)
- [Commits](https://github.com/squidfunk/mkdocs-material/compare/9.5.10...9.5.11)

---
updated-dependencies:
- dependency-name: mkdocs-material
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-02-26 01:37:07 +00:00
Tomasz Wrona ae6021a5b4 Fix indent 2024-02-25 23:33:46 +01:00
Tomasz Wrona f866a11099 Review fixes 2024-02-25 23:32:50 +01:00
Linas Kondrackis afcb77965c Fix smoother removing tracking_id from detections
* Addresses issue #928 matching implementation in ByteTrack,
  but sidestepping the underlying cause outlined in #943.
2024-02-25 20:33:24 +02:00
pre-commit-ci[bot] 451e0200cb fix(pre_commit): 🎨 auto format pre-commit hooks 2024-02-23 03:23:20 +00:00
Nick Herrig b0667ce6cb Remove tqdm bar so mkdocs builds 2024-02-22 21:21:53 -06:00
PacificDou b2e085dd21 Merge pull request #938 from roboflow/mask-iou-batch-memory-issue
Limit memory usage for mask_iou_batch
2024-02-22 20:41:40 +01:00
pre-commit-ci[bot] a3a8fcb433 fix(pre_commit): 🎨 auto format pre-commit hooks 2024-02-22 18:00:04 +00:00
PacificDou 7d46c64628 limit memory usage for mask_iou_batch 2024-02-22 17:54:48 +00:00
pre-commit-ci[bot] 419c9e375b fix(pre_commit): 🎨 auto format pre-commit hooks 2024-02-22 02:03:18 +00:00
Nick Herrig 59bfc68b6f Add visuals to object tracking cookbook 2024-02-21 19:56:34 -06:00
Nick Herrig 8383b445f1 Add visualizations to annotate with detections cookbook 2024-02-21 18:10:41 -06:00
Onuralp SEZER 8599345a3c Merge pull request #934 from roboflow/dependabot/pip/cryptography-42.0.4
⬆️ Bump cryptography from 42.0.2 to 42.0.4
2024-02-22 00:19:40 +03:00
Onuralp SEZER 69fadf026b Merge pull request #931 from roboflow/dependabot/pip/nbconvert-7.16.1
⬆️ Bump nbconvert from 7.16.0 to 7.16.1
2024-02-22 00:19:22 +03:00
dependabot[bot] 4b2a9bf607 ⬆️ Bump cryptography from 42.0.2 to 42.0.4
Bumps [cryptography](https://github.com/pyca/cryptography) from 42.0.2 to 42.0.4.
- [Changelog](https://github.com/pyca/cryptography/blob/main/CHANGELOG.rst)
- [Commits](https://github.com/pyca/cryptography/compare/42.0.2...42.0.4)

---
updated-dependencies:
- dependency-name: cryptography
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-02-21 20:49:06 +00:00
Nick Herrig a1d4cb8b33 Center html video, similar to count-object-crossing cookbook 2024-02-21 11:00:18 -06:00
Nick Herrig e9d0635a74 Add video display for supervision asset download example 2024-02-21 10:05:57 -06:00
dependabot[bot] dd07502543 ⬆️ Bump nbconvert from 7.16.0 to 7.16.1
Bumps [nbconvert](https://github.com/jupyter/nbconvert) from 7.16.0 to 7.16.1.
- [Release notes](https://github.com/jupyter/nbconvert/releases)
- [Changelog](https://github.com/jupyter/nbconvert/blob/main/CHANGELOG.md)
- [Commits](https://github.com/jupyter/nbconvert/compare/v7.16.0...v7.16.1)

---
updated-dependencies:
- dependency-name: nbconvert
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-02-21 00:15:43 +00:00
Onuralp SEZER 56d3e8ef0b Merge pull request #917 from roboflow/dependabot/pip/tox-4.13.0
⬆️ Bump tox from 4.12.1 to 4.13.0
2024-02-20 22:14:26 +03:00
Onuralp SEZER c328cf0469 Merge pull request #918 from roboflow/dependabot/pip/matplotlib-3.7.5
⬆️ Bump matplotlib from 3.7.4 to 3.7.5
2024-02-20 22:14:12 +03:00
Onuralp SEZER e34d274d8f Merge pull request #919 from roboflow/dependabot/pip/ruff-0.2.2
⬆️ Bump ruff from 0.2.1 to 0.2.2
2024-02-20 22:13:54 +03:00
Onuralp SEZER 88f0c68929 Merge pull request #920 from roboflow/dependabot/pip/pytest-8.0.1
⬆️ Bump pytest from 8.0.0 to 8.0.1
2024-02-20 22:13:40 +03:00
Onuralp SEZER 34d73e8847 Merge pull request #924 from roboflow/pre-commit-ci-update-config
chore(pre_commit): ⬆ pre_commit autoupdate
2024-02-20 22:08:52 +03:00
Onuralp SEZER 56a7f8a55f Merge pull request #927 from roboflow/dependabot/pip/mkdocs-material-9.5.10
⬆️ Bump mkdocs-material from 9.5.9 to 9.5.10
2024-02-20 22:08:37 +03:00
dependabot[bot] afacc19236 ⬆️ Bump mkdocs-material from 9.5.9 to 9.5.10
Bumps [mkdocs-material](https://github.com/squidfunk/mkdocs-material) from 9.5.9 to 9.5.10.
- [Release notes](https://github.com/squidfunk/mkdocs-material/releases)
- [Changelog](https://github.com/squidfunk/mkdocs-material/blob/master/CHANGELOG)
- [Commits](https://github.com/squidfunk/mkdocs-material/compare/9.5.9...9.5.10)

---
updated-dependencies:
- dependency-name: mkdocs-material
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-02-20 00:58:56 +00:00
pre-commit-ci[bot] 59ba52fd80 chore(pre_commit): ⬆ pre_commit autoupdate
updates:
- [github.com/astral-sh/ruff-pre-commit: v0.2.1 → v0.2.2](https://github.com/astral-sh/ruff-pre-commit/compare/v0.2.1...v0.2.2)
2024-02-19 17:48:58 +00:00
Piotr Skalski 5ffb3424f3 Merge pull request #922 from roboflow/cookbooks/style-update
new cookbook z-index fix for author avatar
2024-02-19 12:41:38 +01:00
SkalskiP ac7d36b215 new cookbook z-index fix for author avatar 2024-02-19 12:37:25 +01:00
James cf3a954416 Merge pull request #908 from roboflow/cookbooks/author-avatar-zindex
fix: 🐞 cookbook z-index fix for author avatar
2024-02-19 10:00:45 +00:00
James 6615c553e5 Merge pull request #870 from roboflow/docs/home-page
docs: 📝 h1 title Home removed from index.md
2024-02-19 10:00:21 +00:00
dependabot[bot] 0f36679ac7 ⬆️ Bump pytest from 8.0.0 to 8.0.1
Bumps [pytest](https://github.com/pytest-dev/pytest) from 8.0.0 to 8.0.1.
- [Release notes](https://github.com/pytest-dev/pytest/releases)
- [Changelog](https://github.com/pytest-dev/pytest/blob/main/CHANGELOG.rst)
- [Commits](https://github.com/pytest-dev/pytest/compare/8.0.0...8.0.1)

---
updated-dependencies:
- dependency-name: pytest
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-02-19 01:19:38 +00:00
dependabot[bot] 97a986cd11 ⬆️ Bump ruff from 0.2.1 to 0.2.2
Bumps [ruff](https://github.com/astral-sh/ruff) from 0.2.1 to 0.2.2.
- [Release notes](https://github.com/astral-sh/ruff/releases)
- [Changelog](https://github.com/astral-sh/ruff/blob/main/CHANGELOG.md)
- [Commits](https://github.com/astral-sh/ruff/compare/v0.2.1...v0.2.2)

---
updated-dependencies:
- dependency-name: ruff
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-02-19 01:09:46 +00:00
dependabot[bot] a21d54fab3 ⬆️ Bump matplotlib from 3.7.4 to 3.7.5
Bumps [matplotlib](https://github.com/matplotlib/matplotlib) from 3.7.4 to 3.7.5.
- [Release notes](https://github.com/matplotlib/matplotlib/releases)
- [Commits](https://github.com/matplotlib/matplotlib/compare/v3.7.4...v3.7.5)

---
updated-dependencies:
- dependency-name: matplotlib
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-02-19 01:02:38 +00:00
dependabot[bot] b80a88ee25 ⬆️ Bump tox from 4.12.1 to 4.13.0
Bumps [tox](https://github.com/tox-dev/tox) from 4.12.1 to 4.13.0.
- [Release notes](https://github.com/tox-dev/tox/releases)
- [Changelog](https://github.com/tox-dev/tox/blob/main/docs/changelog.rst)
- [Commits](https://github.com/tox-dev/tox/compare/4.12.1...4.13.0)

---
updated-dependencies:
- dependency-name: tox
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-02-19 00:58:49 +00:00
Onuralp SEZER c1c528d378 Merge pull request #914 from roboflow/dependabot/pip/cryptography-42.0.2
⬆️ Bump cryptography from 42.0.0 to 42.0.2
2024-02-17 21:46:06 +03:00
dependabot[bot] 1c1a6236ea ⬆️ Bump cryptography from 42.0.0 to 42.0.2
Bumps [cryptography](https://github.com/pyca/cryptography) from 42.0.0 to 42.0.2.
- [Changelog](https://github.com/pyca/cryptography/blob/main/CHANGELOG.rst)
- [Commits](https://github.com/pyca/cryptography/compare/42.0.0...42.0.2)

---
updated-dependencies:
- dependency-name: cryptography
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-02-17 00:54:06 +00:00
Leo Ueno ebd86eef32 Update occupancy_analytics.ipynb 2024-02-16 12:47:50 -08:00
Leo Ueno 158471283f Add occupancy analytics cookbook 2024-02-16 12:40:55 -08:00
Piotr Skalski df3f8464b1 Merge pull request #911 from roboflow/cookbooks/zero-shot-object-detection-with-yolo-world
🧑‍🍳 Zero-Shot Object Detection with YOLO-World Cookbook
2024-02-16 14:29:01 +01:00
pre-commit-ci[bot] 8625c7217c fix(pre_commit): 🎨 auto format pre-commit hooks 2024-02-16 13:26:34 +00:00
SkalskiP 382b4e0801 🧑‍🍳 Zero-Shot Object Detection with YOLO-World Cookbook 2024-02-16 14:23:20 +01:00
Onuralp SEZER 6d2d0c01a3 fix: 🐞 cookbook z-index fix for author avatar
Signed-off-by: Onuralp SEZER <thunderbirdtr@gmail.com>
2024-02-15 20:43:11 +03:00
sansyoandpre-commit-ci[bot] 15b099cb71 Add Support for Center Left,Right Text Position for LabelAnnotator (#905)
* Added Position.CENTER_LEFT
* Added Position.CENTER_RIGHT
---------
Author: sansyo <moutoutan@gmail.com>
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
2024-02-15 18:17:28 +03:00
pre-commit-ci[bot] 4e635ee788 fix(pre_commit): 🎨 auto format pre-commit hooks 2024-02-15 13:17:56 +00:00
Tomasz Wrona f53e0d8aa5 A new cookbook about alignment evaluation 2024-02-15 14:00:09 +01:00
Onuralp SEZER 6ba9e70b69 Merge pull request #904 from NickHerrig/feature/fix-cookbook
Fix google colab link in object tracking cookbook
2024-02-15 14:20:00 +03:00
Nick Herrig 14771fa326 Fix google colab link in object tracking cookbook 2024-02-14 21:56:33 -06:00
Onuralp SEZER 95398c2a8e Merge pull request #901 from Kadermiyanyedi/add-class-name-to-detection-data
[Detections] - from_inference should include 'class_name' key in Detections.data even if result is empty #837
2024-02-14 23:39:05 +03:00
Kader Miyanyedi 75bb07078c fix(detection): add class name to detection data even if empty
Signed-off-by: Kader Miyanyedi <Kadermiyanyedi@hotmail.com>
2024-02-14 23:36:48 +03:00
Kader Miyanyedi ba7077918d docs(byte_tracker): improve byte track argument doc string descriptions 2024-02-14 21:25:28 +03:00
Onuralp SEZER 6b16970d50 Merge pull request #898 from roboflow/dependabot/pip/notebook-7.1.0
⬆️ Bump notebook from 7.0.8 to 7.1.0
2024-02-14 17:25:25 +03:00
Linas Kondrackis 20b412b7e1 Docs fix: ImageType displayed on multiple lines 2024-02-14 15:42:50 +02:00
Linas Kondrackis 3f965c9121 Remove check-docstring-first from pre-commit hook
* Add docstring for ImageType type
* As discussed in https://github.com/roboflow/supervision/pull/875#issuecomment-1941388238
2024-02-14 13:52:50 +02:00
Linas Kondrackis 08418246c2 Add Pillow dependency, add docsrings for ImageType
* PR #875
2024-02-14 13:52:15 +02:00
dependabot[bot] e1607b4590 ⬆️ Bump notebook from 7.0.8 to 7.1.0
Bumps [notebook](https://github.com/jupyter/notebook) from 7.0.8 to 7.1.0.
- [Release notes](https://github.com/jupyter/notebook/releases)
- [Changelog](https://github.com/jupyter/notebook/blob/main/CHANGELOG.md)
- [Commits](https://github.com/jupyter/notebook/compare/@jupyter-notebook/tree@7.0.8...@jupyter-notebook/tree@7.1.0)

---
updated-dependencies:
- dependency-name: notebook
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-02-14 01:12:14 +00:00
Onuralp SEZER be2d75c312 ci: 👷 check-docstring-first removed
Signed-off-by: Onuralp SEZER <thunderbirdtr@gmail.com>
2024-02-13 16:06:27 +03:00
Onuralp SEZER a697e71ccd ci: 👷 ruff name rules updated
Signed-off-by: Onuralp SEZER <thunderbirdtr@gmail.com>
2024-02-13 15:59:59 +03:00
Christoforos Aristeidou 2a9d4257ba Merge branch 'roboflow:develop' into develop 2024-02-12 22:10:14 +02:00
Christoforos Aristeidou 9ca3c9319d pre-commit spacing correction 2024-02-12 22:08:58 +02:00
Christoforos Aristeidou 379d755a52 description of x,y pixel and trim method 2024-02-12 22:03:57 +02:00
Christoforos Aristeidou d228224f06 completed if else statements for positioning 2024-02-12 21:47:29 +02:00
Onuralp SEZER e3f0ca6937 Merge pull request #885 from roboflow/pre-commit-ci-update-config
chore(pre_commit): ⬆ pre_commit autoupdate
2024-02-12 21:54:20 +03:00
Kader Miyanyedi dafa2a42de refactor(byte_tracker): change byte tracker class argument names to more clear 2024-02-12 21:21:26 +03:00
pre-commit-ci[bot] c96022b97a chore(pre_commit): ⬆ pre_commit autoupdate
updates:
- [github.com/astral-sh/ruff-pre-commit: v0.2.0 → v0.2.1](https://github.com/astral-sh/ruff-pre-commit/compare/v0.2.0...v0.2.1)
2024-02-12 17:38:59 +00:00
Piotr Skalski 899be6a5a4 Merge pull request #884 from roboflow/cookbooks/contributing-guidelines
`CONTRIBUTING.md` updates.
2024-02-12 18:26:21 +01:00
pre-commit-ci[bot] 94b0e9cd22 fix(pre_commit): 🎨 auto format pre-commit hooks 2024-02-12 17:25:12 +00:00
SkalskiP 8ac3b5f8d2 CONTRIBUTING.md updates. 2024-02-12 18:23:56 +01:00
Christoforos Aristeidou 2863267f30 asdf 2024-02-12 18:33:47 +02:00
Piotr Skalski cebf726997 Merge pull request #883 from roboflow/cookbooks/count-objects-crossing-the-line-3
`Count People Crossing the Line` cookbook updates.
2024-02-12 17:02:18 +01:00
pre-commit-ci[bot] 8ddfcdcd9a fix(pre_commit): 🎨 auto format pre-commit hooks 2024-02-12 16:00:48 +00:00
SkalskiP 5997c39ac7 Count People Crossing the Line cookbook updates. 2024-02-12 16:43:40 +01:00
Piotr Skalski 39b5563465 Merge pull request #882 from roboflow/docs/line-zone-docs-improvement
`LineZone`, `LineZoneAnnotator` documentation improvements
2024-02-12 13:53:33 +01:00
pre-commit-ci[bot] 1b07974e93 fix(pre_commit): 🎨 auto format pre-commit hooks 2024-02-12 12:51:07 +00:00
SkalskiP ba81a09b2c LineZone, LineZoneAnnotator documentation improvements 2024-02-12 13:43:58 +01:00
Onuralp SEZER 2e898f137e Merge pull request #879 from roboflow/dependabot/pip/tqdm-4.66.2
⬆️ Bump tqdm from 4.66.1 to 4.66.2
2024-02-12 15:40:26 +03:00
dependabot[bot] c7e8534650 ⬆️ Bump tqdm from 4.66.1 to 4.66.2
Bumps [tqdm](https://github.com/tqdm/tqdm) from 4.66.1 to 4.66.2.
- [Release notes](https://github.com/tqdm/tqdm/releases)
- [Commits](https://github.com/tqdm/tqdm/compare/v4.66.1...v4.66.2)

---
updated-dependencies:
- dependency-name: tqdm
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-02-12 10:30:41 +00:00
Onuralp SEZER fd2b3c4e8e Merge pull request #877 from roboflow/dependabot/pip/mkdocs-material-9.5.9
⬆️ Bump mkdocs-material from 9.5.8 to 9.5.9
2024-02-12 13:21:16 +03:00
Onuralp SEZER 632d078f4b Merge pull request #878 from roboflow/dependabot/pip/notebook-7.0.8
⬆️ Bump notebook from 7.0.7 to 7.0.8
2024-02-12 13:20:54 +03:00
Onuralp SEZER cbd77b10f9 Merge pull request #880 from roboflow/dependabot/pip/twine-5.0.0
⬆️ Bump twine from 4.0.2 to 5.0.0
2024-02-12 13:19:54 +03:00
dependabot[bot] 48500cd350 ⬆️ Bump twine from 4.0.2 to 5.0.0
Bumps [twine](https://github.com/pypa/twine) from 4.0.2 to 5.0.0.
- [Release notes](https://github.com/pypa/twine/releases)
- [Changelog](https://github.com/pypa/twine/blob/main/docs/changelog.rst)
- [Commits](https://github.com/pypa/twine/compare/4.0.2...5.0.0)

---
updated-dependencies:
- dependency-name: twine
  dependency-type: direct:development
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-02-12 00:55:18 +00:00
dependabot[bot] ac53125bb6 ⬆️ Bump notebook from 7.0.7 to 7.0.8
Bumps [notebook](https://github.com/jupyter/notebook) from 7.0.7 to 7.0.8.
- [Release notes](https://github.com/jupyter/notebook/releases)
- [Changelog](https://github.com/jupyter/notebook/blob/@jupyter-notebook/tree@7.0.8/CHANGELOG.md)
- [Commits](https://github.com/jupyter/notebook/compare/@jupyter-notebook/tree@7.0.7...@jupyter-notebook/tree@7.0.8)

---
updated-dependencies:
- dependency-name: notebook
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-02-12 00:50:34 +00:00
dependabot[bot] 0f2a18efd1 ⬆️ Bump mkdocs-material from 9.5.8 to 9.5.9
Bumps [mkdocs-material](https://github.com/squidfunk/mkdocs-material) from 9.5.8 to 9.5.9.
- [Release notes](https://github.com/squidfunk/mkdocs-material/releases)
- [Changelog](https://github.com/squidfunk/mkdocs-material/blob/master/CHANGELOG)
- [Commits](https://github.com/squidfunk/mkdocs-material/compare/9.5.8...9.5.9)

---
updated-dependencies:
- dependency-name: mkdocs-material
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-02-12 00:48:54 +00:00
Linas Kondrackis c8f7622e91 Remove ImgType docstring
* Bad decision, but makes the pre-commit hook happy
2024-02-10 16:39:38 +02:00
Linas Kondrackis c2dd5031ba Decorators around annotate functions, convert PIL images to np.ndarray and back, if required 2024-02-10 14:43:00 +02:00
Piotr Skalski 2f9fee6451 Merge pull request #872 from roboflow/cookbooks/count-pople-crossing-the-line-2
[Cookbooks] - Count People Crossing the Line 2
2024-02-09 19:11:55 +01:00
pre-commit-ci[bot] b6dc988e37 fix(pre_commit): 🎨 auto format pre-commit hooks 2024-02-09 18:10:48 +00:00
SkalskiP 2ea2231324 ready 2024-02-09 19:09:10 +01:00
Piotr Skalski 78d6890508 Merge pull request #869 from roboflow/cookbooks/count-objects-crossing-the-line
[Cookbooks] - Count Objects Crossing the Line
2024-02-09 18:50:57 +01:00
SkalskiP d8584333ef Merge remote-tracking branch 'origin/cookbooks/count-objects-crossing-the-line' into cookbooks/count-objects-crossing-the-line 2024-02-09 18:50:02 +01:00
SkalskiP 69213b19d7 up 2024-02-09 18:49:55 +01:00
Onuralp SEZER 0d312f3cd7 docs: 📝 h1 title Home removed from index.md
Signed-off-by: Onuralp SEZER <thunderbirdtr@gmail.com>
2024-02-09 20:17:53 +03:00
SkalskiP 11197f8a4e bump version from 0.19.0rc2 to 0.19.0rc3 2024-02-09 18:09:56 +01:00
pre-commit-ci[bot] 01e7330e6e fix(pre_commit): 🎨 auto format pre-commit hooks 2024-02-09 16:57:32 +00:00
SkalskiP 9d71636051 cleaning up Nick's cookbooks 2024-02-09 17:57:18 +01:00
SkalskiP 569157f0f0 Merge remote-tracking branch 'origin/develop' into cookbooks/count-objects-crossing-the-line
# Conflicts:
#	docs/theme/cookbooks.html
2024-02-09 17:43:19 +01:00
Piotr Skalski 8529a3ec18 Merge pull request #861 from NickHerrig/feat/cookbooks
Feat/cookbooks
2024-02-09 17:37:50 +01:00
SkalskiP 115d4492da changing colab names, card names, and card labels 2024-02-09 17:36:13 +01:00
SkalskiP 6cf9ece3a8 initial changes for count objects crossing the line cookbook 2024-02-09 17:25:55 +01:00
Nick Herrig 84b54d31bf Add colab notebook button, test in notebooks 2024-02-09 10:34:40 -05:00
pre-commit-ci[bot] 57c7109498 fix(pre_commit): 🎨 auto format pre-commit hooks 2024-02-09 14:30:00 +00:00
Nick Herrig 008dbcb0b4 Merge branch 'develop' into feat/cookbooks 2024-02-09 09:29:49 -05:00
Nick Herrig 122ca82cad Update cookbooks html to match new format -> no desc, cap tags 2024-02-09 09:27:07 -05:00
Nick Herrig 9ca7d3eb75 Finish and fix grammar of tracking cookbook 2024-02-09 09:21:14 -05:00
Piotr Skalski 5b2bdf58e7 Merge pull request #868 from roboflow/cookbooks/cards-improvements
[Cookbooks] - Improved functionality of cookbook cards
2024-02-09 14:24:51 +01:00
pre-commit-ci[bot] b7070ae574 fix(pre_commit): 🎨 auto format pre-commit hooks 2024-02-09 13:23:07 +00:00
SkalskiP 85f09e3323 same label have same color across multiple cards; fixed small bug with hover effect 2024-02-09 14:19:41 +01:00
SkalskiP 03f7001a2b cookbooks-card.js refactor 2024-02-09 13:26:32 +01:00
SkalskiP 36a825b7a0 author styling improvements 2024-02-09 12:47:02 +01:00
Onuralp SEZER 0950f90ddf Merge pull request #867 from roboflow/dependabot/pip/nbconvert-7.16.0
⬆️ Bump nbconvert from 7.14.2 to 7.16.0
2024-02-09 14:22:44 +03:00
Onuralp SEZER cb22b94fe1 Merge pull request #866 from roboflow/dependabot/pip/ipywidgets-8.1.2
⬆️ Bump ipywidgets from 8.1.1 to 8.1.2
2024-02-09 14:22:29 +03:00
pre-commit-ci[bot] 019c41bf1a fix(pre_commit): 🎨 auto format pre-commit hooks 2024-02-09 04:37:54 +00:00
Nick Herrig 607d94dad9 Merge branch 'develop' into feat/cookbooks 2024-02-08 23:37:45 -05:00
Nick Herrig aacdbe76f0 Add html entries for cookbooks, add tracking cookbook 2024-02-08 23:27:53 -05:00
Nick Herrig f340c49a70 Update bounding box cookbook name, Fix grammar and spelling 2024-02-08 20:30:57 -05:00
dependabot[bot] 5bd30f4c72 ⬆️ Bump nbconvert from 7.14.2 to 7.16.0
Bumps [nbconvert](https://github.com/jupyter/nbconvert) from 7.14.2 to 7.16.0.
- [Release notes](https://github.com/jupyter/nbconvert/releases)
- [Changelog](https://github.com/jupyter/nbconvert/blob/main/CHANGELOG.md)
- [Commits](https://github.com/jupyter/nbconvert/compare/v7.14.2...v7.16.0)

---
updated-dependencies:
- dependency-name: nbconvert
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-02-09 01:04:56 +00:00
dependabot[bot] d0f31448b9 ⬆️ Bump ipywidgets from 8.1.1 to 8.1.2
Bumps [ipywidgets](https://github.com/jupyter-widgets/ipywidgets) from 8.1.1 to 8.1.2.
- [Release notes](https://github.com/jupyter-widgets/ipywidgets/releases)
- [Commits](https://github.com/jupyter-widgets/ipywidgets/compare/8.1.1...8.1.2)

---
updated-dependencies:
- dependency-name: ipywidgets
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-02-09 01:01:04 +00:00
Nick Herrig 7b4cf2f0f6 Reviewed supervision assets cookbook and renamed 2024-02-08 19:51:08 -05:00
Piotr Skalski fb7dd6aefd Merge pull request #865 from roboflow/cookbooks/html-optimization-and-css-update
cookbooks page HTML optimisation + CSS update
2024-02-08 22:42:00 +01:00
pre-commit-ci[bot] ce70266d23 fix(pre_commit): 🎨 auto format pre-commit hooks 2024-02-08 21:39:07 +00:00
SkalskiP f1a2b99931 ready for review 2024-02-08 22:36:57 +01:00
Nick Herrig e3adcbeec1 Move cookbooks to new webpage and configure html file 2024-02-08 15:30:32 -05:00
SkalskiP 48af41377f move notebook inside the grid 2024-02-08 20:32:37 +01:00
Nick Herrig 0b7b8bb439 Move assets cookbook to docs, Update theme/cookbooks 2024-02-08 14:13:14 -05:00
Nick Herrig 95d28fabb5 Merge branch 'roboflow:develop' into feat/cookbooks 2024-02-08 13:30:40 -05:00
pre-commit-ci[bot] efd06ac77d fix(pre_commit): 🎨 auto format pre-commit hooks 2024-02-08 17:22:01 +00:00
Nick Herrig 1ac497a3e2 Finished bounding box annotation cookbook 2024-02-08 12:20:56 -05:00
Piotr Skalski 3dd3781b1b Add hackfest baner to README.md 2024-02-08 18:20:13 +01:00
Nick Herrig a015fc176e Fix object detection conflicts 2024-02-08 12:18:09 -05:00
Piotr Skalski 775c1b65f8 Merge pull request #863 from roboflow/fix/doc-env2
docs(fix): 🐞📝 MKDOCS_GIT_COMMITTERS_APIKEY fix attempt v2
2024-02-08 17:56:10 +01:00
Onuralp SEZER 8514f086b7 docs(fix): 🐞📝 MKDOCS_GIT_COMMITTERS_APIKEY fix attempt v2
Signed-off-by: Onuralp SEZER <thunderbirdtr@gmail.com>
2024-02-08 19:53:51 +03:00
Nick Herrig 4685a0a2ff Update bounding box conflict 2024-02-08 11:38:14 -05:00
Piotr Skalski a26dd9416e Merge pull request #862 from roboflow/fix/doc-env
docs(fix): 🐞📝 MKDOCS_GIT_COMMITTERS_APIKEY value added
2024-02-08 17:37:57 +01:00
Onuralp SEZER a6466d13a9 docs(fix): 🐞📝 MKDOCS_GIT_COMMITTERS_APIKEY value added
Signed-off-by: Onuralp SEZER <thunderbirdtr@gmail.com>
2024-02-08 19:33:20 +03:00
Piotr Skalski 82b18ae3f8 Merge pull request #860 from roboflow/docs/notebooks
docs(page): 🚀 Supervision Cookbook
2024-02-08 17:26:24 +01:00
Onuralp SEZER 08a204d872 docs(api): 📝 api/annotators position adjusted and small typo fix
Signed-off-by: Onuralp SEZER <thunderbirdtr@gmail.com>
2024-02-08 19:20:15 +03:00
Onuralp SEZER 4e5331b92d docs(version): 🐞 restore version part and revert hide h1 on home for now
Signed-off-by: Onuralp SEZER <thunderbirdtr@gmail.com>
2024-02-08 18:57:39 +03:00
Onuralp SEZER 985624e35e docs(assets): 🐞 missing js and css files added into mkdocs.yml
Signed-off-by: Onuralp SEZER <thunderbirdtr@gmail.com>
2024-02-08 18:05:07 +03:00
Onuralp SEZER 6a091b58a8 ci(docs): 👷 GH_TOKEN added for git-committers
Signed-off-by: Onuralp SEZER <thunderbirdtr@gmail.com>
2024-02-08 17:51:19 +03:00
Onuralp SEZER 4ef2d04dec ci(docs): 👷 new packages added for build document
Signed-off-by: Onuralp SEZER <thunderbirdtr@gmail.com>
2024-02-08 17:39:16 +03:00
pre-commit-ci[bot] f81ccbcc5f fix(pre_commit): 🎨 auto format pre-commit hooks 2024-02-08 14:34:47 +00:00
Onuralp SEZER d900e68787 docs(home): 🚀 hide table of content for home page only and give looks as more like home of supervision
Signed-off-by: Onuralp SEZER <thunderbirdtr@gmail.com>
2024-02-08 17:33:52 +03:00
Onuralp SEZER ab38cb1531 docs(nb): 🚀 initial notebook added as quickstart and other examples are removed
Signed-off-by: Onuralp SEZER <thunderbirdtr@gmail.com>
2024-02-08 17:30:04 +03:00
pre-commit-ci[bot] 7f51984063 fix(pre_commit): 🎨 auto format pre-commit hooks 2024-02-08 14:22:52 +00:00
pre-commit-ci[bot] 1ad26b5527 fix(pre_commit): 🎨 auto format pre-commit hooks 2024-02-08 14:13:38 +00:00
Onuralp SEZER d2ccc4f270 docs(nav): 🚀 nav-tab enabled and new order of pages for better understanding
Signed-off-by: Onuralp SEZER <thunderbirdtr@gmail.com>
2024-02-08 17:13:03 +03:00
Onuralp SEZER 15b4914448 docs(js): 🔥 unused params has been removed from js files for cookbook page
Signed-off-by: Onuralp SEZER <thunderbirdtr@gmail.com>
2024-02-08 17:06:22 +03:00
Onuralp SEZER 3ddeed1945 docs: ✨ data-url param added
Signed-off-by: Onuralp SEZER <thunderbirdtr@gmail.com>
2024-02-08 16:48:46 +03:00
Onuralp SEZER 1a20bb5745 docs: ✨ add demo notebook and remove notebooks folder from ignore list
Signed-off-by: Onuralp SEZER <thunderbirdtr@gmail.com>
2024-02-08 16:33:05 +03:00
Onuralp SEZER c4365871b5 Merge changes from develop branch 2024-02-08 15:31:06 +03:00
Onuralp SEZER 1fba192319 docs: ✨ folder rename to javascript to javascripts (plural)
Signed-off-by: Onuralp SEZER <thunderbirdtr@gmail.com>
2024-02-08 15:26:03 +03:00
Onuralp SEZER 6ffd159b77 docs: ✨ supervision cookbook initial page design landed
Signed-off-by: Onuralp SEZER <thunderbirdtr@gmail.com>
2024-02-08 15:20:43 +03:00
Onuralp SEZER 16d3214db9 Merge pull request #857 from roboflow/dependabot/pip/mkdocs-material-9.5.8
⬆️ Bump mkdocs-material from 9.5.7 to 9.5.8
2024-02-08 03:41:16 +03:00
dependabot[bot] 381bc8aed6 ⬆️ Bump mkdocs-material from 9.5.7 to 9.5.8
Bumps [mkdocs-material](https://github.com/squidfunk/mkdocs-material) from 9.5.7 to 9.5.8.
- [Release notes](https://github.com/squidfunk/mkdocs-material/releases)
- [Changelog](https://github.com/squidfunk/mkdocs-material/blob/master/CHANGELOG)
- [Commits](https://github.com/squidfunk/mkdocs-material/compare/9.5.7...9.5.8)

---
updated-dependencies:
- dependency-name: mkdocs-material
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-02-08 00:37:30 +00:00
Nick Herrig 3150f5a672 Add rough draft of bounding box displays 2024-02-07 18:55:24 -05:00
Onuralp SEZER eb35fdd1b7 Merge pull request #856 from roboflow/dependabot/pip/ruff-0.2.1
⬆️ Bump ruff from 0.2.0 to 0.2.1
2024-02-08 00:43:46 +03:00
Nick Herrig 9e95e1f0b3 Add supervision assets cookbook, correct assets documentation 2024-02-07 14:56:08 -05:00
Nick Herrig 4bfbe3c8f7 Add readme for cookbooks directory 2024-02-07 14:52:43 -05:00
Onuralp SEZER a6d9961b2b docs: ✨ jupyter notebook support added
Signed-off-by: Onuralp SEZER <thunderbirdtr@gmail.com>
2024-02-07 20:06:25 +03:00
Piotr Skalski a670faf646 Merge pull request #847 from AdonaiVera/segmentation_nms
[NMS] - add segmentation models support
2024-02-07 10:09:01 +01:00
SkalskiP 824a9140b6 tests fixed 2024-02-07 09:59:58 +01:00
SkalskiP 36ec1b6481 Merge remote-tracking branch 'origin/segmentation_nms' into segmentation_nms 2024-02-07 09:43:20 +01:00
SkalskiP 79a13d0432 final tests 2024-02-07 09:42:56 +01:00
pre-commit-ci[bot] cbbfb453f2 fix(pre_commit): 🎨 auto format pre-commit hooks 2024-02-07 08:41:34 +00:00
SkalskiP bbe0bfc760 final tests 2024-02-07 09:41:21 +01:00
SkalskiP 98e7310038 test vectorized mask_non_max_suppression 2024-02-07 09:31:02 +01:00
SkalskiP 71836ed1ee Merge remote-tracking branch 'origin/segmentation_nms' into segmentation_nms 2024-02-07 09:28:03 +01:00
SkalskiP b681274954 Merge remote-tracking branch 'origin/segmentation_nms' into segmentation_nms 2024-02-07 09:27:49 +01:00
SkalskiP 619fa832c5 Merge remote-tracking branch 'origin/segmentation_nms' into segmentation_nms 2024-02-07 09:24:55 +01:00
SkalskiP f2e65cf6fc refactored mask_non_max_suppression 2024-02-07 09:24:45 +01:00
pre-commit-ci[bot] 8f6887d994 fix(pre_commit): 🎨 auto format pre-commit hooks 2024-02-07 08:21:36 +00:00
SkalskiP c46a2e9c08 Merge remote-tracking branch 'origin/segmentation_nms' into segmentation_nms
# Conflicts:
#	supervision/detection/utils.py
2024-02-07 09:21:22 +01:00
SkalskiP 7e44838e51 refactored mask_non_max_suppression 2024-02-07 09:20:54 +01:00
pre-commit-ci[bot] c98dbbf2f6 fix(pre_commit): 🎨 auto format pre-commit hooks 2024-02-07 08:18:54 +00:00
SkalskiP 239f7333f1 refactored mask_non_max_suppression 2024-02-07 09:18:41 +01:00
SkalskiP 35c9ebdd60 refactored mask_non_max_suppression 2024-02-07 08:51:57 +01:00
pre-commit-ci[bot] 879cf6d9dc fix(pre_commit): 🎨 auto format pre-commit hooks 2024-02-07 05:15:10 +00:00
Adonai Vera fd70f3ce5d Applied inclusion-exclusion principle to mask_iou_batch and resize function to improve speed 2024-02-07 00:14:54 -05:00
pre-commit-ci[bot] cf63c838b2 fix(pre_commit): 🎨 auto format pre-commit hooks 2024-02-06 08:55:15 +00:00
SkalskiP 9ee42e5257 mask_iou_batch speed test 2024-02-06 09:54:07 +01:00
dependabot[bot] 9253da570f ⬆️ Bump ruff from 0.2.0 to 0.2.1
Bumps [ruff](https://github.com/astral-sh/ruff) from 0.2.0 to 0.2.1.
- [Release notes](https://github.com/astral-sh/ruff/releases)
- [Changelog](https://github.com/astral-sh/ruff/blob/main/CHANGELOG.md)
- [Commits](https://github.com/astral-sh/ruff/compare/v0.2.0...v0.2.1)

---
updated-dependencies:
- dependency-name: ruff
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-02-06 01:03:21 +00:00
SkalskiP beee1c715d bump version from 0.19.0rc1 to 0.19.0rc2 2024-02-05 23:49:09 +01:00
Christoforos Aristeidou cf14758891 as 2024-02-05 23:46:30 +02:00
Onuralp SEZER d9adc45ca9 Merge pull request #855 from roboflow/pre-commit-ci-update-config
chore(pre_commit): ⬆ pre_commit autoupdate
2024-02-05 21:11:04 +03:00
pre-commit-ci[bot] 24df5aa78e chore(pre_commit): ⬆ pre_commit autoupdate
updates:
- [github.com/astral-sh/ruff-pre-commit: v0.1.14 → v0.2.0](https://github.com/astral-sh/ruff-pre-commit/compare/v0.1.14...v0.2.0)
2024-02-05 17:37:15 +00:00
Onuralp SEZER 4a58c0b726 Merge pull request #852 from roboflow/dependabot/pip/mkdocs-material-9.5.7
⬆️ Bump mkdocs-material from 9.5.6 to 9.5.7
2024-02-05 15:30:44 +03:00
dependabot[bot] 9fc789e6cf ⬆️ Bump mkdocs-material from 9.5.6 to 9.5.7
Bumps [mkdocs-material](https://github.com/squidfunk/mkdocs-material) from 9.5.6 to 9.5.7.
- [Release notes](https://github.com/squidfunk/mkdocs-material/releases)
- [Changelog](https://github.com/squidfunk/mkdocs-material/blob/master/CHANGELOG)
- [Commits](https://github.com/squidfunk/mkdocs-material/compare/9.5.6...9.5.7)

---
updated-dependencies:
- dependency-name: mkdocs-material
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-02-05 00:47:50 +00:00
pre-commit-ci[bot] 1e87a99259 fix(pre_commit): 🎨 auto format pre-commit hooks 2024-02-03 03:19:57 +00:00
Adonai Vera ebe2785287 Removed issue of length sentence 2024-02-02 22:19:40 -05:00
pre-commit-ci[bot] aaf3621841 fix(pre_commit): 🎨 auto format pre-commit hooks 2024-02-03 03:10:29 +00:00
Adonai Vera 6a9c013949 Added nms for segmentation algorithm, added unit test, added init, added withnms conditional depends if contains mask 2024-02-02 21:33:15 -05:00
Onuralp SEZER d423ff3b6c Merge pull request #845 from Kadermiyanyedi/fix-linezone-in-out-values
[LineZone] - flip in/out line crossing directions #838
2024-02-02 20:59:36 +03:00
Adonai Vera 8d702ceccd Remove csv file 2024-02-02 12:59:12 -05:00
Adonai Vera f9caa7db66 Change name csv from json 2024-02-02 12:59:12 -05:00
Adonai Vera 6e32cdb55a allowing to serialise Detections to a JSON file 2024-02-02 12:59:12 -05:00
Kader Miyanyedi 7fae4dbbb8 fix(line_zone): fix in/out values 2024-02-02 20:38:30 +03:00
Piotr Skalski 87a4927d03 Merge pull request #818 from AdonaiVera/allowing_serialise_detections_csv
New function [CSVSink] - allowing to serialise Detections to a CSV file
2024-02-02 18:11:10 +01:00
pre-commit-ci[bot] 6bebd4e70d fix(pre_commit): 🎨 auto format pre-commit hooks 2024-02-02 17:03:05 +00:00
SkalskiP 2e76c66675 Merge remote-tracking branch 'origin/allowing_serialise_detections_csv' into allowing_serialise_detections_csv 2024-02-02 18:02:45 +01:00
SkalskiP d6ee6440ad final tests 2024-02-02 17:52:56 +01:00
pre-commit-ci[bot] abb8daa352 fix(pre_commit): 🎨 auto format pre-commit hooks 2024-02-02 15:45:40 +00:00
SkalskiP ac6f3d6e7c small docs updates 2024-02-02 16:45:05 +01:00
Piotr Skalski 0ccb0b85ad Merge pull request #843 from roboflow/doc/urls-relative-fix
docs(fix): 🐞📝 relative path fix for mike
2024-02-02 13:31:14 +01:00
Onuralp SEZER e3c9ea5ee6 docs(fix): 🐞📝 changelog url fix /0.18.0/annotators/#percentagebarannotator
Signed-off-by: Onuralp SEZER <thunderbirdtr@gmail.com>
2024-02-02 15:21:10 +03:00
Onuralp SEZER 26135bd84d docs(fix): 🐞📝 relative path fix for mike
Signed-off-by: Onuralp SEZER <thunderbirdtr@gmail.com>
2024-02-02 15:15:18 +03:00
Piotr Skalski cdd88dafeb Merge pull request #829 from roboflow/doc/urls-fixes-and-others
docs: ✨ fix url and coc and contributing.md, pythonic features of docs enabled, relative urls added.
2024-02-02 12:53:45 +01:00
Onuralp SEZER 177bcddcd9 Merge pull request #841 from roboflow/dependabot/pip/ruff-0.2.0
⬆️ Bump ruff from 0.1.15 to 0.2.0
2024-02-02 09:12:13 +03:00
dependabot[bot] e9bab7913f ⬆️ Bump ruff from 0.1.15 to 0.2.0
Bumps [ruff](https://github.com/astral-sh/ruff) from 0.1.15 to 0.2.0.
- [Release notes](https://github.com/astral-sh/ruff/releases)
- [Changelog](https://github.com/astral-sh/ruff/blob/main/CHANGELOG.md)
- [Commits](https://github.com/astral-sh/ruff/compare/v0.1.15...v0.2.0)

---
updated-dependencies:
- dependency-name: ruff
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-02-02 00:54:14 +00:00
pre-commit-ci[bot] b1034fe139 fix(pre_commit): 🎨 auto format pre-commit hooks 2024-02-01 23:08:57 +00:00
Adonai Vera e899b428ca Fix length of the line 2024-02-01 18:07:24 -05:00
pre-commit-ci[bot] aba5c0a07b fix(pre_commit): 🎨 auto format pre-commit hooks 2024-02-01 22:56:02 +00:00
Adonai Vera 788bc317fa Improvements in thread #818: documentation, handle unit test, improvements pattern directory 2024-02-01 17:53:15 -05:00
Onuralp SEZER 732aa09059 docs: 📝 linkedin url adjustment
Signed-off-by: Onuralp SEZER <thunderbirdtr@gmail.com>
2024-02-02 01:22:57 +03:00
Onuralp SEZER 671b48df4b docs: 📝 add social discord into footer
Signed-off-by: Onuralp SEZER <thunderbirdtr@gmail.com>
2024-02-02 01:21:44 +03:00
Onuralp SEZER 71a18a12d7 docs: 📝 install and quick start position swapped
Signed-off-by: Onuralp SEZER <thunderbirdtr@gmail.com>
2024-02-01 22:17:25 +03:00
Onuralp SEZER 3576f4f1a1 docs: 📝 versioned based change logs url and old url has been replace with new one
Signed-off-by: Onuralp SEZER <thunderbirdtr@gmail.com>
2024-02-01 22:07:36 +03:00
Onuralp SEZER df9616948b docs(mkdocs): pythonic mkdocs features enabled
Signed-off-by: Onuralp SEZER <thunderbirdtr@gmail.com>
2024-02-01 21:40:20 +03:00
Onuralp SEZER edf35f4c6e docs(link): add relative urls and fix readme urls
Signed-off-by: Onuralp SEZER <thunderbirdtr@gmail.com>
2024-02-01 21:39:57 +03:00
Onuralp SEZER ab5c8cfa68 docs(link): annotators now has proper linking
Signed-off-by: Onuralp SEZER <thunderbirdtr@gmail.com>
2024-02-01 20:23:11 +03:00
Onuralp SEZER 847ebeb7b2 docs(fix): 🐞📝 removal of table of content duplicates for detection metrics
Signed-off-by: Onuralp SEZER <thunderbirdtr@gmail.com>
2024-02-01 20:22:40 +03:00
Onuralp SEZERandPiotr Skalski 7a04a11524 Update docs/how_to/track_objects.md
Co-authored-by: Piotr Skalski <piotr.skalski92@gmail.com>
2024-02-01 18:27:09 +03:00
Piotr Skalski fc3bced56d Merge pull request #832 from roboflow/fix/inference_and_yolo_nas_speed_estimation_examples
fix inference and yolo nas speed estimation examples
2024-02-01 10:30:40 +01:00
SkalskiP 775efd0d41 fix inference and yolo nas speed estimation examples 2024-02-01 10:25:43 +01:00
Piotr Skalski 81d0c3a1a3 Merge pull request #827 from AdonaiVera/add_method_reset_state_tracker
[ByteTrack] - add a method to reset the state of the tracker
2024-02-01 08:46:51 +01:00
SkalskiP ee58e28d25 Small update in reset docstring. 2024-02-01 08:42:36 +01:00
Adonai Vera 889044cf06 Add docs to reset function and reduce the length 2024-02-01 00:37:43 -05:00
Adonai Vera 5f8127a1a5 Add docstring to the reset function 2024-02-01 00:30:48 -05:00
Onuralp SEZER 18c0ec4196 Merge branch 'develop' into doc/urls-fixes-and-others 2024-02-01 00:32:40 +03:00
Piotr Skalski 46426f816a Merge pull request #830 from roboflow/feature/update_fps_monitor_api
Update `FPSMonitor` API
2024-01-31 22:29:29 +01:00
pre-commit-ci[bot] 2280de707b fix(pre_commit): 🎨 auto format pre-commit hooks 2024-01-31 21:27:15 +00:00
Adonai Vera 9da2d9f761 Remove ultralytics example multiple video 2024-01-31 16:26:49 -05:00
SkalskiP da8cc0cbaa documentation updated 2024-01-31 22:25:47 +01:00
Onuralp SEZER 833a9f117d Merge branch 'develop' into doc/urls-fixes-and-others 2024-02-01 00:21:25 +03:00
SkalskiP d00f5e4797 deprecated.md added 2024-02-01 00:18:53 +03:00
pre-commit-ci[bot] b6ddd21cdb fix(pre_commit): 🎨 auto format pre-commit hooks 2024-01-31 21:18:42 +00:00
SkalskiP 92f8fefef1 Merge branch 'develop' into feature/update_fps_monitor_api 2024-01-31 22:18:29 +01:00
SkalskiP 5771a29d33 deprecated.md added 2024-01-31 22:12:54 +01:00
Onuralp SEZER ff3df644c9 Merge branch 'develop' into doc/urls-fixes-and-others 2024-02-01 00:12:17 +03:00
Onuralp SEZER fc5126f352 docs: ✨ docs urls in detection latest tag added
Signed-off-by: Onuralp SEZER <thunderbirdtr@gmail.com>
2024-02-01 00:09:17 +03:00
Piotr Skalski 34af22581e Merge pull request #828 from roboflow/feature/improved-communication-of-deprecated-features
improved communication of deprecated features
2024-01-31 22:05:00 +01:00
pre-commit-ci[bot] 3d2530f3a6 fix(pre_commit): 🎨 auto format pre-commit hooks 2024-01-31 21:02:30 +00:00
SkalskiP 9817598c2c improved communication of deprecated features 2024-01-31 21:59:06 +01:00
pre-commit-ci[bot] bef5fb02d0 fix(pre_commit): 🎨 auto format pre-commit hooks 2024-01-31 20:32:49 +00:00
Adonai Vera 9ba0511610 Change import name 2024-01-31 15:30:03 -05:00
Adonai Vera 6993ca3d71 Reset function to process multiple videos 2024-01-31 15:07:27 -05:00
Onuralp SEZER 163aa785f9 docs: ✨ contributing.md/code_of_conduct/license added into docs
Signed-off-by: Onuralp SEZER <thunderbirdtr@gmail.com>
2024-01-31 22:10:28 +03:00
Onuralp SEZER d009f75c28 docs: 📝 pypi and docker url added to footer
Signed-off-by: Onuralp SEZER <thunderbirdtr@gmail.com>
2024-01-31 21:47:07 +03:00
pre-commit-ci[bot] 91260bdfc9 fix(pre_commit): 🎨 auto format pre-commit hooks 2024-01-31 17:11:18 +00:00
Adonai Vera 4ec353f5c2 Apply format 2024-01-31 12:10:56 -05:00
SkalskiP 173719020e ready for tests 2024-01-31 18:01:42 +01:00
pre-commit-ci[bot] fd00bd4ba2 fix(pre_commit): 🎨 auto format pre-commit hooks 2024-01-31 16:41:57 +00:00
Adonai Vera 12568336ba Applied feedback from SkalskiP in PR #818 2024-01-31 11:39:05 -05:00
Piotr Skalski c692d264ae Merge pull request #823 from roboflow/doc/fix-table-of-content-duplicates
docs(fix): 🐞📝 removal of table of content duplicates
2024-01-31 14:40:03 +01:00
Onuralp SEZER 840fe2c5d5 docs(fix): 🐞📝 removal of table of content duplicates assets and datasets
Signed-off-by: Onuralp SEZER <thunderbirdtr@gmail.com>
2024-01-31 16:33:08 +03:00
Onuralp SEZER 49a30f9830 docs: ✨ Twitter logo updated
Signed-off-by: Onuralp SEZER <thunderbirdtr@gmail.com>
2024-01-31 16:19:23 +03:00
Onuralp SEZER c7501868d0 docs: ✨ Supervision 2024 docs (copyright fix)
Signed-off-by: Onuralp SEZER <thunderbirdtr@gmail.com>
2024-01-31 16:15:43 +03:00
Onuralp SEZER 5f684e717c docs(fix): 🐞📝 removal of table of content duplicates annotators
Signed-off-by: Onuralp SEZER <thunderbirdtr@gmail.com>
2024-01-31 15:58:31 +03:00
Onuralp SEZER 95a19d1c0e docs(fix): 🐞📝 removal of table of content duplicates assets,datasets,trackers,file,utils/(image,notebook,video)
Signed-off-by: Onuralp SEZER <thunderbirdtr@gmail.com>
2024-01-31 15:54:36 +03:00
Onuralp SEZER b81eb85616 docs(fix): 🐞📝 add missing h1 for how tos
Signed-off-by: Onuralp SEZER <thunderbirdtr@gmail.com>
2024-01-31 15:19:51 +03:00
Onuralp SEZER bf9d56215a docs(fix): 🐞📝 removal of table of content duplicates core/geometry
Signed-off-by: Onuralp SEZER <thunderbirdtr@gmail.com>
2024-01-31 15:19:36 +03:00
Onuralp SEZER 31fff6c821 docs(fix): 🐞📝 removal of table of content duplicates utils/draw functions
Signed-off-by: Onuralp SEZER <thunderbirdtr@gmail.com>
2024-01-31 15:18:54 +03:00
Onuralp SEZER 9a3c3fee2f docs(fix): 🐞📝 removal of table of content duplicates Color
Signed-off-by: Onuralp SEZER <thunderbirdtr@gmail.com>
2024-01-31 15:18:41 +03:00
Onuralp SEZER 443edc9760 docs(fix): 🐞📝 removal of table of content duplicates Detection Smoother
Signed-off-by: Onuralp SEZER <thunderbirdtr@gmail.com>
2024-01-31 15:18:19 +03:00
Onuralp SEZER beec044421 docs(fix): 🐞📝 removal of table of content duplicates PolygonZone,PolygonZoneAnnotator
Signed-off-by: Onuralp SEZER <thunderbirdtr@gmail.com>
2024-01-31 15:17:53 +03:00
Onuralp SEZER 1aab21c333 docs(fix): 🐞📝 removal of table of content duplicates LineZone
Signed-off-by: Onuralp SEZER <thunderbirdtr@gmail.com>
2024-01-31 15:15:06 +03:00
Onuralp SEZER 05aed165dc docs(fix): 🐞📝 removal of table of content duplicates InferenceSlicer
Signed-off-by: Onuralp SEZER <thunderbirdtr@gmail.com>
2024-01-31 15:14:11 +03:00
Onuralp SEZER 921b450040 docs(fix): 🐞📝 removal of table of content duplicates Detections/utils
Signed-off-by: Onuralp SEZER <thunderbirdtr@gmail.com>
2024-01-31 15:13:30 +03:00
Onuralp SEZER a8d8ed5cb4 docs(fix): 🐞📝 removal of table of content duplicates core(Detections,Classification)
Signed-off-by: Onuralp SEZER <thunderbirdtr@gmail.com>
2024-01-31 15:09:07 +03:00
Onuralp SEZER c44767cc12 Merge pull request #822 from roboflow/mike-provider-typo-fix
fix: 🐞 version provider typo fix
2024-01-31 14:24:30 +03:00
Onuralp SEZER 947f8d35c4 fix: 🐞 version provider typo fix
Signed-off-by: Onuralp SEZER <thunderbirdtr@gmail.com>
2024-01-31 14:22:21 +03:00
Piotr Skalski eaaa1a83c7 Merge pull request #815 from roboflow/gh-mike-docs-setup
ci: 👷 documentation build via mike for develop tag configuration
2024-01-31 12:05:24 +01:00
Piotr Skalski 0d36d01afc Merge pull request #814 from roboflow/feature/make-from_ultralytics-extract-class-names-from-result
make `from_ultralytics` extract class names from result
2024-01-31 08:30:33 +01:00
SkalskiP fc571cc191 Merge remote-tracking branch 'origin/feature/make-from_ultralytics-extract-class-names-from-result' into feature/make-from_ultralytics-extract-class-names-from-result 2024-01-31 08:28:45 +01:00
SkalskiP c6718d374c update docs 2024-01-31 08:28:34 +01:00
Adonai Vera 5e339f99fc [CSVSink] - allowing to serialise Detections to a CSV file ready for prod 2024-01-31 01:32:49 -05:00
Onuralp SEZER 4b75daaad6 ci: 👷 documentation build via mike for develop tag configuration
Signed-off-by: Onuralp SEZER <thunderbirdtr@gmail.com>
2024-01-31 01:28:22 +03:00
Onuralp SEZER e801879e70 Merge pull request #811 from roboflow/dependabot/pip/ruff-0.1.15
⬆️ Bump ruff from 0.1.14 to 0.1.15
2024-01-31 00:05:55 +03:00
pre-commit-ci[bot] 33b7861c70 fix(pre_commit): 🎨 auto format pre-commit hooks 2024-01-30 17:36:04 +00:00
Onuralp SEZER 5d93ae61ee Merge pull request #813 from Kadermiyanyedi/fix-typos-in-the-changelog-file
Fix typos in the CITATION.cff and changelog.md files
2024-01-30 20:35:51 +03:00
SkalskiP 7f9153e826 initial commit 2024-01-30 18:34:41 +01:00
Kader Miyanyedi a1cc319293 chore(docs): fix typos 2024-01-30 20:16:31 +03:00
Piotr Skalski 6147b6ee03 Merge pull request #802 from Kadermiyanyedi/make-display-values-optional
LineZoneAnnotator make display of int/out values optional
2024-01-30 13:37:27 +01:00
Kader Miyanyedi c285ff68b4 chore(line_zone_annotator): update is_in_count parameter description 2024-01-30 15:32:10 +03:00
Piotr Skalski 5ae3327737 Merge pull request #801 from KingKokouvi/traffic_analysis_0
Refactor class DetectionsManager to handle empty detections_all array
2024-01-30 13:08:38 +01:00
Kader Miyanyedi e0294cd296 refactor(line_zone_annotator): refactor _annotate_count method 2024-01-30 14:28:15 +03:00
Kokouvi 226090aeaf Update inference_example.py
formattig
2024-01-30 11:20:55 +00:00
Kokouvi 0603527bb2 Update inference_example.py
fix formatting
2024-01-30 11:12:54 +00:00
Kokouvi c781a8efa1 Update ultralytics_example.py
adding else statement to return an empty array when there is no detections
2024-01-30 10:58:16 +00:00
Kokouvi 82aa4bb857 Update inference_example.py
Formatting
2024-01-30 10:55:34 +00:00
pre-commit-ci[bot] 6c98e211e5 fix(pre_commit): 🎨 auto format pre-commit hooks 2024-01-30 10:54:00 +00:00
Kokouvi 1e482e172f Update inference_example.py
Adding else statement
2024-01-30 10:53:40 +00:00
dependabot[bot] 499cf7e294 ⬆️ Bump ruff from 0.1.14 to 0.1.15
Bumps [ruff](https://github.com/astral-sh/ruff) from 0.1.14 to 0.1.15.
- [Release notes](https://github.com/astral-sh/ruff/releases)
- [Changelog](https://github.com/astral-sh/ruff/blob/main/CHANGELOG.md)
- [Commits](https://github.com/astral-sh/ruff/compare/v0.1.14...v0.1.15)

---
updated-dependencies:
- dependency-name: ruff
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-01-30 01:00:51 +00:00
Christoforos Aristeidou fbbf147312 added zoom factor, crop of image part and placement on frame 2024-01-30 02:25:21 +02:00
Christoforos Aristeidou 96b52f28fb added attributes and base for annotate() method 2024-01-29 23:36:20 +02:00
Onuralp SEZER 9aaa18865b Merge pull request #810 from roboflow/pre-commit-ci-update-config
chore(pre_commit): ⬆ pre_commit autoupdate
2024-01-30 00:15:55 +03:00
Christoforos Aristeidou c132d5fcf2 added CropAnnotator to __init__() 2024-01-29 22:54:51 +02:00
Christoforos Aristeidou bc24d0ec44 initial doc strings 2024-01-29 22:49:51 +02:00
Christoforos Aristeidou 714937e4bd initial class build 2024-01-29 22:40:33 +02:00
Christoforos Aristeidou c016ea3071 as 2024-01-29 22:38:40 +02:00
Kader Miyanyedi 9210ccf8b7 refactor(line_zone_annotator): use draw_text function in the annotate_count method and add center method to vector 2024-01-29 22:30:34 +03:00
pre-commit-ci[bot] 563a0299a8 chore(pre_commit): ⬆ pre_commit autoupdate
updates:
- [github.com/PyCQA/bandit: 1.7.6 → 1.7.7](https://github.com/PyCQA/bandit/compare/1.7.6...1.7.7)
2024-01-29 17:40:27 +00:00
Piotr Skalski 30db3c3f06 Merge pull request #806 from roboflow/multi-version-docs-prep
feat: ✨ mkdocs multi versioning package and old doc deployment CI disabled
2024-01-29 12:35:05 +01:00
Onuralp SEZER 5cc21bc768 feat: ✨ mkdocs multi versioning package and old doc deployment CI disabled
Signed-off-by: Onuralp SEZER <thunderbirdtr@gmail.com>
2024-01-29 14:30:46 +03:00
Onuralp SEZER 9deea66679 Merge pull request #805 from roboflow/dependabot/pip/pytest-8.0.0
⬆️ bump pytest from 7.4.4 to 8.0.0
2024-01-29 11:31:45 +03:00
Onuralp SEZER cfc086f3ea Merge pull request #804 from roboflow/dependabot/pip/mkdocs-material-9.5.6
⬆️ bump mkdocs-material from 9.5.5 to 9.5.6
2024-01-29 11:31:22 +03:00
dependabot[bot] 28730308a5 ⬆️ bump pytest from 7.4.4 to 8.0.0
---
updated-dependencies:
- dependency-name: pytest
  dependency-type: direct:development
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-01-29 01:22:57 +00:00
dependabot[bot] 89edbcf8ff ⬆️ bump mkdocs-material from 9.5.5 to 9.5.6
---
updated-dependencies:
- dependency-name: mkdocs-material
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
2024-01-29 01:10:27 +00:00
Kader Miyanyedi 598e387f7c feat(line_zone_annotator): make display of int/out values optional 2024-01-28 23:54:37 +03:00
bright1205 2d494893fc Refactor class DetectionsManager to handle empty detections_all array 2024-01-28 16:29:11 +00:00
Piotr Skalski a44c76563e Merge pull request #798 from roboflow/fix/iterating-over-detections-in-detaset-loaders
fix looping over detections in dataset loaders
2024-01-28 09:46:09 +01:00
SkalskiP c41b68e9cb fix looping over detections in dataset loaders 2024-01-28 09:39:26 +01:00
Piotr Skalski 9b21231204 Merge pull request #797 from roboflow/fix/crop_image_docs
small `crop_image` documentation fix
2024-01-28 08:00:17 +01:00
SkalskiP 83fa7d0f2c small crop_image documentation fix 2024-01-28 07:56:41 +01:00
Piotr Skalski fff13d5ef2 Merge pull request #796 from roboflow/tracker-doc-fix
docs: 📝 missing import of numpy and correct variable name in tracker section
2024-01-28 07:54:13 +01:00
Onuralp SEZER 5347b78469 docs: 📝 missing import of numpy and correct variable name in tracker section
Signed-off-by: Onuralp SEZER <thunderbirdtr@gmail.com>
2024-01-28 01:25:35 +03:00
Piotr Skalski 3024ddca83 Merge pull request #776 from roboflow/main
Merge pull request #764 from roboflow/develop
2024-01-25 10:35:54 +01:00
Piotr Skalski 53f4cde18d Merge pull request #764 from roboflow/develop
`supervision-0.18.0` release
2024-01-25 10:33:16 +01:00
Piotr Skalski 181724e2d3 Merge pull request #775 from roboflow/feature/supervision-0-18-0-changelog
`supervision-0.18.0` change log update
2024-01-25 10:31:17 +01:00
pre-commit-ci[bot] 205b2d200a fix(pre_commit): 🎨 auto format pre-commit hooks 2024-01-25 09:29:43 +00:00
SkalskiP 3dcb330822 - version bump from 0.18.0rc4 to 0.18.0
- `supervision-0.18.0` release changelog update
- minot docs changes
2024-01-25 10:27:22 +01:00
SkalskiP 6fa4f25250 bump version from 0.18.0rc3 to 0.18.0rc4 2024-01-24 18:10:56 +01:00
Piotr Skalski 35d5738622 Merge pull request #770 from roboflow/yolov8-obb
feat: ✨ yolov8-obb support and OrientedBoxAnnotator added for obb
2024-01-24 17:50:41 +01:00
pre-commit-ci[bot] 9d56d8a9fe fix(pre_commit): 🎨 auto format pre-commit hooks 2024-01-24 16:47:55 +00:00
SkalskiP c7d7e8b71e Merge remote-tracking branch 'origin/yolov8-obb' into yolov8-obb
# Conflicts:
#	docs/annotators.md
2024-01-24 17:47:41 +01:00
SkalskiP 6565fae1c2 final docs updates 2024-01-24 17:47:11 +01:00
Onuralp SEZER a5bef3b15e docs: 📝 >>>/... removed from obb docs and code example
Signed-off-by: Onuralp SEZER <thunderbirdtr@gmail.com>
2024-01-24 19:31:46 +03:00
SkalskiP 164b9bedce Merge branch 'develop' into yolov8-obb 2024-01-24 16:49:00 +01:00
Piotr Skalski aabe60be6a Merge pull request #774 from roboflow/docs-emojis-fix
fix(docs): 🐞 emoji extension added for show emojis properly
2024-01-24 16:42:19 +01:00
Piotr Skalski 533a8a1aa3 Merge pull request #773 from roboflow/readme-example-docs
docs: 📝 readme >>>/... removed
2024-01-24 16:33:43 +01:00
Onuralp SEZER c7790fdf56 fix(docs): 🐞 emoji extension added for show emojis properly
Signed-off-by: Onuralp SEZER <thunderbirdtr@gmail.com>
2024-01-24 17:53:56 +03:00
Onuralp SEZER dd53cd06b9 docs: 📝 readme >>>/... removed
Signed-off-by: Onuralp SEZER <thunderbirdtr@gmail.com>
2024-01-24 17:43:10 +03:00
Onuralp SEZER 24593b64d5 Removed '>>>' and '...' from docs - Merge PR #761 from RaghavvGupta/improved-code-usability
Removed '>>>' and '...' from examples and docs and improved some indentation.
2024-01-24 17:21:00 +03:00
Piotr Skalski 80b7eecfaf Merge pull request #696 from roboflow/prediction-smoothing
Add Prediction Smoothing
2024-01-24 15:13:13 +01:00
SkalskiP 6b063736d9 Merge remote-tracking branch 'origin/prediction-smoothing' into prediction-smoothing 2024-01-24 15:11:50 +01:00
SkalskiP 7b0d5e729e ready for merge 2024-01-24 15:09:47 +01:00
pre-commit-ci[bot] 7916d6a6a4 fix(pre_commit): 🎨 auto format pre-commit hooks 2024-01-24 14:07:46 +00:00
SkalskiP 79560945f5 ready for merge 2024-01-24 15:07:32 +01:00
Onuralp SEZER d4e0d8d46d docs: 📝 supervision/annotators/core.py PercentageBarAnnotator >>>/... removed
Signed-off-by: Onuralp SEZER <thunderbirdtr@gmail.com>
2024-01-24 15:41:18 +03:00
Onuralp SEZER 5a89e2170f Merge remote-tracking branch 'mainland/develop' into improved-code-usability 2024-01-24 15:39:07 +03:00
Onuralp SEZER ab5a86596f docs: 📝 supervision downloader classfication draw geometry and utils >>>/... removed
Signed-off-by: Onuralp SEZER <thunderbirdtr@gmail.com>
2024-01-24 15:26:43 +03:00
Onuralp SEZER 12b42f80de docs: 📝 supervision/utils/notebook.py >>>/... removed
Signed-off-by: Onuralp SEZER <thunderbirdtr@gmail.com>
2024-01-24 15:17:49 +03:00
Onuralp SEZER 8a5cd1bc3e docs: 📝 supervision/utils/video.py >>>/... removed
Signed-off-by: Onuralp SEZER <thunderbirdtr@gmail.com>
2024-01-24 15:17:29 +03:00
Onuralp SEZER e29e960c5f docs: 📝 supervision/metrics/detection.py >>>/... removed
Signed-off-by: Onuralp SEZER <thunderbirdtr@gmail.com>
2024-01-24 15:14:18 +03:00
pre-commit-ci[bot] f6e5b6dc54 fix(pre_commit): 🎨 auto format pre-commit hooks 2024-01-24 12:06:21 +00:00
SkalskiP e2751368d5 improvements 2024-01-24 13:06:07 +01:00
Onuralp SEZER 955a6d67fb docs: 📝 supervision/tracker/byte_tracker/core.py >>>/... removed
Signed-off-by: Onuralp SEZER <thunderbirdtr@gmail.com>
2024-01-24 13:13:56 +03:00
Onuralp SEZER 833edc95ad docs: 📝 supervision/detection/utils.py >>>/... removed
Signed-off-by: Onuralp SEZER <thunderbirdtr@gmail.com>
2024-01-24 13:10:48 +03:00
Onuralp SEZER 4df21ded6a docs: 📝 supervision/detection/annotate.py >>>/... removed
Signed-off-by: Onuralp SEZER <thunderbirdtr@gmail.com>
2024-01-24 13:03:34 +03:00
Onuralp SEZER f03be21a9f docs: 📝 supervision/dataset/core.py >>>/... removed
Signed-off-by: Onuralp SEZER <thunderbirdtr@gmail.com>
2024-01-24 13:01:55 +03:00
Onuralp SEZER 2d1aa3b996 docs: 📝 supervision/detection/tools/inference_slicer.py >>>/... removed
Signed-off-by: Onuralp SEZER <thunderbirdtr@gmail.com>
2024-01-24 12:52:34 +03:00
Onuralp SEZER 7af914bf56 docs: 📝 supervision/annotators/core.py docs/annotators.md >>>/... removed
Signed-off-by: Onuralp SEZER <thunderbirdtr@gmail.com>
2024-01-24 12:50:23 +03:00
Onuralp SEZER 8872151d0c docs: 📝 core/detection/core.py >>>/... removed
Signed-off-by: Onuralp SEZER <thunderbirdtr@gmail.com>
2024-01-24 12:28:45 +03:00
raghav d961aa9eb4 docs: example image = ... reverted and added annotators.md 2024-01-24 12:05:57 +03:00
raghav 845c9cc2c2 docs: '>>>' and '...' are removed and indentation improvements 2024-01-24 12:05:48 +03:00
Piotr Skalski 4667e02d79 Merge pull request #772 from roboflow/mkdocs-matplotlib-updates
build(deps): 📦 mkdocs-material and matplotlib update for security
2024-01-24 09:07:43 +01:00
Onuralp SEZER 047672d458 build(deps): 📦 mkdocs-material and matplotlib update for security
Signed-off-by: Onuralp SEZER <thunderbirdtr@gmail.com>
2024-01-24 10:51:41 +03:00
Piotr Skalski 2622144660 Merge pull request #771 from roboflow/removal-pillow-reqs
build(deps): 📦 package pillow removed
2024-01-23 20:15:31 +01:00
Onuralp SEZER fb0500c394 build(deps): 📦 package pillow removed
Signed-off-by: Onuralp SEZER <thunderbirdtr@gmail.com>
2024-01-23 21:19:01 +03:00
Onuralp SEZER 10f3b73e79 docs: 📝 OrientedBox Annotator docs added
Signed-off-by: Onuralp SEZER <thunderbirdtr@gmail.com>
2024-01-23 21:07:09 +03:00
Onuralp SEZER 564f979977 Merge branch 'develop' into yolov8-obb 2024-01-23 20:52:07 +03:00
Onuralp SEZER 64302f450c feat: ✨ yolov8-obb support and OrientedBoxAnnotator added for obb
Signed-off-by: Onuralp SEZER <thunderbirdtr@gmail.com>
2024-01-23 20:18:47 +03:00
James Gallagher 626636cfa7 update tracking logic 2024-01-23 17:10:02 +00:00
James Gallagher 21791c8522 remove idle trackers 2024-01-23 13:38:15 +00:00
James Gallagher 24ca25ef94 fix formatting 2024-01-23 13:28:00 +00:00
James 09d771c139 Merge branch 'develop' into prediction-smoothing 2024-01-23 12:59:28 +00:00
James Gallagher 6efd51dfb1 respond to feedback 2024-01-23 12:57:36 +00:00
James Gallagher c299a929c5 respond to feedback 2024-01-23 12:57:31 +00:00
Brad Dwyer 310a09859d Remove unused tracker_length 2023-12-29 11:42:25 -06:00
pre-commit-ci[bot] bf427d5061 fix(pre_commit): 🎨 auto format pre-commit hooks 2023-12-28 18:21:48 +00:00
Brad Dwyer 8ab7cb659c Merge branch 'prediction-smoothing' of https://github.com/roboflow/supervision into prediction-smoothing 2023-12-28 12:21:38 -06:00
Brad Dwyer a58c8ef0fe Add set_length and use deque 2023-12-28 12:21:07 -06:00
pre-commit-ci[bot] 3e0a665ef2 fix(pre_commit): 🎨 auto format pre-commit hooks 2023-12-28 18:04:43 +00:00
Brad Dwyer 3a0682db08 Remove NoneDict and add type hints 2023-12-28 12:04:33 -06:00
Brad Dwyer a36b426dff Merge branch 'develop' into prediction-smoothing 2023-12-28 11:50:15 -06:00
Brad Dwyer 3f77433f2e Merge branch 'prediction-smoothing' of https://github.com/roboflow/supervision into prediction-smoothing 2023-12-28 11:50:12 -06:00
Brad Dwyer 5d1e76fbd0 Update copy based on feedback from James & Piotr 2023-12-28 11:50:06 -06:00
pre-commit-ci[bot] 6600d7533a fix(pre_commit): 🎨 auto format pre-commit hooks 2023-12-28 17:43:55 +00:00
Brad Dwyer 1d4d7dd4ea Move into tools directory 2023-12-28 11:42:55 -06:00
Brad Dwyer d7420c545e Move video to correct spot in the docs 2023-12-27 15:17:28 -06:00
Brad Dwyer 729eb16ea6 Merge branch 'prediction-smoothing' of https://github.com/roboflow/supervision into prediction-smoothing 2023-12-27 15:15:31 -06:00
Brad Dwyer ca6ba30375 Fix linter errors 2023-12-27 15:15:18 -06:00
pre-commit-ci[bot] 7f4b27a556 fix(pre_commit): 🎨 auto format pre-commit hooks 2023-12-27 21:09:26 +00:00
Brad Dwyer ffdab06376 Update Docs 2023-12-27 15:02:02 -06:00
Brad Dwyer b912db7a06 Add Detections Smoother 2023-12-27 14:13:40 -06:00
103 changed files with 12621 additions and 3397 deletions
+31 -10
View File
@@ -1,10 +1,8 @@
name: Docs WorkFlow
name: Docs WorkFlow - Develop Tag 📚
on:
push:
branches:
- master
- main
- develop
permissions:
@@ -16,11 +14,34 @@ jobs:
deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-python@v5
- name: 🔄 Checkout code
uses: actions/checkout@v4
with:
python-version: 3.x
- run: pip install mkdocs-material
- run: pip install "mkdocstrings[python]"
- run: pip install "mkdocs-material[imaging]"
- run: mkdocs gh-deploy --force
fetch-depth: 0
- name: 🐍 Set up Python
uses: actions/setup-python@v5
with:
python-version: '3.10'
- name: 📦 Install mkdocs-material
run: pip install "mkdocs-material[all]"
- name: 📦 Install mkdocstrings[python]
run: pip install "mkdocstrings[python]"
- name: 📦 Install mkdocs-material[imaging]
run: pip install "mkdocs-material[imaging]"
- name: 📦 Install mike
run: pip install "mike"
- name: 📦 Install mkdocs-git-revision-date-localized-plugin
run: pip install "mkdocs-git-revision-date-localized-plugin"
- name: 📦 Install JupyterLab
run: pip install jupyterlab
- name: 📦 Install mkdocs-jupyter
run: pip install mkdocs-jupyter
- name: 📦 Install mkdocs-git-committers-plugin-2
run: pip install mkdocs-git-committers-plugin-2
- name: ⚙️ Configure git for github-actions
run: |
git config --global user.name "github-actions[bot]"
git config --global user.email "41898282+github-actions[bot]@users.noreply.github.com"
- name: 🚀 Deploy MkDoc-Material with mike
run: |
MKDOCS_GIT_COMMITTERS_APIKEY=${{ secrets.GITHUB_TOKEN }} mike deploy --push develop
-2
View File
@@ -3,8 +3,6 @@ on:
push:
tags:
- '[0-9]+.[0-9]+[0-9]+.[0-9]'
- '[0-9]+.[0-9]+[0-9]+.[0-9]'
- '[0-9]+.[0-9]+[0-9]+.[0-9]'
# Allows you to run this workflow manually from the Actions tab
workflow_dispatch:
+34
View File
@@ -0,0 +1,34 @@
name: 🧪 Docs Test WorkFlow 📚
on:
pull_request:
branches: [main, develop]
jobs:
docs-build-test:
runs-on: ubuntu-latest
steps:
- name: 🔄 Checkout code
uses: actions/checkout@v4
- name: 🐍 Set up Python
uses: actions/setup-python@v5
with:
python-version: '3.10'
- name: 📦 Install mkdocs-material
run: pip install "mkdocs-material[all]"
- name: 📦 Install mkdocstrings[python]
run: pip install "mkdocstrings[python]"
- name: 📦 Install mkdocs-material[imaging]
run: pip install "mkdocs-material[imaging]"
- name: 📦 Install mike
run: pip install "mike"
- name: 📦 Install mkdocs-git-revision-date-localized-plugin
run: pip install "mkdocs-git-revision-date-localized-plugin"
- name: 📦 Install JupyterLab
run: pip install jupyterlab
- name: 📦 Install mkdocs-jupyter
run: pip install mkdocs-jupyter
- name: 📦 Install mkdocs-git-committers-plugin-2
run: pip install mkdocs-git-committers-plugin-2
- name: 🧪 Test documentation build
run: mkdocs build --verbose
+1 -1
View File
@@ -37,8 +37,8 @@ jobs:
matplotlib==3.5.0 \
numpy==1.21.2 \
opencv-python==4.5.5.64 \
packaging==23.2 \
Pillow==10.1.0 \
packaging==23.2 \
pluggy==1.3.0 \
pyparsing==3.1.1 \
pytest==7.2.0 \
-3
View File
@@ -133,9 +133,6 @@ dmypy.json
# Pyre type checker
.pyre/
# Notebooks
notebooks/
# OSX folder attributes
.DS_Store
.AppleDouble
+3 -3
View File
@@ -13,7 +13,7 @@ repos:
- id: trailing-whitespace
exclude: test/.*\.py
- id: check-yaml
- id: check-docstring-first
exclude: mkdocs.yml
- id: check-executables-have-shebangs
- id: check-toml
- id: check-case-conflict
@@ -29,7 +29,7 @@ repos:
- repo: https://github.com/PyCQA/bandit
rev: '1.7.6'
rev: '1.7.8'
hooks:
- id: bandit
args: ["-c", "pyproject.toml"]
@@ -46,7 +46,7 @@ repos:
- repo: https://github.com/astral-sh/ruff-pre-commit
rev: v0.1.14
rev: v0.3.2
hooks:
- id: ruff
args: [--fix, --exit-non-zero-on-fix]
+1 -1
View File
@@ -15,7 +15,7 @@ url: 'https://roboflow.github.io/supervision/'
abstract: >-
supervision features a range of utilities for use in
computer vision projects, from detections processing and
filtering to confusion matrix calcuation.
filtering to confusion matrix calculation.
keywords:
- computer vision
- image processing
+15 -1
View File
@@ -52,7 +52,7 @@ git push -u origin main
### Pre-commit tool
This project utilizes the [pre-commit](https://pre-commit.com/) tool to maintain code quality and consistency. Before submitting a pull request or making any commits, it is important to run the pre-commit tool to ensure that your changes meet the project's guidelines.
This project uses the [pre-commit](https://pre-commit.com/) tool to maintain code quality and consistency. Before submitting a pull request or making any commits, it is important to run the pre-commit tool to ensure that your changes meet the project's guidelines.
Furthermore, we have integrated a pre-commit GitHub Action into our workflow. This means that with every pull request opened, the pre-commit checks will be automatically enforced, streamlining the code review process and ensuring that all contributions adhere to our quality standards.
@@ -112,6 +112,20 @@ To run the documentation, install the project requirements with `poetry install
You can learn more about mkdocs on the [mkdocs website](https://www.mkdocs.org/).
## 🧑‍🍳 cookbooks
We are always looking for new examples and cookbooks to add to the `supervision`
documentation. If you have a use case that you think would be helpful to others, please
submit a PR with your example. Here are some guidelines for submitting a new example:
- Create a new notebook in the [`docs/nodebooks`](https://github.com/roboflow/supervision/tree/develop/docs/notebooks) folder.
- Add a link to the new notebook in [`docs/theme/cookbooks.html`](https://github.com/roboflow/supervision/blob/develop/docs/theme/cookbooks.html). Make sure to add the path to the new notebook, as well as a title, labels, author and supervision version.
- Use the [Count Objects Crossing the Line](https://supervision.roboflow.com/develop/notebooks/count-objects-crossing-the-line/) example as a template for your new example.
- Freeze the version of `supervision` you are using.
- Place an appropriate Open in Colab button at the top of the notebook. You can find an example of such a button in the aforementioned `Count Objects Crossing the Line` cookbook.
- Notebook should be self-contained. If you rely on external data ( videos, images, etc.) or libraries, include download and installation commands in the notebook.
- Annotate the code with appropriate comments, including links to the documentation describing each of the tools you have used.
## 🧪 tests
[`pytests`](https://docs.pytest.org/en/7.1.x/) is used to run our tests.
+97 -95
View File
@@ -1,6 +1,6 @@
<div align="center">
<p>
<a align="center" href="" target="_blank">
<a align="center" href="" target="https://supervision.roboflow.com">
<img
width="100%"
src="https://media.roboflow.com/open-source/supervision/rf-supervision-banner.png?updatedAt=1678995927529"
@@ -10,7 +10,7 @@
<br>
[notebooks](https://github.com/roboflow/notebooks) | [inference](https://github.com/roboflow/inference) | [autodistill](https://github.com/autodistill/autodistill) | [collect](https://github.com/roboflow/roboflow-collect)
[notebooks](https://github.com/roboflow/notebooks) | [inference](https://github.com/roboflow/inference) | [autodistill](https://github.com/autodistill/autodistill) | [maestro](https://github.com/roboflow/multimodal-maestro)
<br>
@@ -21,13 +21,15 @@
[![Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/roboflow/supervision/blob/main/demo.ipynb)
[![Gradio](https://img.shields.io/badge/%F0%9F%A4%97%20Hugging%20Face-Spaces-blue)](https://huggingface.co/spaces/Roboflow/Annotators)
[![Discord](https://img.shields.io/discord/1159501506232451173)](https://discord.gg/GbfgXGJ8Bk)
[![Built with Material for MkDocs](https://img.shields.io/badge/Material_for_MkDocs-526CFE?logo=MaterialForMkDocs&logoColor=white)](https://squidfunk.github.io/mkdocs-material/)
</div>
## 👋 hello
**We write your reusable computer vision tools.** Whether you need to load your dataset from your hard drive, draw detections on an image or video, or count how many detections are in a zone. You can count on us! 🤝
[![supervision-hackfest](https://github.com/roboflow/supervision/assets/26109316/c05cc954-b9a6-4ed5-9a52-d0b4b619ff65)](https://github.com/orgs/roboflow/projects/10)
## 💻 install
Pip install the supervision package in a
@@ -43,20 +45,20 @@ Read more about desktop, headless, and local installation in our [guide](https:/
### models
Supervision was designed to be model agnostic. Just plug in any classification, detection, or segmentation model. For your convenience, we have created [connectors](https://supervision.roboflow.com/detection/core/#detections) for the most popular libraries like Ultralytics, Transformers, or MMDetection.
Supervision was designed to be model agnostic. Just plug in any classification, detection, or segmentation model. For your convenience, we have created [connectors](https://supervision.roboflow.com/latest/detection/core/#detections) for the most popular libraries like Ultralytics, Transformers, or MMDetection.
```python
>>> import cv2
>>> import supervision as sv
>>> from ultralytics import YOLO
import cv2
import supervision as sv
from ultralytics import YOLO
>>> image = cv2.imread(...)
>>> model = YOLO('yolov8s.pt')
>>> result = model(image)[0]
>>> detections = sv.Detections.from_ultralytics(result)
image = cv2.imread(...)
model = YOLO('yolov8s.pt')
result = model(image)[0]
detections = sv.Detections.from_ultralytics(result)
>>> len(detections)
5
len(detections)
# 5
```
<details>
@@ -67,17 +69,17 @@ Supervision was designed to be model agnostic. Just plug in any classification,
Running with [Inference](https://github.com/roboflow/inference) requires a [Roboflow API KEY](https://docs.roboflow.com/api-reference/authentication#retrieve-an-api-key).
```python
>>> import cv2
>>> import supervision as sv
>>> from inference.models.utils import get_roboflow_model
import cv2
import supervision as sv
from inference.models.utils import get_roboflow_model
>>> image = cv2.imread(...)
>>> model = get_roboflow_model(model_id="yolov8s-640", api_key=<ROBOFLOW API KEY>)
>>> result = model.infer(image)[0]
>>> detections = sv.Detections.from_inference(result)
image = cv2.imread(...)
model = get_roboflow_model(model_id="yolov8s-640", api_key=<ROBOFLOW API KEY>)
result = model.infer(image)[0]
detections = sv.Detections.from_inference(result)
>>> len(detections)
>>> 5
len(detections)
# 5
```
@@ -85,42 +87,42 @@ Supervision was designed to be model agnostic. Just plug in any classification,
### annotators
Supervision offers a wide range of highly customizable [annotators](https://supervision.roboflow.com/annotators/), allowing you to compose the perfect visualization for your use case.
Supervision offers a wide range of highly customizable [annotators](https://supervision.roboflow.com/latest/annotators/), allowing you to compose the perfect visualization for your use case.
```python
>>> import cv2
>>> import supervision as sv
import cv2
import supervision as sv
>>> image = cv2.imread(...)
>>> detections = sv.Detections(...)
image = cv2.imread(...)
detections = sv.Detections(...)
>>> bounding_box_annotator = sv.BoundingBoxAnnotator()
>>> annotated_frame = bounding_box_annotator.annotate(
... scene=image.copy(),
... detections=detections
... )
bounding_box_annotator = sv.BoundingBoxAnnotator()
annotated_frame = bounding_box_annotator.annotate(
scene=image.copy(),
detections=detections
)
```
https://github.com/roboflow/supervision/assets/26109316/691e219c-0565-4403-9218-ab5644f39bce
### datasets
Supervision provides a set of [utils](https://supervision.roboflow.com/datasets/) that allow you to load, split, merge, and save datasets in one of the supported formats.
Supervision provides a set of [utils](https://supervision.roboflow.com/latest/datasets/) that allow you to load, split, merge, and save datasets in one of the supported formats.
```python
>>> import supervision as sv
import supervision as sv
>>> dataset = sv.DetectionDataset.from_yolo(
... images_directory_path=...,
... annotations_directory_path=...,
... data_yaml_path=...
... )
dataset = sv.DetectionDataset.from_yolo(
images_directory_path=...,
annotations_directory_path=...,
data_yaml_path=...
)
>>> dataset.classes
dataset.classes
['dog', 'person']
>>> len(dataset)
1000
len(dataset)
# 1000
```
<details close>
@@ -129,86 +131,86 @@ Supervision provides a set of [utils](https://supervision.roboflow.com/datasets/
- load
```python
>>> dataset = sv.DetectionDataset.from_yolo(
... images_directory_path=...,
... annotations_directory_path=...,
... data_yaml_path=...
... )
dataset = sv.DetectionDataset.from_yolo(
images_directory_path=...,
annotations_directory_path=...,
data_yaml_path=...
)
>>> dataset = sv.DetectionDataset.from_pascal_voc(
... images_directory_path=...,
... annotations_directory_path=...
... )
dataset = sv.DetectionDataset.from_pascal_voc(
images_directory_path=...,
annotations_directory_path=...
)
>>> dataset = sv.DetectionDataset.from_coco(
... images_directory_path=...,
... annotations_path=...
... )
dataset = sv.DetectionDataset.from_coco(
images_directory_path=...,
annotations_path=...
)
```
- split
```python
>>> train_dataset, test_dataset = dataset.split(split_ratio=0.7)
>>> test_dataset, valid_dataset = test_dataset.split(split_ratio=0.5)
train_dataset, test_dataset = dataset.split(split_ratio=0.7)
test_dataset, valid_dataset = test_dataset.split(split_ratio=0.5)
>>> len(train_dataset), len(test_dataset), len(valid_dataset)
(700, 150, 150)
len(train_dataset), len(test_dataset), len(valid_dataset)
# (700, 150, 150)
```
- merge
```python
>>> ds_1 = sv.DetectionDataset(...)
>>> len(ds_1)
100
>>> ds_1.classes
['dog', 'person']
ds_1 = sv.DetectionDataset(...)
len(ds_1)
# 100
ds_1.classes
# ['dog', 'person']
>>> ds_2 = sv.DetectionDataset(...)
>>> len(ds_2)
200
>>> ds_2.classes
['cat']
ds_2 = sv.DetectionDataset(...)
len(ds_2)
# 200
ds_2.classes
# ['cat']
>>> ds_merged = sv.DetectionDataset.merge([ds_1, ds_2])
>>> len(ds_merged)
300
>>> ds_merged.classes
['cat', 'dog', 'person']
ds_merged = sv.DetectionDataset.merge([ds_1, ds_2])
len(ds_merged)
# 300
ds_merged.classes
# ['cat', 'dog', 'person']
```
- save
```python
>>> dataset.as_yolo(
... images_directory_path=...,
... annotations_directory_path=...,
... data_yaml_path=...
... )
dataset.as_yolo(
images_directory_path=...,
annotations_directory_path=...,
data_yaml_path=...
)
>>> dataset.as_pascal_voc(
... images_directory_path=...,
... annotations_directory_path=...
... )
dataset.as_pascal_voc(
images_directory_path=...,
annotations_directory_path=...
)
>>> dataset.as_coco(
... images_directory_path=...,
... annotations_path=...
... )
dataset.as_coco(
images_directory_path=...,
annotations_path=...
)
```
- convert
```python
>>> sv.DetectionDataset.from_yolo(
... images_directory_path=...,
... annotations_directory_path=...,
... data_yaml_path=...
... ).as_pascal_voc(
... images_directory_path=...,
... annotations_directory_path=...
... )
sv.DetectionDataset.from_yolo(
images_directory_path=...,
annotations_directory_path=...,
data_yaml_path=...
).as_pascal_voc(
images_directory_path=...,
annotations_directory_path=...
)
```
</details>
Vendored
+1294 -1292
View File
File diff suppressed because one or more lines are too long
+234 -168
View File
@@ -1,20 +1,23 @@
---
comments: true
status: new
---
# Annotators
=== "BoundingBox"
```python
>>> import supervision as sv
import supervision as sv
>>> image = ...
>>> detections = sv.Detections(...)
image = ...
detections = sv.Detections(...)
>>> bounding_box_annotator = sv.BoundingBoxAnnotator()
>>> annotated_frame = bounding_box_annotator.annotate(
... scene=image.copy(),
... detections=detections
... )
bounding_box_annotator = sv.BoundingBoxAnnotator()
annotated_frame = bounding_box_annotator.annotate(
scene=image.copy(),
detections=detections
)
```
<div class="result" markdown>
@@ -26,16 +29,16 @@ comments: true
=== "RoundBox"
```python
>>> import supervision as sv
import supervision as sv
>>> image = ...
>>> detections = sv.Detections(...)
image = ...
detections = sv.Detections(...)
>>> round_box_annotator = sv.RoundBoxAnnotator()
>>> annotated_frame = round_box_annotator.annotate(
... scene=image.copy(),
... detections=detections
... )
round_box_annotator = sv.RoundBoxAnnotator()
annotated_frame = round_box_annotator.annotate(
scene=image.copy(),
detections=detections
)
```
<div class="result" markdown>
@@ -47,16 +50,16 @@ comments: true
=== "BoxCorner"
```python
>>> import supervision as sv
import supervision as sv
>>> image = ...
>>> detections = sv.Detections(...)
image = ...
detections = sv.Detections(...)
>>> corner_annotator = sv.BoxCornerAnnotator()
>>> annotated_frame = corner_annotator.annotate(
... scene=image.copy(),
... detections=detections
... )
corner_annotator = sv.BoxCornerAnnotator()
annotated_frame = corner_annotator.annotate(
scene=image.copy(),
detections=detections
)
```
<div class="result" markdown>
@@ -68,16 +71,16 @@ comments: true
=== "Color"
```python
>>> import supervision as sv
import supervision as sv
>>> image = ...
>>> detections = sv.Detections(...)
image = ...
detections = sv.Detections(...)
>>> color_annotator = sv.ColorAnnotator()
>>> annotated_frame = color_annotator.annotate(
... scene=image.copy(),
... detections=detections
... )
color_annotator = sv.ColorAnnotator()
annotated_frame = color_annotator.annotate(
scene=image.copy(),
detections=detections
)
```
<div class="result" markdown>
@@ -89,16 +92,16 @@ comments: true
=== "Circle"
```python
>>> import supervision as sv
import supervision as sv
>>> image = ...
>>> detections = sv.Detections(...)
image = ...
detections = sv.Detections(...)
>>> circle_annotator = sv.CircleAnnotator()
>>> annotated_frame = circle_annotator.annotate(
... scene=image.copy(),
... detections=detections
... )
circle_annotator = sv.CircleAnnotator()
annotated_frame = circle_annotator.annotate(
scene=image.copy(),
detections=detections
)
```
<div class="result" markdown>
@@ -110,16 +113,16 @@ comments: true
=== "Dot"
```python
>>> import supervision as sv
import supervision as sv
>>> image = ...
>>> detections = sv.Detections(...)
image = ...
detections = sv.Detections(...)
>>> dot_annotator = sv.DotAnnotator()
>>> annotated_frame = dot_annotator.annotate(
... scene=image.copy(),
... detections=detections
... )
dot_annotator = sv.DotAnnotator()
annotated_frame = dot_annotator.annotate(
scene=image.copy(),
detections=detections
)
```
<div class="result" markdown>
@@ -131,16 +134,16 @@ comments: true
=== "Triangle"
```python
>>> import supervision as sv
import supervision as sv
>>> image = ...
>>> detections = sv.Detections(...)
image = ...
detections = sv.Detections(...)
>>> triangle_annotator = sv.TriangleAnnotator()
>>> annotated_frame = triangle_annotator.annotate(
... scene=image.copy(),
... detections=detections
... )
triangle_annotator = sv.TriangleAnnotator()
annotated_frame = triangle_annotator.annotate(
scene=image.copy(),
detections=detections
)
```
<div class="result" markdown>
@@ -152,16 +155,16 @@ comments: true
=== "Ellipse"
```python
>>> import supervision as sv
import supervision as sv
>>> image = ...
>>> detections = sv.Detections(...)
image = ...
detections = sv.Detections(...)
>>> ellipse_annotator = sv.EllipseAnnotator()
>>> annotated_frame = ellipse_annotator.annotate(
... scene=image.copy(),
... detections=detections
... )
ellipse_annotator = sv.EllipseAnnotator()
annotated_frame = ellipse_annotator.annotate(
scene=image.copy(),
detections=detections
)
```
<div class="result" markdown>
@@ -173,16 +176,16 @@ comments: true
=== "Halo"
```python
>>> import supervision as sv
import supervision as sv
>>> image = ...
>>> detections = sv.Detections(...)
image = ...
detections = sv.Detections(...)
>>> halo_annotator = sv.HaloAnnotator()
>>> annotated_frame = halo_annotator.annotate(
... scene=image.copy(),
... detections=detections
... )
halo_annotator = sv.HaloAnnotator()
annotated_frame = halo_annotator.annotate(
scene=image.copy(),
detections=detections
)
```
<div class="result" markdown>
@@ -194,16 +197,16 @@ comments: true
=== "PercentageBar"
```python
>>> import supervision as sv
import supervision as sv
>>> image = ...
>>> detections = sv.Detections(...)
image = ...
detections = sv.Detections(...)
>>> percentage_bar_annotator = sv.PercentageBarAnnotator()
>>> annotated_frame = percentage_bar_annotator.annotate(
... scene=image.copy(),
... detections=detections
... )
percentage_bar_annotator = sv.PercentageBarAnnotator()
annotated_frame = percentage_bar_annotator.annotate(
scene=image.copy(),
detections=detections
)
```
<div class="result" markdown>
@@ -215,16 +218,16 @@ comments: true
=== "Mask"
```python
>>> import supervision as sv
import supervision as sv
>>> image = ...
>>> detections = sv.Detections(...)
image = ...
detections = sv.Detections(...)
>>> mask_annotator = sv.MaskAnnotator()
>>> annotated_frame = mask_annotator.annotate(
... scene=image.copy(),
... detections=detections
... )
mask_annotator = sv.MaskAnnotator()
annotated_frame = mask_annotator.annotate(
scene=image.copy(),
detections=detections
)
```
<div class="result" markdown>
@@ -236,16 +239,16 @@ comments: true
=== "Polygon"
```python
>>> import supervision as sv
import supervision as sv
>>> image = ...
>>> detections = sv.Detections(...)
image = ...
detections = sv.Detections(...)
>>> polygon_annotator = sv.PolygonAnnotator()
>>> annotated_frame = polygon_annotator.annotate(
... scene=image.copy(),
... detections=detections
... )
polygon_annotator = sv.PolygonAnnotator()
annotated_frame = polygon_annotator.annotate(
scene=image.copy(),
detections=detections
)
```
<div class="result" markdown>
@@ -257,16 +260,16 @@ comments: true
=== "Label"
```python
>>> import supervision as sv
import supervision as sv
>>> image = ...
>>> detections = sv.Detections(...)
image = ...
detections = sv.Detections(...)
>>> label_annotator = sv.LabelAnnotator(text_position=sv.Position.CENTER)
>>> annotated_frame = label_annotator.annotate(
... scene=image.copy(),
... detections=detections
... )
label_annotator = sv.LabelAnnotator(text_position=sv.Position.CENTER)
annotated_frame = label_annotator.annotate(
scene=image.copy(),
detections=detections
)
```
<div class="result" markdown>
@@ -275,19 +278,34 @@ comments: true
</div>
=== "Crop"
```python
import supervision as sv
image = ...
detections = sv.Detections(...)
crop_annotator = sv.CropAnnotator()
annotated_frame = crop_annotator.annotate(
scene=image.copy(),
detections=detections
)
```
=== "Blur"
```python
>>> import supervision as sv
import supervision as sv
>>> image = ...
>>> detections = sv.Detections(...)
image = ...
detections = sv.Detections(...)
>>> blur_annotator = sv.BlurAnnotator()
>>> annotated_frame = blur_annotator.annotate(
... scene=image.copy(),
... detections=detections
... )
blur_annotator = sv.BlurAnnotator()
annotated_frame = blur_annotator.annotate(
scene=image.copy(),
detections=detections
)
```
<div class="result" markdown>
@@ -299,16 +317,16 @@ comments: true
=== "Pixelate"
```python
>>> import supervision as sv
import supervision as sv
>>> image = ...
>>> detections = sv.Detections(...)
image = ...
detections = sv.Detections(...)
>>> pixelate_annotator = sv.PixelateAnnotator()
>>> annotated_frame = pixelate_annotator.annotate(
... scene=image.copy(),
... detections=detections
... )
pixelate_annotator = sv.PixelateAnnotator()
annotated_frame = pixelate_annotator.annotate(
scene=image.copy(),
detections=detections
)
```
<div class="result" markdown>
@@ -320,26 +338,26 @@ comments: true
=== "Trace"
```python
>>> import supervision as sv
>>> from ultralytics import YOLO
import supervision as sv
from ultralytics import YOLO
>>> model = YOLO('yolov8x.pt')
model = YOLO('yolov8x.pt')
>>> trace_annotator = sv.TraceAnnotator()
trace_annotator = sv.TraceAnnotator()
>>> video_info = sv.VideoInfo.from_video_path(video_path='...')
>>> frames_generator = get_video_frames_generator(source_path='...')
>>> tracker = sv.ByteTrack()
video_info = sv.VideoInfo.from_video_path(video_path='...')
frames_generator = get_video_frames_generator(source_path='...')
tracker = sv.ByteTrack()
>>> with sv.VideoSink(target_path='...', video_info=video_info) as sink:
... for frame in frames_generator:
... result = model(frame)[0]
... detections = sv.Detections.from_ultralytics(result)
... detections = tracker.update_with_detections(detections)
... annotated_frame = trace_annotator.annotate(
... scene=frame.copy(),
... detections=detections)
... sink.write_frame(frame=annotated_frame)
with sv.VideoSink(target_path='...', video_info=video_info) as sink:
for frame in frames_generator:
result = model(frame)[0]
detections = sv.Detections.from_ultralytics(result)
detections = tracker.update_with_detections(detections)
annotated_frame = trace_annotator.annotate(
scene=frame.copy(),
detections=detections)
sink.write_frame(frame=annotated_frame)
```
<div class="result" markdown>
@@ -351,24 +369,24 @@ comments: true
=== "HeatMap"
```python
>>> import supervision as sv
>>> from ultralytics import YOLO
import supervision as sv
from ultralytics import YOLO
>>> model = YOLO('yolov8x.pt')
model = YOLO('yolov8x.pt')
>>> heat_map_annotator = sv.HeatMapAnnotator()
heat_map_annotator = sv.HeatMapAnnotator()
>>> video_info = sv.VideoInfo.from_video_path(video_path='...')
>>> frames_generator = get_video_frames_generator(source_path='...')
video_info = sv.VideoInfo.from_video_path(video_path='...')
frames_generator = get_video_frames_generator(source_path='...')
>>> with sv.VideoSink(target_path='...', video_info=video_info) as sink:
... for frame in frames_generator:
... result = model(frame)[0]
... detections = sv.Detections.from_ultralytics(result)
... annotated_frame = heat_map_annotator.annotate(
... scene=frame.copy(),
... detections=detections)
... sink.write_frame(frame=annotated_frame)
with sv.VideoSink(target_path='...', video_info=video_info) as sink:
for frame in frames_generator:
result = model(frame)[0]
detections = sv.Detections.from_ultralytics(result)
annotated_frame = heat_map_annotator.annotate(
scene=frame.copy(),
detections=detections)
sink.write_frame(frame=annotated_frame)
```
<div class="result" markdown>
@@ -377,74 +395,122 @@ comments: true
</div>
## BoundingBoxAnnotator
<div class="md-typeset">
<h2><a href="#supervision.annotators.core.BoundingBoxAnnotator">BoundingBoxAnnotator</a></h2>
</div>
:::supervision.annotators.core.BoundingBoxAnnotator
## RoundBoxAnnotator
<div class="md-typeset">
<h2><a href="#supervision.annotators.core.RoundBoxAnnotator">RoundBoxAnnotator</a></h2>
</div>
:::supervision.annotators.core.RoundBoxAnnotator
## BoxCornerAnnotator
<div class="md-typeset">
<h2><a href="#supervision.annotators.core.BoxCornerAnnotator">BoxCornerAnnotator</a></h2>
</div>
:::supervision.annotators.core.BoxCornerAnnotator
## ColorAnnotator
<div class="md-typeset">
<h2><a href="#supervision.annotators.core.OrientedBoxAnnotator">OrientedBoxAnnotator</a></h2>
</div>
:::supervision.annotators.core.OrientedBoxAnnotator
<div class="md-typeset">
<h2><a href="#supervision.annotators.core.ColorAnnotator">ColorAnnotator</a></h2>
</div>
:::supervision.annotators.core.ColorAnnotator
## CircleAnnotator
<div class="md-typeset">
<h2><a href="#supervision.annotators.core.CircleAnnotator">CircleAnnotator</a></h2>
</div>
:::supervision.annotators.core.CircleAnnotator
## DotAnnotator
<div class="md-typeset">
<h2><a href="#supervision.annotators.core.DotAnnotator">DotAnnotator</a></h2>
</div>
:::supervision.annotators.core.DotAnnotator
## TriangleAnnotator
<div class="md-typeset">
<h2><a href="#supervision.annotators.core.TriangleAnnotator">TriangleAnnotator</a></h2>
</div>
:::supervision.annotators.core.TriangleAnnotator
## EllipseAnnotator
<div class="md-typeset">
<h2><a href="#supervision.annotators.core.EllipseAnnotator">EllipseAnnotator</a></h2>
</div>
:::supervision.annotators.core.EllipseAnnotator
## HaloAnnotator
<div class="md-typeset">
<h2><a href="#supervision.annotators.core.HaloAnnotator">HaloAnnotator</a></h2>
</div>
:::supervision.annotators.core.HaloAnnotator
## PercentageBarAnnotator
<div class="md-typeset">
<h2><a href="#supervision.annotators.core.PercentageBarAnnotator">PercentageBarAnnotator</a></h2>
</div>
:::supervision.annotators.core.PercentageBarAnnotator
## HeatMapAnnotator
<div class="md-typeset">
<h2><a href="#supervision.annotators.core.HeatMapAnnotator">HeatMapAnnotator</a></h2>
</div>
:::supervision.annotators.core.HeatMapAnnotator
## MaskAnnotator
<div class="md-typeset">
<h2><a href="#supervision.annotators.core.MaskAnnotator">MaskAnnotator</a></h2>
</div>
:::supervision.annotators.core.MaskAnnotator
## PolygonAnnotator
<div class="md-typeset">
<h2><a href="#supervision.annotators.core.PolygonAnnotator">PolygonAnnotator</a></h2>
</div>
:::supervision.annotators.core.PolygonAnnotator
## LabelAnnotator
<div class="md-typeset">
<h2><a href="#supervision.annotators.core.LabelAnnotator">LabelAnnotator</a></h2>
</div>
:::supervision.annotators.core.LabelAnnotator
## BlurAnnotator
<div class="md-typeset">
<h2><a href="#supervision.annotators.core.BlurAnnotator">BlurAnnotator</a></h2>
</div>
:::supervision.annotators.core.BlurAnnotator
## PixelateAnnotator
<div class="md-typeset">
<h2><a href="#supervision.annotators.core.PixelateAnnotator">PixelateAnnotator</a></h2>
</div>
:::supervision.annotators.core.PixelateAnnotator
## TraceAnnotator
<div class="md-typeset">
<h2><a href="#supervision.annotators.core.TraceAnnotator">TraceAnnotator</a></h2>
</div>
:::supervision.annotators.core.TraceAnnotator
## ColorLookup
<div class="md-typeset">
<h2><a href="#supervision.annotators.core.CropAnnotator">CropAnnotator</a></h2>
</div>
:::supervision.annotators.core.CropAnnotator
<div class="md-typeset">
<h2><a href="#supervision.annotators.core.ColorLookup">ColorLookup</a></h2>
</div>
:::supervision.annotators.utils.ColorLookup
+10 -4
View File
@@ -2,10 +2,12 @@
comments: true
---
# Assets
Supervision offers an assets download utility that allows you to download video files
that you can use in your demos.
## install extra
## Install extra
To install the Supervision assets utility, you can use `pip`. This utility is available
as an extra within the Supervision package.
@@ -13,13 +15,17 @@ as an extra within the Supervision package.
!!! example "pip install"
```bash
pip install supervision[assets]
pip install "supervision[assets]"
```
## download_assets
<div class="md-typeset">
<h2>download_assets</h2>
</div>
:::supervision.assets.downloader.download_assets
## VideoAssets
<div class="md-typeset">
<h2>VideoAssets</h2>
</div>
:::supervision.assets.list.VideoAssets
+227 -73
View File
@@ -1,10 +1,164 @@
### 0.19.0 <small>March 15, 2024</small>
- Added [#818](https://github.com/roboflow/supervision/pull/818): [`sv.CSVSink`](/0.19.0/detection/tools/save_detections/#supervision.detection.tools.csv_sink.CSVSink) allowing for the straightforward saving of image, video, or stream inference results in a `.csv` file.
```python
import supervision as sv
from ultralytics import YOLO
model = YOLO(<SOURCE_MODEL_PATH>)
csv_sink = sv.CSVSink(<RESULT_CSV_FILE_PATH>)
frames_generator = sv.get_video_frames_generator(<SOURCE_VIDEO_PATH>)
with csv_sink:
for frame in frames_generator:
result = model(frame)[0]
detections = sv.Detections.from_ultralytics(result)
csv_sink.append(detections, custom_data={<CUSTOM_LABEL>:<CUSTOM_DATA>})
```
- Added [#819](https://github.com/roboflow/supervision/pull/819): [`sv.JSONSink`](/0.19.0/detection/tools/save_detections/#supervision.detection.tools.csv_sink.JSONSink) allowing for the straightforward saving of image, video, or stream inference results in a `.json` file.
```python
```python
import supervision as sv
from ultralytics import YOLO
model = YOLO(<SOURCE_MODEL_PATH>)
json_sink = sv.JSONSink(<RESULT_JSON_FILE_PATH>)
frames_generator = sv.get_video_frames_generator(<SOURCE_VIDEO_PATH>)
with json_sink:
for frame in frames_generator:
result = model(frame)[0]
detections = sv.Detections.from_ultralytics(result)
json_sink.append(detections, custom_data={<CUSTOM_LABEL>:<CUSTOM_DATA>})
```
- Added [#847](https://github.com/roboflow/supervision/pull/847): [`sv.mask_iou_batch`](/0.19.0/detection/utils/#supervision.detection.utils.mask_iou_batch) allowing to compute Intersection over Union (IoU) of two sets of masks.
- Added [#847](https://github.com/roboflow/supervision/pull/847): [`sv.mask_non_max_suppression`](/0.19.0/detection/utils/#supervision.detection.utils.mask_non_max_suppression) allowing to perform Non-Maximum Suppression (NMS) on segmentation predictions.
- Added [#888](https://github.com/roboflow/supervision/pull/888): [`sv.CropAnnotator`](/0.19.0/annotators/#supervision.annotators.core.CropAnnotator) allowing users to annotate the scene with scaled-up crops of detections.
```python
import cv2
import supervision as sv
from inference import get_model
image = cv2.imread(<SOURCE_IMAGE_PATH>)
model = get_model(model_id="yolov8n-640")
result = model.infer(image)[0]
detections = sv.Detections.from_inference(result)
crop_annotator = sv.CropAnnotator()
annotated_frame = crop_annotator.annotate(
scene=image.copy(),
detections=detections
)
```
- Changed [#827](https://github.com/roboflow/supervision/pull/827): [`sv.ByteTrack.reset`](/0.19.0/tracking/#supervision.tracking.ByteTrack.reset) allowing users to clear trackers state, enabling the processing of multiple video files in sequence.
- Changed [#802](https://github.com/roboflow/supervision/pull/802): [`sv.LineZoneAnnotator`](/0.19.0/detection/tools/line_zone/#supervision.detection.line_zone.LineZone) allowing to hide in/out count using `display_in_count` and `display_out_count` properties.
- Changed [#787](https://github.com/roboflow/supervision/pull/787): [`sv.ByteTrack`](/0.19.0/tracking/#supervision.tracking.ByteTrack) input arguments and docstrings updated to improve readability and ease of use.
!!! failure "Deprecated"
The `track_buffer`, `track_thresh`, and `match_thresh` parameters in `sv.ByterTrack` are deprecated and will be removed in `supervision-0.23.0`. Use `lost_track_buffer,` `track_activation_threshold`, and `minimum_matching_threshold` instead.
- Changed [#910](https://github.com/roboflow/supervision/pull/910): [`sv.PolygonZone`](/0.19.0/detection/tools/polygon_zone/#supervision.detection.tools.polygon_zone.PolygonZone) to now accept a list of specific box anchors that must be in zone for a detection to be counted.
!!! failure "Deprecated"
The `triggering_position ` parameter in `sv.PolygonZone` is deprecated and will be removed in `supervision-0.23.0`. Use `triggering_anchors` instead.
- Changed [#875](https://github.com/roboflow/supervision/pull/875): annotators adding support for Pillow images. All supervision Annotators can now accept an image as either a numpy array or a Pillow Image. They automatically detect its type, draw annotations, and return the output in the same format as the input.
- Fixed [#944](https://github.com/roboflow/supervision/pull/944): [`sv.DetectionsSmoother`](/0.19.0/detection/tools/smoother/#supervision.detection.tools.smoother.DetectionsSmoother) removing `tracking_id` from `sv.Detections`.
### 0.18.0 <small>January 25, 2024</small>
- Added [#720](https://github.com/roboflow/supervision/pull/720): [`sv.PercentageBarAnnotator`](/0.18.0/annotators/#percentagebarannotator) allowing to annotate images and videos with percentage values representing confidence or other custom property.
```python
>>> import supervision as sv
>>> image = ...
>>> detections = sv.Detections(...)
>>> percentage_bar_annotator = sv.PercentageBarAnnotator()
>>> annotated_frame = percentage_bar_annotator.annotate(
... scene=image.copy(),
... detections=detections
... )
```
- Added [#702](https://github.com/roboflow/supervision/pull/702): [`sv.RoundBoxAnnotator`](/0.18.0/annotators/#roundboxannotator) allowing to annotate images and videos with rounded corners bounding boxes.
- Added [#770](https://github.com/roboflow/supervision/pull/770): [`sv.OrientedBoxAnnotator`](/0.18.0/annotators/#orientedboxannotator) allowing to annotate images and videos with OBB (Oriented Bounding Boxes).
```python
import cv2
import supervision as sv
from ultralytics import YOLO
image = cv2.imread(<SOURCE_IMAGE_PATH>)
model = YOLO("yolov8n-obb.pt")
result = model(image)[0]
detections = sv.Detections.from_ultralytics(result)
oriented_box_annotator = sv.OrientedBoxAnnotator()
annotated_frame = oriented_box_annotator.annotate(
scene=image.copy(),
detections=detections
)
```
- Added [#696](https://github.com/roboflow/supervision/pull/696): [`sv.DetectionsSmoother`](/0.18.0/detection/tools/smoother/#detection-smoother) allowing for smoothing detections over multiple frames in video tracking.
- Added [#769](https://github.com/roboflow/supervision/pull/769): [`sv.ColorPalette.from_matplotlib`](/0.18.0/draw/color/#supervision.draw.color.ColorPalette.from_matplotlib) allowing users to create a `sv.ColorPalette` instance from a Matplotlib color palette.
```python
>>> import supervision as sv
>>> sv.ColorPalette.from_matplotlib('viridis', 5)
ColorPalette(colors=[Color(r=68, g=1, b=84), Color(r=59, g=82, b=139), ...])
```
- Changed [#770](https://github.com/roboflow/supervision/pull/770): [`sv.Detections.from_ultralytics`](/0.18.0/detection/core/#supervision.detection.core.Detections.from_ultralytics) adding support for OBB (Oriented Bounding Boxes).
- Changed [#735](https://github.com/roboflow/supervision/pull/735): [`sv.LineZone`](/0.18.0/detection/tools/line_zone/#linezone) to now accept a list of specific box anchors that must cross the line for a detection to be counted. This update marks a significant improvement from the previous requirement, where all four box corners were necessary. Users can now specify a single anchor, such as `sv.Position.BOTTOM_CENTER`, or any other combination of anchors defined as `List[sv.Position]`.
- Changed [#756](https://github.com/roboflow/supervision/pull/756): [`sv.Color`](/0.18.0/draw/color/#color)'s and [`sv.ColorPalette`](/0.18.0/draw/color/#colorpalette)'s method of accessing predefined colors, transitioning from a function-based approach (`sv.Color.red()`) to a more intuitive and conventional property-based method (`sv.Color.RED`).
!!! failure "Deprecated"
`sv.ColorPalette.default()` is deprecated and will be removed in `supervision-0.22.0`. Use `sv.ColorPalette.DEFAULT` instead.
- Changed [#769](https://github.com/roboflow/supervision/pull/769): [`sv.ColorPalette.DEFAULT`](/0.18.0/draw/color/#colorpalette) value, giving users a more extensive set of annotation colors.
- Changed [#677](https://github.com/roboflow/supervision/pull/677): `sv.Detections.from_roboflow` to [`sv.Detections.from_inference`](/0.18.0/detection/core/#supervision.detection.core.Detections.from_inference) streamlining its functionality to be compatible with both the both [inference](https://github.com/roboflow/inference) pip package and the Robloflow [hosted API](https://docs.roboflow.com/deploy/hosted-api).
!!! failure "Deprecated"
`Detections.from_roboflow()` is deprecated and will be removed in `supervision-0.22.0`. Use `Detections.from_inference` instead.
- Fixed [#735](https://github.com/roboflow/supervision/pull/735): [`sv.LineZone`](/0.18.0/detection/tools/line_zone/#linezone) functionality to accurately update the counter when an object crosses a line from any direction, including from the side. This enhancement enables more precise tracking and analytics, such as calculating individual in/out counts for each lane on the road.
### 0.17.0 <small>December 06, 2023</small>
- Added [#633](https://github.com/roboflow/supervision/pull/633): [`sv.PixelateAnnotator`](https://supervision.roboflow.com/annotators/#supervision.annotators.core.PixelateAnnotator) allowing to pixelate objects on images and videos.
- Added [#633](https://github.com/roboflow/supervision/pull/633): [`sv.PixelateAnnotator`](/0.17.0/annotators/#supervision.annotators.core.PixelateAnnotator) allowing to pixelate objects on images and videos.
- Added [#652](https://github.com/roboflow/supervision/pull/652): [`sv.TriangleAnnotator`](https://supervision.roboflow.com/annotators/#supervision.annotators.core.TriangleAnnotator) allowing to annotate images and videos with triangle markers.
- Added [#652](https://github.com/roboflow/supervision/pull/652): [`sv.TriangleAnnotator`](/0.17.0/annotators/#supervision.annotators.core.TriangleAnnotator) allowing to annotate images and videos with triangle markers.
- Added [#602](https://github.com/roboflow/supervision/pull/602): [`sv.PolygonAnnotator`](https://supervision.roboflow.com/annotators/#supervision.annotators.core.PolygonAnnotator) allowing to annotate images and videos with segmentation mask outline.
- Added [#602](https://github.com/roboflow/supervision/pull/602): [`sv.PolygonAnnotator`](/0.17.0/annotators/#supervision.annotators.core.PolygonAnnotator) allowing to annotate images and videos with segmentation mask outline.
```python
>>> import supervision as sv
@@ -19,7 +173,7 @@
... )
```
- Added [#476](https://github.com/roboflow/supervision/pull/476): [`sv.assets`](https://supervision.roboflow.com/assets/) allowing download of video files that you can use in your demos.
- Added [#476](https://github.com/roboflow/supervision/pull/476): [`sv.assets`](/0.18.0/assets/) allowing download of video files that you can use in your demos.
```python
>>> from supervision.assets import download_assets, VideoAssets
@@ -27,35 +181,35 @@
"vehicles.mp4"
```
- Added [#605](https://github.com/roboflow/supervision/pull/605): [`Position.CENTER_OF_MASS`](https://supervision.roboflow.com/geometry/core/#position) allowing to place labels in center of mass of segmentation masks.
- Added [#605](https://github.com/roboflow/supervision/pull/605): [`Position.CENTER_OF_MASS`](/0.17.0/geometry/core/#position) allowing to place labels in center of mass of segmentation masks.
- Added [#651](https://github.com/roboflow/supervision/pull/651): [`sv.scale_boxes`](https://supervision.roboflow.com/detection/utils/#supervision.detection.utils.scale_boxes) allowing to scale [`sv.Detections.xyxy`](https://supervision.roboflow.com/detection/core/#supervision.detection.core.Detections) values.
- Added [#651](https://github.com/roboflow/supervision/pull/651): [`sv.scale_boxes`](/0.17.0/detection/utils/#supervision.detection.utils.scale_boxes) allowing to scale [`sv.Detections.xyxy`](/0.17.0/detection/core/#supervision.detection.core.Detections) values.
- Added [#637](https://github.com/roboflow/supervision/pull/637): [`sv.calculate_dynamic_text_scale`](https://supervision.roboflow.com/draw/utils/#supervision.draw.utils.calculate_dynamic_text_scale) and [`sv.calculate_dynamic_line_thickness`](https://supervision.roboflow.com/draw/utils/#supervision.draw.utils.calculate_dynamic_line_thickness) allowing text scale and line thickness to match image resolution.
- Added [#637](https://github.com/roboflow/supervision/pull/637): [`sv.calculate_dynamic_text_scale`](/0.17.0/draw/utils/#supervision.draw.utils.calculate_dynamic_text_scale) and [`sv.calculate_dynamic_line_thickness`](/0.17.0/draw/utils/#supervision.draw.utils.calculate_dynamic_line_thickness) allowing text scale and line thickness to match image resolution.
- Added [#620](https://github.com/roboflow/supervision/pull/620): [`sv.Color.as_hex`](https://supervision.roboflow.com/draw/color/#supervision.draw.color.Color.as_hex) allowing to extract color value in HEX format.
- Added [#620](https://github.com/roboflow/supervision/pull/620): [`sv.Color.as_hex`](/0.17.0/draw/color/#supervision.draw.color.Color.as_hex) allowing to extract color value in HEX format.
- Added [#572](https://github.com/roboflow/supervision/pull/572): [`sv.Classifications.from_timm`](https://supervision.roboflow.com/classification/core/#supervision.classification.core.Classifications.from_timm) allowing to load classification result from [timm](https://huggingface.co/docs/hub/timm) models.
- Added [#572](https://github.com/roboflow/supervision/pull/572): [`sv.Classifications.from_timm`](/0.17.0/classification/core/#supervision.classification.core.Classifications.from_timm) allowing to load classification result from [timm](https://huggingface.co/docs/hub/timm) models.
- Added [#478](https://github.com/roboflow/supervision/pull/478): [`sv.Classifications.from_clip`](https://supervision.roboflow.com/classification/core/#supervision.classification.core.Classifications.from_clip) allowing to load classification result from [clip](https://github.com/openai/clip) model.
- Added [#478](https://github.com/roboflow/supervision/pull/478): [`sv.Classifications.from_clip`](/0.17.0/classification/core/#supervision.classification.core.Classifications.from_clip) allowing to load classification result from [clip](https://github.com/openai/clip) model.
- Added [#571](https://github.com/roboflow/supervision/pull/571): [`sv.Detections.from_azure_analyze_image`](https://supervision.roboflow.com/detection/core/#supervision.detection.core.Detections.from_azure_analyze_image) allowing to load detection results from [Azure Image Analysis](https://learn.microsoft.com/en-us/azure/ai-services/computer-vision/concept-object-detection-40).
- Added [#571](https://github.com/roboflow/supervision/pull/571): [`sv.Detections.from_azure_analyze_image`](/0.17.0/detection/core/#supervision.detection.core.Detections.from_azure_analyze_image) allowing to load detection results from [Azure Image Analysis](https://learn.microsoft.com/en-us/azure/ai-services/computer-vision/concept-object-detection-40).
- Changed [#646](https://github.com/roboflow/supervision/pull/646): `sv.BoxMaskAnnotator` renaming it to [`sv.ColorAnnotator`](https://supervision.roboflow.com/annotators/#supervision.annotators.core.ColorAnnotator).
- Changed [#646](https://github.com/roboflow/supervision/pull/646): `sv.BoxMaskAnnotator` renaming it to [`sv.ColorAnnotator`](/0.17.0/annotators/#supervision.annotators.core.ColorAnnotator).
- Changed [#606](https://github.com/roboflow/supervision/pull/606): [`sv.MaskAnnotator`](https://supervision.roboflow.com/annotators/#supervision.annotators.core.MaskAnnotator) to make it **5x faster**.
- Changed [#606](https://github.com/roboflow/supervision/pull/606): [`sv.MaskAnnotator`](/0.17.0/annotators/#supervision.annotators.core.MaskAnnotator) to make it **5x faster**.
- Fixed [#584](https://github.com/roboflow/supervision/pull/584): [`sv.DetectionDataset.from_yolo`](https://supervision.roboflow.com/datasets/#supervision.dataset.core.DetectionDataset.from_yolo) to ignore empty lines in annotation files.
- Fixed [#584](https://github.com/roboflow/supervision/pull/584): [`sv.DetectionDataset.from_yolo`](/0.17.0/datasets/#supervision.dataset.core.DetectionDataset.from_yolo) to ignore empty lines in annotation files.
- Fixed [#555](https://github.com/roboflow/supervision/pull/555): [`sv.BlurAnnotator`](https://supervision.roboflow.com/annotators/#supervision.annotators.core.BlurAnnotator) to trim negative coordinates before bluring detections.
- Fixed [#555](https://github.com/roboflow/supervision/pull/555): [`sv.BlurAnnotator`](/0.17.0/annotators/#supervision.annotators.core.BlurAnnotator) to trim negative coordinates before bluring detections.
- Fixed [#511](https://github.com/roboflow/supervision/pull/511): [`sv.TraceAnnotator`](https://supervision.roboflow.com/annotators/#supervision.annotators.core.TraceAnnotator) to respect trace position.
- Fixed [#511](https://github.com/roboflow/supervision/pull/511): [`sv.TraceAnnotator`](/0.17.0/annotators/#supervision.annotators.core.TraceAnnotator) to respect trace position.
### 0.16.0 <small>October 19, 2023</small>
- Added [#422](https://github.com/roboflow/supervision/pull/422): [`sv.BoxMaskAnnotator`](https://supervision.roboflow.com/annotators/#supervision.annotators.core.BoxMaskAnnotator) allowing to annotate images and videos with mox masks.
- Added [#422](https://github.com/roboflow/supervision/pull/422): [`sv.BoxMaskAnnotator`](/0.16.0/annotators/#supervision.annotators.core.BoxMaskAnnotator) allowing to annotate images and videos with mox masks.
- Added [#433](https://github.com/roboflow/supervision/pull/433): [`sv.HaloAnnotator`](https://supervision.roboflow.com/annotators/#supervision.annotators.core.HaloAnnotator) allowing to annotate images and videos with halo effect.
- Added [#433](https://github.com/roboflow/supervision/pull/433): [`sv.HaloAnnotator`](/0.16.0/annotators/#supervision.annotators.core.HaloAnnotator) allowing to annotate images and videos with halo effect.
```python
>>> import supervision as sv
@@ -70,46 +224,46 @@
... )
```
- Added [#466](https://github.com/roboflow/supervision/pull/466): [`sv.HeatMapAnnotator`](https://supervision.roboflow.com/annotators/#supervision.annotators.core.HeatMapAnnotator) allowing to annotate videos with heat maps.
- Added [#466](https://github.com/roboflow/supervision/pull/466): [`sv.HeatMapAnnotator`](/0.16.0/annotators/#supervision.annotators.core.HeatMapAnnotator) allowing to annotate videos with heat maps.
- Added [#492](https://github.com/roboflow/supervision/pull/492): [`sv.DotAnnotator`](https://supervision.roboflow.com/annotators/#supervision.annotators.core.DotAnnotator) allowing to annotate images and videos with dots.
- Added [#492](https://github.com/roboflow/supervision/pull/492): [`sv.DotAnnotator`](/0.16.0/annotators/#supervision.annotators.core.DotAnnotator) allowing to annotate images and videos with dots.
- Added [#449](https://github.com/roboflow/supervision/pull/449): [`sv.draw_image`](https://supervision.roboflow.com/draw/utils/#supervision.draw.utils.draw_image) allowing to draw an image onto a given scene with specified opacity and dimensions.
- Added [#449](https://github.com/roboflow/supervision/pull/449): [`sv.draw_image`](/0.16.0/draw/utils/#supervision.draw.utils.draw_image) allowing to draw an image onto a given scene with specified opacity and dimensions.
- Added [#280](https://github.com/roboflow/supervision/pull/280): [`sv.FPSMonitor`](https://supervision.roboflow.com/utils/video/#supervision.utils.video.FPSMonitor) for monitoring frames per second (FPS) to benchmark latency.
- Added [#280](https://github.com/roboflow/supervision/pull/280): [`sv.FPSMonitor`](/0.16.0/utils/video/#supervision.utils.video.FPSMonitor) for monitoring frames per second (FPS) to benchmark latency.
- Added [#454](https://github.com/roboflow/supervision/pull/454): 🤗 Hugging Face Annotators [space](https://huggingface.co/spaces/Roboflow/Annotators).
- Changed [#482](https://github.com/roboflow/supervision/pull/482): [`sv.LineZone.tigger`](https://supervision.roboflow.com/detection/tools/line_zone/#supervision.detection.line_counter.LineZone.trigger) now return `Tuple[np.ndarray, np.ndarray]`. The first array indicates which detections have crossed the line from outside to inside. The second array indicates which detections have crossed the line from inside to outside.
- Changed [#482](https://github.com/roboflow/supervision/pull/482): [`sv.LineZone.trigger`](/0.16.0/detection/tools/line_zone/#supervision.detection.line_counter.LineZone.trigger) now return `Tuple[np.ndarray, np.ndarray]`. The first array indicates which detections have crossed the line from outside to inside. The second array indicates which detections have crossed the line from inside to outside.
- Changed [#465](https://github.com/roboflow/supervision/pull/465): Annotator argument name from `color_map: str` to `color_lookup: ColorLookup` enum to increase type safety.
- Changed [#426](https://github.com/roboflow/supervision/pull/426): [`sv.MaskAnnotator`](https://supervision.roboflow.com/annotators/#supervision.annotators.core.MaskAnnotator) allowing 2x faster annotation.
- Changed [#426](https://github.com/roboflow/supervision/pull/426): [`sv.MaskAnnotator`](/0.16.0/annotators/#supervision.annotators.core.MaskAnnotator) allowing 2x faster annotation.
- Fixed [#477](https://github.com/roboflow/supervision/pull/477): Poetry env definition allowing proper local installation.
- Fixed [#430](https://github.com/roboflow/supervision/pull/430): [`sv.ByteTrack`](https://supervision.roboflow.com/trackers/#supervision.tracker.byte_tracker.core.ByteTrack) to return `np.array([], dtype=int)` when `svDetections` is empty.
- Fixed [#430](https://github.com/roboflow/supervision/pull/430): [`sv.ByteTrack`](/0.16.0/trackers/#supervision.tracker.byte_tracker.core.ByteTrack) to return `np.array([], dtype=int)` when `svDetections` is empty.
!!! warning
!!! failure "Deprecated"
`sv.Detections.from_yolov8` and `sv.Classifications.from_yolov8` as those are now replaced by [`sv.Detections.from_ultralytics`](https://supervision.roboflow.com/detection/core/#supervision.detection.core.Detections.from_ultralytics) and [`sv.Classifications.from_ultralytics`](https://supervision.roboflow.com/classification/core/#supervision.classification.core.Classifications.from_ultralytics).
`sv.Detections.from_yolov8` and `sv.Classifications.from_yolov8` as those are now replaced by [`sv.Detections.from_ultralytics`](/0.16.0/detection/core/#supervision.detection.core.Detections.from_ultralytics) and [`sv.Classifications.from_ultralytics`](/0.16.0/classification/core/#supervision.classification.core.Classifications.from_ultralytics).
### 0.15.0 <small>October 5, 2023</small>
- Added [#170](https://github.com/roboflow/supervision/pull/170): [`sv.BoundingBoxAnnotator`](https://supervision.roboflow.com/annotators/#supervision.annotators.core.BoundingBoxAnnotator) allowing to annotate images and videos with bounding boxes.
- Added [#170](https://github.com/roboflow/supervision/pull/170): [`sv.BoundingBoxAnnotator`](/0.15.0/annotators/#supervision.annotators.core.BoundingBoxAnnotator) allowing to annotate images and videos with bounding boxes.
- Added [#170](https://github.com/roboflow/supervision/pull/170): [`sv.BoxCornerAnnotator `](https://supervision.roboflow.com/annotators/#supervision.annotators.core.BoxCornerAnnotator) allowing to annotate images and videos with just bounding box corners.
- Added [#170](https://github.com/roboflow/supervision/pull/170): [`sv.BoxCornerAnnotator `](/0.15.0/annotators/#supervision.annotators.core.BoxCornerAnnotator) allowing to annotate images and videos with just bounding box corners.
- Added [#170](https://github.com/roboflow/supervision/pull/170): [`sv.MaskAnnotator`](https://supervision.roboflow.com/annotators/#supervision.annotators.core.MaskAnnotator) allowing to annotate images and videos with segmentation masks.
- Added [#170](https://github.com/roboflow/supervision/pull/170): [`sv.MaskAnnotator`](/0.15.0/annotators/#supervision.annotators.core.MaskAnnotator) allowing to annotate images and videos with segmentation masks.
- Added [#170](https://github.com/roboflow/supervision/pull/170): [`sv.EllipseAnnotator`](https://supervision.roboflow.com/annotators/#supervision.annotators.core.EllipseAnnotator) allowing to annotate images and videos with ellipses (sports game style).
- Added [#170](https://github.com/roboflow/supervision/pull/170): [`sv.EllipseAnnotator`](/0.15.0/annotators/#supervision.annotators.core.EllipseAnnotator) allowing to annotate images and videos with ellipses (sports game style).
- Added [#386](https://github.com/roboflow/supervision/pull/386): [`sv.CircleAnnotator`](https://supervision.roboflow.com/annotators/#supervision.annotators.core.CircleAnnotator) allowing to annotate images and videos with circles.
- Added [#386](https://github.com/roboflow/supervision/pull/386): [`sv.CircleAnnotator`](/0.15.0/annotators/#supervision.annotators.core.CircleAnnotator) allowing to annotate images and videos with circles.
- Added [#354](https://github.com/roboflow/supervision/pull/354): [`sv.TraceAnnotator`](https://supervision.roboflow.com/annotators/#supervision.annotators.core.TraceAnnotator) allowing to draw path of moving objects on videos.
- Added [#354](https://github.com/roboflow/supervision/pull/354): [`sv.TraceAnnotator`](/0.15.0/annotators/#supervision.annotators.core.TraceAnnotator) allowing to draw path of moving objects on videos.
- Added [#405](https://github.com/roboflow/supervision/pull/405): [`sv.BlurAnnotator`](https://supervision.roboflow.com/annotators/#supervision.annotators.core.BlurAnnotator) allowing to blur objects on images and videos.
- Added [#405](https://github.com/roboflow/supervision/pull/405): [`sv.BlurAnnotator`](/0.15.0/annotators/#supervision.annotators.core.BlurAnnotator) allowing to blur objects on images and videos.
```python
>>> import supervision as sv
@@ -126,17 +280,17 @@
- Added [#354](https://github.com/roboflow/supervision/pull/354): Supervision usage [example](https://github.com/roboflow/supervision/tree/develop/examples/traffic_analysis). You can now learn how to perform traffic flow analysis with Supervision.
- Changed [#399](https://github.com/roboflow/supervision/pull/399): [`sv.Detections.from_roboflow`](https://supervision.roboflow.com/detection/core/#supervision.detection.core.Detections.from_roboflow) now does not require `class_list` to be specified. The `class_id` value can be extracted directly from the [inference](https://github.com/roboflow/inference) response.
- Changed [#399](https://github.com/roboflow/supervision/pull/399): [`sv.Detections.from_roboflow`](/0.15.0/detection/core/#supervision.detection.core.Detections.from_roboflow) now does not require `class_list` to be specified. The `class_id` value can be extracted directly from the [inference](https://github.com/roboflow/inference) response.
- Changed [#381](https://github.com/roboflow/supervision/pull/381): [`sv.VideoSink`](https://supervision.roboflow.com/utils/video/#videosink) now allows to customize the output codec.
- Changed [#381](https://github.com/roboflow/supervision/pull/381): [`sv.VideoSink`](/0.15.0/utils/video/#videosink) now allows to customize the output codec.
- Changed [#361](https://github.com/roboflow/supervision/pull/361): [`sv.InferenceSlicer`](https://supervision.roboflow.com/detection/tools/inference_slicer/#supervision.detection.tools.inference_slicer.InferenceSlicer) can now operate in multithreading mode.
- Changed [#361](https://github.com/roboflow/supervision/pull/361): [`sv.InferenceSlicer`](/0.15.0/detection/tools/inference_slicer/#supervision.detection.tools.inference_slicer.InferenceSlicer) can now operate in multithreading mode.
- Fixed [#348](https://github.com/roboflow/supervision/pull/348): [`sv.Detections.from_deepsparse`](https://supervision.roboflow.com/detection/core/#supervision.detection.core.Detections.from_deepsparse) to allow processing empty [deepsparse](https://github.com/neuralmagic/deepsparse) result object.
- Fixed [#348](https://github.com/roboflow/supervision/pull/348): [`sv.Detections.from_deepsparse`](/0.15.0/detection/core/#supervision.detection.core.Detections.from_deepsparse) to allow processing empty [deepsparse](https://github.com/neuralmagic/deepsparse) result object.
### 0.14.0 <small>August 31, 2023</small>
- Added [#282](https://github.com/roboflow/supervision/pull/282): support for SAHI inference technique with [`sv.InferenceSlicer`](https://supervision.roboflow.com/detection/tools/inference_slicer).
- Added [#282](https://github.com/roboflow/supervision/pull/282): support for SAHI inference technique with [`sv.InferenceSlicer`](/0.14.0/detection/tools/inference_slicer).
```python
>>> import cv2
@@ -155,23 +309,23 @@
>>> detections = slicer(image)
```
- Added [#297](https://github.com/roboflow/supervision/pull/297): [`Detections.from_deepsparse`](https://roboflow.github.io/supervision/detection/core/#supervision.detection.core.Detections.from_deepsparse) to enable seamless integration with [DeepSparse](https://github.com/neuralmagic/deepsparse) framework.
- Added [#297](https://github.com/roboflow/supervision/pull/297): [`Detections.from_deepsparse`](/0.14.0/detection/core/#supervision.detection.core.Detections.from_deepsparse) to enable seamless integration with [DeepSparse](https://github.com/neuralmagic/deepsparse) framework.
- Added [#281](https://github.com/roboflow/supervision/pull/281): [`sv.Classifications.from_ultralytics`](https://supervision.roboflow.com/classification/core/#supervision.classification.core.Classifications.from_ultralytics) to enable seamless integration with [Ultralytics](https://github.com/ultralytics/ultralytics) framework. This will enable you to use supervision with all [models](https://docs.ultralytics.com/models/) that Ultralytics supports.
- Added [#281](https://github.com/roboflow/supervision/pull/281): [`sv.Classifications.from_ultralytics`](/0.14.0/classification/core/#supervision.classification.core.Classifications.from_ultralytics) to enable seamless integration with [Ultralytics](https://github.com/ultralytics/ultralytics) framework. This will enable you to use supervision with all [models](https://docs.ultralytics.com/models/) that Ultralytics supports.
!!! warning
!!! failure "Deprecated"
[sv.Detections.from_yolov8](https://roboflow.github.io/supervision/detection/core/#supervision.detection.core.Detections.from_yolov8) and [sv.Classifications.from_yolov8](https://supervision.roboflow.com/classification/core/#supervision.classification.core.Classifications.from_yolov8) are now deprecated and will be removed with supervision-0.16.0 release.
[sv.Detections.from_yolov8](/0.14.0/detection/core/#supervision.detection.core.Detections.from_yolov8) and [sv.Classifications.from_yolov8](/0.14.0/classification/core/#supervision.classification.core.Classifications.from_yolov8) are now deprecated and will be removed with `supervision-0.16.0` release.
- Added [#341](https://github.com/roboflow/supervision/pull/341): First supervision usage example script showing how to detect and track objects on video using YOLOv8 + Supervision.
- Changed [#296](https://github.com/roboflow/supervision/pull/296): [`sv.ClassificationDataset`](https://supervision.roboflow.com/dataset/core/#supervision.dataset.core.ClassificationDataset) and [`sv.DetectionDataset`](https://supervision.roboflow.com/dataset/core/#supervision.dataset.core.DetectionDataset) now use image path (not image name) as dataset keys.
- Changed [#296](https://github.com/roboflow/supervision/pull/296): [`sv.ClassificationDataset`](/0.14.0/dataset/core/#supervision.dataset.core.ClassificationDataset) and [`sv.DetectionDataset`](/0.14.0/dataset/core/#supervision.dataset.core.DetectionDataset) now use image path (not image name) as dataset keys.
- Fixed [#300](https://github.com/roboflow/supervision/pull/300): [`Detections.from_roboflow`](https://supervision.roboflow.com/detection/core/#supervision.detection.core.Detections.from_roboflow) to filter out polygons with less than 3 points.
- Fixed [#300](https://github.com/roboflow/supervision/pull/300): [`Detections.from_roboflow`](/0.14.0/detection/core/#supervision.detection.core.Detections.from_roboflow) to filter out polygons with less than 3 points.
### 0.13.0 <small>August 8, 2023</small>
- Added [#236](https://github.com/roboflow/supervision/pull/236): support for mean average precision (mAP) for object detection models with [`sv.MeanAveragePrecision`](https://roboflow.github.io/supervision/metrics/detection/#meanaverageprecision).
- Added [#236](https://github.com/roboflow/supervision/pull/236): support for mean average precision (mAP) for object detection models with [`sv.MeanAveragePrecision`](/0.13.0/metrics/detection/#meanaverageprecision).
```python
>>> import supervision as sv
@@ -193,25 +347,25 @@
0.433
```
- Added [#256](https://github.com/roboflow/supervision/pull/256): support for ByteTrack for object tracking with [`sv.ByteTrack`](https://roboflow.github.io/supervision/tracker/core/#bytetrack).
- Added [#256](https://github.com/roboflow/supervision/pull/256): support for ByteTrack for object tracking with [`sv.ByteTrack`](/0.13.0/tracker/core/#bytetrack).
- Added [#222](https://github.com/roboflow/supervision/pull/222): [`sv.Detections.from_ultralytics`](https://roboflow.github.io/supervision/detection/core/#supervision.detection.core.Detections.from_ultralytics) to enable seamless integration with [Ultralytics](https://github.com/ultralytics/ultralytics) framework. This will enable you to use `supervision` with all [models](https://docs.ultralytics.com/models/) that Ultralytics supports.
- Added [#222](https://github.com/roboflow/supervision/pull/222): [`sv.Detections.from_ultralytics`](/0.13.0/detection/core/#supervision.detection.core.Detections.from_ultralytics) to enable seamless integration with [Ultralytics](https://github.com/ultralytics/ultralytics) framework. This will enable you to use `supervision` with all [models](https://docs.ultralytics.com/models/) that Ultralytics supports.
!!! warning
!!! failure "Deprecated"
[`sv.Detections.from_yolov8`](https://roboflow.github.io/supervision/detection/core/#supervision.detection.core.Detections.from_yolov8) is now deprecated and will be removed with `supervision-0.15.0` release.
[`sv.Detections.from_yolov8`](/0.13.0/detection/core/#supervision.detection.core.Detections.from_yolov8) is now deprecated and will be removed with `supervision-0.15.0` release.
- Added [#191](https://github.com/roboflow/supervision/pull/191): [`sv.Detections.from_paddledet`](https://roboflow.github.io/supervision/detection/core/#supervision.detection.core.Detections.from_paddledet) to enable seamless integration with [PaddleDetection](https://github.com/PaddlePaddle/PaddleDetection) framework.
- Added [#191](https://github.com/roboflow/supervision/pull/191): [`sv.Detections.from_paddledet`](/0.13.0/detection/core/#supervision.detection.core.Detections.from_paddledet) to enable seamless integration with [PaddleDetection](https://github.com/PaddlePaddle/PaddleDetection) framework.
- Added [#245](https://github.com/roboflow/supervision/pull/245): support for loading PASCAL VOC segmentation datasets with [`sv.DetectionDataset.`](https://roboflow.github.io/supervision/dataset/core/#supervision.dataset.core.DetectionDataset.from_pascal_voc).
- Added [#245](https://github.com/roboflow/supervision/pull/245): support for loading PASCAL VOC segmentation datasets with [`sv.DetectionDataset.`](/0.13.0/dataset/core/#supervision.dataset.core.DetectionDataset.from_pascal_voc).
### 0.12.0 <small>July 24, 2023</small>
!!! warning
!!! failure "Python 3.7. Support Terminated"
With the `supervision-0.12.0` release, we are terminating official support for Python 3.7.
- Added [#177](https://github.com/roboflow/supervision/pull/177): initial support for object detection model benchmarking with [`sv.ConfusionMatrix`](https://roboflow.github.io/supervision/metrics/detection/#confusionmatrix).
- Added [#177](https://github.com/roboflow/supervision/pull/177): initial support for object detection model benchmarking with [`sv.ConfusionMatrix`](/0.12.0/metrics/detection/#confusionmatrix).
```python
>>> import supervision as sv
@@ -238,23 +392,23 @@ array([
])
```
- Added [#173](https://github.com/roboflow/supervision/pull/173): [`Detections.from_mmdetection`](https://roboflow.github.io/supervision/detection/core/#supervision.detection.core.Detections.from_mmdetection) to enable seamless integration with [MMDetection](https://github.com/open-mmlab/mmdetection) framework.
- Added [#173](https://github.com/roboflow/supervision/pull/173): [`Detections.from_mmdetection`](/0.12.0/detection/core/#supervision.detection.core.Detections.from_mmdetection) to enable seamless integration with [MMDetection](https://github.com/open-mmlab/mmdetection) framework.
- Added [#130](https://github.com/roboflow/supervision/issues/130): ability to [install](https://roboflow.github.io/supervision/) package in `headless` or `desktop` mode.
- Added [#130](https://github.com/roboflow/supervision/issues/130): ability to [install](https://supervision.roboflow.com/) package in `headless` or `desktop` mode.
- Changed [#180](https://github.com/roboflow/supervision/pull/180): packing method from `setup.py` to `pyproject.toml`.
- Fixed [#188](https://github.com/roboflow/supervision/issues/188): [`sv.DetectionDataset.from_cooc`](https://roboflow.github.io/supervision/dataset/core/#supervision.dataset.core.DetectionDataset.from_coco) can't be loaded when there are images without annotations.
- Fixed [#188](https://github.com/roboflow/supervision/issues/188): [`sv.DetectionDataset.from_cooc`](/0.12.0/dataset/core/#supervision.dataset.core.DetectionDataset.from_coco) can't be loaded when there are images without annotations.
- Fixed [#226](https://github.com/roboflow/supervision/issues/226): [`sv.DetectionDataset.from_yolo`](https://roboflow.github.io/supervision/dataset/core/#supervision.dataset.core.DetectionDataset.from_yolo) can't load background instances.
- Fixed [#226](https://github.com/roboflow/supervision/issues/226): [`sv.DetectionDataset.from_yolo`](/0.12.0/dataset/core/#supervision.dataset.core.DetectionDataset.from_yolo) can't load background instances.
### 0.11.1 <small>June 29, 2023</small>
- Fix [#165](https://github.com/roboflow/supervision/pull/165): [`as_folder_structure`](https://roboflow.github.io/supervision/dataset/core/#supervision.dataset.core.ClassificationDataset.as_folder_structure) fails to save [`sv.ClassificationDataset`](https://roboflow.github.io/supervision/dataset/core/#classificationdataset) when it is result of inference.
- Fix [#165](https://github.com/roboflow/supervision/pull/165): [`as_folder_structure`](/0.11.1/dataset/core/#supervision.dataset.core.ClassificationDataset.as_folder_structure) fails to save [`sv.ClassificationDataset`](/0.11.1/dataset/core/#classificationdataset) when it is result of inference.
### 0.11.0 <small>June 28, 2023</small>
- Added [#150](https://github.com/roboflow/supervision/pull/150): ability to load and save [`sv.DetectionDataset`](https://roboflow.github.io/supervision/dataset/core/#detectiondataset) in COCO format using [`as_coco`](https://roboflow.github.io/supervision/dataset/core/#supervision.dataset.core.DetectionDataset.as_coco) and [`from_coco`](https://roboflow.github.io/supervision/dataset/core/#supervision.dataset.core.DetectionDataset.from_coco) methods.
- Added [#150](https://github.com/roboflow/supervision/pull/150): ability to load and save [`sv.DetectionDataset`](/0.11.0/dataset/core/#detectiondataset) in COCO format using [`as_coco`](/0.11.0/dataset/core/#supervision.dataset.core.DetectionDataset.as_coco) and [`from_coco`](/0.11.0/dataset/core/#supervision.dataset.core.DetectionDataset.from_coco) methods.
```python
>>> import supervision as sv
@@ -270,7 +424,7 @@ array([
... )
```
- Added [#158](https://github.com/roboflow/supervision/pull/158): ability to marge multiple [`sv.DetectionDataset`](https://roboflow.github.io/supervision/dataset/core/#detectiondataset) together using [`merge`](https://roboflow.github.io/supervision/dataset/core/#supervision.dataset.core.DetectionDataset.merge) method.
- Added [#158](https://github.com/roboflow/supervision/pull/158): ability to merge multiple [`sv.DetectionDataset`](/0.11.0/dataset/core/#detectiondataset) together using [`merge`](/0.11.0/dataset/core/#supervision.dataset.core.DetectionDataset.merge) method.
```python
>>> import supervision as sv
@@ -294,13 +448,13 @@ array([
['cat', 'dog', 'person']
```
- Added [#162](https://github.com/roboflow/supervision/pull/162): additional `start` and `end` arguments to [`sv.get_video_frames_generator`](https://roboflow.github.io/supervision/utils/video/#get_video_frames_generator) allowing to generate frames only for a selected part of the video.
- Added [#162](https://github.com/roboflow/supervision/pull/162): additional `start` and `end` arguments to [`sv.get_video_frames_generator`](/0.11.0/utils/video/#get_video_frames_generator) allowing to generate frames only for a selected part of the video.
- Fix [#157](https://github.com/roboflow/supervision/pull/157): incorrect loading of YOLO dataset class names from `data.yaml`.
### 0.10.0 <small>June 14, 2023</small>
- Added [#125](https://github.com/roboflow/supervision/pull/125): ability to load and save [`sv.ClassificationDataset`](https://roboflow.github.io/supervision/dataset/core/#classificationdataset) in a folder structure format.
- Added [#125](https://github.com/roboflow/supervision/pull/125): ability to load and save [`sv.ClassificationDataset`](/0.10.0/dataset/core/#classificationdataset) in a folder structure format.
```python
>>> import supervision as sv
@@ -314,9 +468,9 @@ array([
... )
```
- Added [#125](https://github.com/roboflow/supervision/pull/125): support for [`sv.ClassificationDataset.split`](https://roboflow.github.io/supervision/dataset/core/#supervision.dataset.core.ClassificationDataset.split) allowing to divide `sv.ClassificationDataset` into two parts.
- Added [#125](https://github.com/roboflow/supervision/pull/125): support for [`sv.ClassificationDataset.split`](/0.10.0/dataset/core/#supervision.dataset.core.ClassificationDataset.split) allowing to divide `sv.ClassificationDataset` into two parts.
- Added [#110](https://github.com/roboflow/supervision/pull/110): ability to extract masks from Roboflow API results using [`sv.Detections.from_roboflow`](https://roboflow.github.io/supervision/detection/core/#supervision.detection.core.Detections.from_roboflow).
- Added [#110](https://github.com/roboflow/supervision/pull/110): ability to extract masks from Roboflow API results using [`sv.Detections.from_roboflow`](/0.10.0/detection/core/#supervision.detection.core.Detections.from_roboflow).
- Added [commit hash](https://github.com/roboflow/supervision/commit/d000292eb2f2342544e0947b65528082e60fb8d6): Supervision Quickstart [notebook](https://colab.research.google.com/github/roboflow/supervision/blob/main/demo.ipynb) where you can learn more about Detection, Dataset and Video APIs.
@@ -324,7 +478,7 @@ array([
### 0.9.0 <small>June 7, 2023</small>
- Added [#118](https://github.com/roboflow/supervision/pull/118): ability to select [`sv.Detections`](https://roboflow.github.io/supervision/detection/core/#supervision.detection.core.Detections.__getitem__) by index, list of indexes or slice. Here is an example illustrating the new selection methods.
- Added [#118](https://github.com/roboflow/supervision/pull/118): ability to select [`sv.Detections`](/0.9.0/detection/core/#supervision.detection.core.Detections.__getitem__) by index, list of indexes or slice. Here is an example illustrating the new selection methods.
```python
>>> import supervision as sv
@@ -338,11 +492,11 @@ array([
2
```
- Added [#101](https://github.com/roboflow/supervision/pull/101): ability to extract masks from YOLOv8 result using [`sv.Detections.from_yolov8`](https://roboflow.github.io/supervision/detection/core/#supervision.detection.core.Detections.from_yolov8). Here is an example illustrating how to extract boolean masks from the result of the YOLOv8 model inference.
- Added [#101](https://github.com/roboflow/supervision/pull/101): ability to extract masks from YOLOv8 result using [`sv.Detections.from_yolov8`](/0.8.0/detection/core/#supervision.detection.core.Detections.from_yolov8). Here is an example illustrating how to extract boolean masks from the result of the YOLOv8 model inference.
- Added [#122](https://github.com/roboflow/supervision/pull/122): ability to crop image using [`sv.crop`](https://roboflow.github.io/supervision/utils/image/#crop). Here is an example showing how to get a separate crop for each detection in `sv.Detections`.
- Added [#122](https://github.com/roboflow/supervision/pull/122): ability to crop image using [`sv.crop`](/latest/utils/image/#crop). Here is an example showing how to get a separate crop for each detection in `sv.Detections`.
- Added [#120](https://github.com/roboflow/supervision/pull/120): ability to conveniently save multiple images into directory using [`sv.ImageSink`](https://roboflow.github.io/supervision/utils/image/#imagesink). Here is an example showing how to save every tenth video frame as a separate image.
- Added [#120](https://github.com/roboflow/supervision/pull/120): ability to conveniently save multiple images into directory using [`sv.ImageSink`](/0.9.0/utils/image/#imagesink). Here is an example showing how to save every tenth video frame as a separate image.
```python
>>> import supervision as sv
@@ -352,12 +506,12 @@ array([
... sink.save_image(image=image)
```
- Fixed [#106](https://github.com/roboflow/supervision/issues/106): inconvenient handling of [`sv.PolygonZone`](https://roboflow.github.io/supervision/detection/tools/polygon_zone/#polygonzone) coordinates. Now `sv.PolygonZone` accepts coordinates in the form of `[[x1, y1], [x2, y2], ...]` that can be both integers and floats.
- Fixed [#106](https://github.com/roboflow/supervision/issues/106): inconvenient handling of [`sv.PolygonZone`](/0.8.0/supervision/detection/tools/polygon_zone/#polygonzone) coordinates. Now `sv.PolygonZone` accepts coordinates in the form of `[[x1, y1], [x2, y2], ...]` that can be both integers and floats.
### 0.8.0 <small>May 17, 2023</small>
- Added [#100](https://github.com/roboflow/supervision/pull/100): support for dataset inheritance. The current `Dataset` got renamed to `DetectionDataset`. Now [`DetectionDataset`](https://roboflow.github.io/supervision/dataset/core/#detectiondataset) inherits from `BaseDataset`. This change was made to enforce the future consistency of APIs of different types of computer vision datasets.
- Added [#100](https://github.com/roboflow/supervision/pull/100): ability to save datasets in YOLO format using [`DetectionDataset.as_yolo`](https://roboflow.github.io/supervision/dataset/core/#supervision.dataset.core.DetectionDataset.as_yolo).
- Added [#100](https://github.com/roboflow/supervision/pull/100): support for dataset inheritance. The current `Dataset` got renamed to `DetectionDataset`. Now [`DetectionDataset`](/0.8.0/supervision/dataset/core/#detectiondataset) inherits from `BaseDataset`. This change was made to enforce the future consistency of APIs of different types of computer vision datasets.
- Added [#100](https://github.com/roboflow/supervision/pull/100): ability to save datasets in YOLO format using [`DetectionDataset.as_yolo`](/0.8.0/dataset/core/#supervision.dataset.core.DetectionDataset.as_yolo).
```python
>>> import roboflow
@@ -381,7 +535,7 @@ array([
['dog', 'person']
```
- Added [#102](https://github.com/roboflow/supervision/pull/103): support for [`DetectionDataset.split`](https://roboflow.github.io/supervision/dataset/core/#supervision.dataset.core.DetectionDataset.split) allowing to divide `DetectionDataset` into two parts.
- Added [#102](https://github.com/roboflow/supervision/pull/103): support for [`DetectionDataset.split`](/0.8.0/dataset/core/#supervision.dataset.core.DetectionDataset.split) allowing to divide `DetectionDataset` into two parts.
```python
>>> import supervision as sv
+1 -1
View File
@@ -2,6 +2,6 @@
comments: true
---
## Classifications
# Classifications
:::supervision.classification.core.Classifications
+5
View File
@@ -0,0 +1,5 @@
# Code of conduct
```
--8<-- "CODE_OF_CONDUCT.md"
```
+1
View File
@@ -0,0 +1 @@
--8<-- "CONTRIBUTING.md"
+8
View File
@@ -0,0 +1,8 @@
---
template: cookbooks.html
comments: true
status: new
hide:
- navigation
- toc
---
+8 -2
View File
@@ -2,15 +2,21 @@
comments: true
---
# Datasets
!!! warning
Dataset API is still fluid and may change. If you use Dataset API in your project until further notice, freeze the
`supervision` version in your `requirements.txt` or `setup.py`.
## DetectionDataset
<div class="md-typeset">
<h2>DetectionDataset</h2>
</div>
:::supervision.dataset.core.DetectionDataset
## ClassificationDataset
<div class="md-typeset">
<h2>ClassificationDataset</h2>
</div>
:::supervision.dataset.core.ClassificationDataset
+18
View File
@@ -0,0 +1,18 @@
---
comments: true
status: deprecated
---
These features are phased out due to better alternatives or potential issues in future versions. Deprecated functionalities are supported for **three subsequent releases**, providing time for users to transition to updated methods.
- [`Detections.from_froboflow`](detection/core.md/#supervision.detection.core.Detections.from_roboflow) is deprecated and will be removed in `supervision-0.22.0`. Use [`Detections.from_inference`](detection/core.md/#supervision.detection.core.Detections.from_inference) instead.
- The method `Color.white()` is deprecated and will be removed in `supervision-0.22.0`. Use the constant `Color.WHITE` instead.
- The method `Color.black()` is deprecated and will be removed in `supervision-0.22.0`. Use the constant `Color.BLACK` instead.
- The method `Color.red()` is deprecated and will be removed in `supervision-0.22.0`. Use the constant `Color.RED` instead.
- The method `Color.green()` is deprecated and will be removed in `supervision-0.22.0`. Use the constant `Color.GREEN` instead.
- The method `Color.blue()` is deprecated and will be removed in `supervision-0.22.0`. Use the constant `Color.BLUE` instead.
- The method [`ColorPalette.default()`](draw/color.md/#supervision.draw.color.ColorPalette.default) is deprecated and will be removed in `supervision-0.22.0`. Use the constant [`ColorPalette.DEFAULT`](draw/color.md/#supervision.draw.color.ColorPalette.DEFAULT) instead.
- `BoxAnnotator` is deprecated and will be removed in `supervision-0.22.0`. Use [`BoundingBoxAnnotator`](annotators.md/#supervision.annotators.core.BoundingBoxAnnotator) and [`LabelAnnotator`](annotators.md/#supervision.annotators.core.LabelAnnotator) instead.
- The method [`FPSMonitor.__call__`](utils/video.md/#supervision.utils.video.FPSMonitor.__call__) is deprecated and will be removed in `supervision-0.22.0`. Use the attribute [`FPSMonitor.fps`](utils/video.md/#supervision.utils.video.FPSMonitor.fps) instead.
- The `track_buffer`, `track_thresh`, and `match_thresh` parameters in [`ByterTrack`](trackers.md/#supervision.tracker.byte_tracker.core.ByteTrack) are deprecated and will be removed in `supervision-0.23.0`. Use `lost_track_buffer,` `track_activation_threshold`, and `minimum_matching_threshold` instead.
- The `triggering_position ` parameter in [`sv.PolygonZone`](detection/tools/polygon_zone.md/#supervision.detection.tools.polygon_zone.PolygonZone) is deprecated and will be removed in `supervision-0.23.0`. Use `triggering_anchors ` instead.
+2 -1
View File
@@ -1,7 +1,8 @@
---
comments: true
status: new
---
## Detections
# Detections
:::supervision.detection.core.Detections
+1 -1
View File
@@ -2,6 +2,6 @@
comments: true
---
## InferenceSlicer
# InferenceSlicer
:::supervision.detection.tools.inference_slicer.InferenceSlicer
+10 -2
View File
@@ -2,6 +2,14 @@
comments: true
---
## LineZone
<div class="md-typeset">
<h2>LineZone</h2>
</div>
:::supervision.detection.line_counter.LineZone
:::supervision.detection.line_zone.LineZone
<div class="md-typeset">
<h2>LineZoneAnnotator</h2>
</div>
:::supervision.detection.line_zone.LineZoneAnnotator
+6 -2
View File
@@ -2,10 +2,14 @@
comments: true
---
## PolygonZone
<div class="md-typeset">
<h2>PolygonZone</h2>
</div>
:::supervision.detection.tools.polygon_zone.PolygonZone
## PolygonZoneAnnotator
<div class="md-typeset">
<h2>PolygonZoneAnnotator</h2>
</div>
:::supervision.detection.tools.polygon_zone.PolygonZoneAnnotator
+18
View File
@@ -0,0 +1,18 @@
---
comments: true
status: new
---
# Save Detections
<div class="md-typeset">
<h2>CSV Sink</h2>
</div>
:::supervision.detection.tools.csv_sink.CSVSink
<div class="md-typeset">
<h2>JSON Sink</h2>
</div>
:::supervision.detection.tools.json_sink.JSONSink
+7
View File
@@ -0,0 +1,7 @@
---
comments: true
---
# Detection Smoother
:::supervision.detection.tools.smoother.DetectionsSmoother
+43 -10
View File
@@ -1,39 +1,72 @@
---
comments: true
status: new
---
## box_iou_batch
# Detection Utils
<div class="md-typeset">
<h2>box_iou_batch</h2>
</div>
:::supervision.detection.utils.box_iou_batch
## non_max_suppression
<div class="md-typeset">
<h2>mask_iou_batch</h2>
</div>
:::supervision.detection.utils.non_max_suppression
:::supervision.detection.utils.mask_iou_batch
## polygon_to_mask
<div class="md-typeset">
<h2>box_non_max_suppression</h2>
</div>
:::supervision.detection.utils.box_non_max_suppression
<div class="md-typeset">
<h2>mask_non_max_suppression</h2>
</div>
:::supervision.detection.utils.mask_non_max_suppression
<div class="md-typeset">
<h2>polygon_to_mask</h2>
</div>
:::supervision.detection.utils.polygon_to_mask
## mask_to_xyxy
<div class="md-typeset">
<h2>mask_to_xyxy</h2>
</div>
:::supervision.detection.utils.mask_to_xyxy
## mask_to_polygons
<div class="md-typeset">
<h2>mask_to_polygons</h2>
</div>
:::supervision.detection.utils.mask_to_polygons
## polygon_to_xyxy
<div class="md-typeset">
<h2>polygon_to_xyxy</h2>
</div>
:::supervision.detection.utils.polygon_to_xyxy
## filter_polygons_by_area
<div class="md-typeset">
<h2>filter_polygons_by_area</h2>
</div>
:::supervision.detection.utils.filter_polygons_by_area
## move_boxes
<div class="md-typeset">
<h2>move_boxes</h2>
</div>
:::supervision.detection.utils.move_boxes
## scale_boxes
<div class="md-typeset">
<h2>scale_boxes</h2>
</div>
:::supervision.detection.utils.scale_boxes
+4 -2
View File
@@ -2,10 +2,12 @@
comments: true
---
## Color
# Color
:::supervision.draw.color.Color
## ColorPalette
<div class="md-typeset">
<h2>ColorPalette</h2>
</div>
:::supervision.draw.color.ColorPalette
+26 -8
View File
@@ -2,34 +2,52 @@
comments: true
---
## draw_line
# Draw Utils
<div class="md-typeset">
<h2>draw_line</h2>
</div>
:::supervision.draw.utils.draw_line
## draw_rectangle
<div class="md-typeset">
<h2>draw_rectangle</h2>
</div>
:::supervision.draw.utils.draw_rectangle
## draw_filled_rectangle
<div class="md-typeset">
<h2>draw_filled_rectangle</h2>
</div>
:::supervision.draw.utils.draw_filled_rectangle
## draw_polygon
<div class="md-typeset">
<h2>draw_polygon</h2>
</div>
:::supervision.draw.utils.draw_polygon
## draw_text
<div class="md-typeset">
<h2>draw_text</h2>
</div>
:::supervision.draw.utils.draw_text
## draw_image
<div class="md-typeset">
<h2>draw_image</h2>
</div>
:::supervision.draw.utils.draw_image
## calculate_dynamic_font_scale
<div class="md-typeset">
<h2>calculate_dynamic_font_scale</h2>
</div>
:::supervision.draw.utils.calculate_dynamic_text_scale
## calculate_dynamic_line_thickness
<div class="md-typeset">
<h2>calculate_dynamic_line_thickness</h2>
</div>
:::supervision.draw.utils.calculate_dynamic_line_thickness
+1 -1
View File
@@ -2,6 +2,6 @@
comments: true
---
## Position
# Position
:::supervision.geometry.core.Position
+13 -11
View File
@@ -2,6 +2,8 @@
comments: true
---
# Detect and Annotate
Supervision offers a streamlined solution to effortlessly annotate predictions from a
range of object detection and segmentation models. This guide demonstrates how to
execute inference using the YOLOv8 model with either the
@@ -42,7 +44,7 @@ Now that we have predictions from a model, we can load them into Supervision.
=== "Ultralytics"
We can do so using the [`sv.Detections.from_ultralytics`](https://supervision.roboflow.com/detection/core/#supervision.detection.core.Detections.from_ultralytics) method, which accepts model results from both detection and segmentation models.
We can do so using the [`sv.Detections.from_ultralytics`](detection/core/#supervision.detection.core.Detections.from_ultralytics) method, which accepts model results from both detection and segmentation models.
```python
import cv2
@@ -57,7 +59,7 @@ Now that we have predictions from a model, we can load them into Supervision.
=== "Inference"
We can do so using the [`sv.Detections.from_inference`](https://supervision.roboflow.com/detection/core/#supervision.detection.core.Detections.from_inference) method, which accepts model results from both detection and segmentation models.
We can do so using the [`sv.Detections.from_inference`](detection/core/#supervision.detection.core.Detections.from_inference) method, which accepts model results from both detection and segmentation models.
```python
import cv2
@@ -72,17 +74,17 @@ Now that we have predictions from a model, we can load them into Supervision.
You can conveniently load predictions from other computer vision frameworks and libraries using:
- [`from_deepsparse`](https://supervision.roboflow.com/detection/core/#supervision.detection.core.Detections.from_deepsparse) ([Deepsparse](https://github.com/neuralmagic/deepsparse))
- [`from_detectron2`](https://supervision.roboflow.com/detection/core/#supervision.detection.core.Detections.from_detectron2) ([Detectron2](https://github.com/facebookresearch/detectron2))
- [`from_mmdetection`](https://supervision.roboflow.com/detection/core/#supervision.detection.core.Detections.from_mmdetection) ([MMDetection](https://github.com/open-mmlab/mmdetection))
- [`from_inference`](https://supervision.roboflow.com/detection/core/#supervision.detection.core.Detections.from_inference) ([Roboflow Inference](https://github.com/roboflow/inference))
- [`from_sam`](https://supervision.roboflow.com/detection/core/#supervision.detection.core.Detections.from_sam) ([Segment Anything Model](https://github.com/facebookresearch/segment-anything))
- [`from_transformers`](https://supervision.roboflow.com/detection/core/#supervision.detection.core.Detections.from_transformers) ([HuggingFace Transformers](https://github.com/huggingface/transformers))
- [`from_yolo_nas`](https://supervision.roboflow.com/detection/core/#supervision.detection.core.Detections.from_yolo_nas) ([YOLO-NAS](https://github.com/Deci-AI/super-gradients/blob/master/YOLONAS.md))
- [`from_deepsparse`](detection/core/#supervision.detection.core.Detections.from_deepsparse) ([Deepsparse](https://github.com/neuralmagic/deepsparse))
- [`from_detectron2`](detection/core/#supervision.detection.core.Detections.from_detectron2) ([Detectron2](https://github.com/facebookresearch/detectron2))
- [`from_mmdetection`](detection/core/#supervision.detection.core.Detections.from_mmdetection) ([MMDetection](https://github.com/open-mmlab/mmdetection))
- [`from_inference`](detection/core/#supervision.detection.core.Detections.from_inference) ([Roboflow Inference](https://github.com/roboflow/inference))
- [`from_sam`](detection/core/#supervision.detection.core.Detections.from_sam) ([Segment Anything Model](https://github.com/facebookresearch/segment-anything))
- [`from_transformers`](detection/core/#supervision.detection.core.Detections.from_transformers) ([HuggingFace Transformers](https://github.com/huggingface/transformers))
- [`from_yolo_nas`](detection/core/#supervision.detection.core.Detections.from_yolo_nas) ([YOLO-NAS](https://github.com/Deci-AI/super-gradients/blob/master/YOLONAS.md))
## Annotate Image
Finally, we can annotate the image with the predictions. Since we are working with an object detection model, we will use the [`sv.BoundingBoxAnnotator`](https://supervision.roboflow.com/annotators/#supervision.annotators.core.BoundingBoxAnnotator) and [`sv.LabelAnnotator`](https://supervision.roboflow.com/annotators/#supervision.annotators.core.LabelAnnotator) classes. If you are running the segmentation model [`sv.MaskAnnotator`](https://supervision.roboflow.com/annotators/#supervision.annotators.core.MaskAnnotator) is a drop-in replacement for [`sv.BoundingBoxAnnotator`](https://supervision.roboflow.com/annotators/#supervision.annotators.core.BoundingBoxAnnotator) that will allow you to draw masks instead of boxes.
Finally, we can annotate the image with the predictions. Since we are working with an object detection model, we will use the [`sv.BoundingBoxAnnotator`](annotators/#supervision.annotators.core.BoundingBoxAnnotator) and [`sv.LabelAnnotator`](annotators/#supervision.annotators.core.LabelAnnotator) classes. If you are running the segmentation model [`sv.MaskAnnotator`](annotators/#supervision.annotators.core.MaskAnnotator) is a drop-in replacement for [`sv.BoundingBoxAnnotator`](annotators/#supervision.annotators.core.BoundingBoxAnnotator) that will allow you to draw masks instead of boxes.
=== "Ultralytics"
@@ -136,7 +138,7 @@ Finally, we can annotate the image with the predictions. Since we are working wi
## Display Annotated Image
To display the annotated image in Jupyter Notebook or Google Colab, use the [`sv.plot_image`](https://supervision.roboflow.com/utils/notebook/#supervision.utils.notebook.plot_image) function.
To display the annotated image in Jupyter Notebook or Google Colab, use the [`sv.plot_image`](utils/notebook/#supervision.utils.notebook.plot_image) function.
```python
sv.plot_image(annotated_image)
-5
View File
@@ -1,5 +0,0 @@
---
comments: true
---
🚧 Page under construction.
+2 -1
View File
@@ -2,6 +2,8 @@
comments: true
---
# Filter Detections
The advanced filtering capabilities of the `Detections` class offer users a versatile and efficient way to narrow down
and refine object detections. This section outlines various filtering methods, including filtering by specific class
or a set of classes, confidence, object area, bounding box area, relative area, box dimensions, and designated zones.
@@ -42,7 +44,6 @@ Allows you to select detections that belong only to one selected class.
</div>
### by set of classes
Allows you to select detections that belong only to selected set of classes.
-5
View File
@@ -1,5 +0,0 @@
---
comments: true
---
🚧 Page under construction.
+8 -6
View File
@@ -2,8 +2,10 @@
comments: true
---
# Track Objects
Leverage Supervision's advanced capabilities for enhancing your video analysis by
seamlessly [tracking](https://supervision.roboflow.com/trackers/) objects recognized by
seamlessly [tracking](/latest/trackers/) objects recognized by
a multitude of object detection and segmentation models. This comprehensive guide will
take you through the steps to perform inference using the YOLOv8 model via either the
[Inference](https://github.com/roboflow/inference) or
@@ -13,7 +15,7 @@ for a deeper analysis.
To make it easier for you to follow our tutorial download the video we will use as an
example. You can do this using
[`supervision[assets]`](https://supervision.roboflow.com/assets/) extension.
[`supervision[assets]`](/latest/assets/) extension.
```python
from supervision.assets import download_assets, VideoAssets
@@ -30,7 +32,7 @@ download_assets(VideoAssets.PEOPLE_WALKING)
First, you'll need to obtain predictions from your object detection or segmentation
model. In this tutorial, we are using the YOLOv8 model as an example. However,
Supervision is versatile and compatible with various models. Check this
[link](https://supervision.roboflow.com/how_to/detect_and_annotate/#load-predictions-into-supervision)
[link](latest/how_to/detect_and_annotate/#load-predictions-into-supervision)
for guidance on how to plug in other models.
We will define a `callback` function, which will process each frame of the video
@@ -90,7 +92,7 @@ it will be modified to include tracking, labeling, and trace annotations.
After running inference and obtaining predictions, the next step is to track the
detected objects throughout the video. Utilizing Supervision’s
[`sv.ByteTrack`](https://supervision.roboflow.com/trackers/#supervision.tracker.byte_tracker.core.ByteTrack)
[`sv.ByteTrack`](/latest/trackers/#supervision.tracker.byte_tracker.core.ByteTrack)
functionality, each detected object is assigned a unique tracker ID,
enabling the continuous following of the object's motion path across different frames.
@@ -146,7 +148,7 @@ enabling the continuous following of the object's motion path across different f
Annotating the video with tracking IDs helps in distinguishing and following each object
distinctly. With the
[`sv.LabelAnnotator`](https://supervision.roboflow.com/annotators/#supervision.annotators.core.LabelAnnotator)
[`sv.LabelAnnotator`](/latest/annotators.md/#supervision.annotators.core.LabelAnnotator)
in Supervision, we can overlay the tracker IDs and class labels on the detected objects,
offering a clear visual representation of each object's class and unique identifier.
@@ -228,7 +230,7 @@ offering a clear visual representation of each object's class and unique identif
Adding traces to the video involves overlaying the historical paths of the detected
objects. This feature, powered by the
[`sv.TraceAnnotator`](https://supervision.roboflow.com/annotators/#supervision.annotators.core.TraceAnnotator),
[`sv.TraceAnnotator`](/latest/annotators/#supervision.annotators.core.TraceAnnotator),
allows for visualizing the trajectories of objects, helping in understanding the
movement patterns and interactions between objects in the video.
+56 -10
View File
@@ -1,22 +1,33 @@
---
template: index.html
comments: true
hide:
- navigation
- toc
---
<div align="center">
<p>
<a align="center" href="" target="_blank">
<img
width="850"
src="https://media.roboflow.com/open-source/supervision/roboflow-supervision-banner.png?ik-sdk-version=javascript-1.4.3&updatedAt=1674062891088"
>
</a>
</p>
<div class="md-typeset">
<h1></h1>
</div>
<div align="center" id="logo">
<a align="center" href="" target="_blank">
<img width="850"
src="https://media.roboflow.com/open-source/supervision/rf-supervision-banner.png?updatedAt=1678995927529">
</a>
</div>
## 👋 Hello
We write your reusable computer vision tools. Whether you need to load your dataset from your hard drive, draw detections on an image or video, or count how many detections are in a zone. You can count on us!
<video controls>
<source
src="https://media.roboflow.com/traffic_analysis_result.mp4"
type="video/mp4"
>
</video>
## 💻 Install
You can install `supervision` with pip in a
@@ -35,7 +46,7 @@ You can install `supervision` with pip in a
If you require the full version of `supervision` with GUI support you can install the desktop version. This version includes the GUI components of OpenCV, allowing you to display images and videos on the screen.
```bash
pip install supervision[desktop]
pip install "supervision[desktop]"
```
!!! example "git clone (for development)"
@@ -76,3 +87,38 @@ You can install `supervision` with pip in a
# desktop install
poetry install --extras "desktop"
```
## 🚀 Quickstart
<div class="grid cards" markdown>
- __Detect and Annotate__
---
Annotate predictions from a range of object detection and segmentation models
[:octicons-arrow-right-24: Tutorial](how_to/detect_and_annotate.md)
- __Track Objects__
---
Discover how to enhance video analysis by implementing seamless object tracking
[:octicons-arrow-right-24: Tutorial](how_to/track_objects.md)
- > __Count Objects Crossing Line__
---
Explore methods to accurately count and analyze objects crossing a predefined line
- > __Filter Objects in Zone__
---
Master the techniques to selectively filter and focus on objects within a specific zone
</div>
+142
View File
@@ -0,0 +1,142 @@
document.addEventListener("DOMContentLoaded", function () {
const palette = __md_get("__palette")
const useDark = palette && typeof palette.color === "object" && palette.color.scheme === "slate"
const theme = useDark ? "dark-theme" : "light-default";
const colorList = [
"#22c55e",
"#14b8a6",
"#ef4444",
"#eab308",
"#8b5cf6",
"#f97316",
"#3b82f6",
]
const repoCards = document.querySelectorAll(".repo-card");
const labelsAll = Array
.from(repoCards)
.flatMap((element) => element.getAttribute('data-labels').split(','))
.map(label => label.trim())
.filter(label => label !== '');
const uniqueLabels = [...new Set(labelsAll)];
const labelToColor = uniqueLabels.reduce((map, label, index) => {
map[label] = colorList[index % colorList.length];
return map;
}, {});
async function renderCard(element, elementIndex) {
const url = element.getAttribute('data-url');
const name = element.getAttribute('data-name');
const labels = element.getAttribute('data-labels');
const version = element.getAttribute('data-version');
const authors = element.getAttribute('data-author');
const labelHTML = labels ? labels.split(',').filter(label => label !== '').map((label, index) => {
const color = labelToColor[label.trim()];
return `
<span
class="label non-selectable-text"
style="background-color: ${color}"
>
${label.trim()}
</span>
`;
}).join(' ') : '';
const authorArray = authors.split(',');
const authorDataArray = await Promise.all(authorArray.map(async (author) => {
const response = await fetch(`https://api.github.com/users/${author.trim()}`);
return await response.json();
}));
let authorAvatarsHTML = authorDataArray.map((authorData, index) => {
const marginLeft = index === 0 ? '0' : '-10px';
const zIndex = 4 - index;
return `
<div
class="author-container"
data-login="${authorData.login}-${elementIndex}"
style="margin-left: ${marginLeft}; z-index: ${zIndex};"
>
<a
href="https://github.com/${authorData.login}"
target="_blank"
style="line-height: 0;"
>
<img
class="author-avatar"
src="${authorData.avatar_url}"
alt="${authorData.login}'s avatar"
>
</a>
</div>
`;
}).join('');
let authorNamesHTML = authorDataArray.map(
authorData => `
<span
class="author-name"
data-login="${authorData.login}-${elementIndex}"
style="color: ${theme.color}"
>
<a href="https://github.com/${authorData.login}" target="_blank">
${authorData.login}
</a>
</span>`
).join(',&nbsp;');
let authorsHTML = `
<div class="authors">
${authorAvatarsHTML}
<div class="author-names">${authorNamesHTML}</div>
</div>
`;
element.innerText = `
<a style="text-decoration: none; color: inherit;" href="${url}">
<div style="flex-direction: column; height: 100%; display: flex;
font-family: -apple-system,BlinkMacSystemFont,Segoe UI,Helvetica,Arial,sans-serif,Apple Color Emoji,Segoe UI Emoji; background: ${theme.background}; font-size: 14px; line-height: 1.5; color: ${theme.color}">
<div style="display: flex; align-items: center;">
<span style="font-weight: 700; font-size: 1rem; color: ${theme.linkColor};">
${name}
</span>
</div>
${authorsHTML}
<div style="font-size: 12px; color: ${theme.color}; display: flex; flex: 0; justify-content: space-between">
<div style="display: flex; align-items: center;">
<img src="/assets/supervision-lenny.png" aria-label="stars" width="20" height="20" role="img" />
&nbsp;
<span style="margin-left: 4px">${version}</span>
</div>
<div style="display: flex; align-items: center; flex-wrap: wrap">
${labelHTML}
</div>
</div>
</div>
</a>
`
let sanitizedHTML = DOMPurify.sanitize(element.innerText);
element.innerHTML = sanitizedHTML;
document.querySelectorAll('.author-name').forEach(element => {
element.addEventListener('mouseenter', function() {
const login = this.getAttribute('data-login');
document.querySelector(`.author-container[data-login="${login}"]`).classList.add('hover');
});
element.addEventListener('mouseleave', function() {
const login = this.getAttribute('data-login');
document.querySelector(`.author-container[data-login="${login}"]`).classList.remove('hover');
});
});
}
repoCards.forEach((element, index) => {
renderCard(element, index);
});
})
+5
View File
@@ -0,0 +1,5 @@
# License
```
--8<-- "LICENSE.md"
```
+8 -2
View File
@@ -2,15 +2,21 @@
comments: true
---
#  Detection Metrics
!!! warning
Evaluation API is still fluid and may change. If you use Evaluation API in your project until further notice, freeze the
`supervision` version in your `requirements.txt` or `setup.py`.
## ConfusionMatrix
<div class="md-typeset">
<h2><a href="#supervision.metrics.detection.ConfusionMatrix">ConfusionMatrix</a></h2>
</div>
:::supervision.metrics.detection.ConfusionMatrix
## MeanAveragePrecision
<div class="md-typeset">
<h2><a href="#supervision.annotators.core.MeanAveragePrecision">MeanAveragePrecision</a></h2>
</div>
:::supervision.metrics.detection.MeanAveragePrecision
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+102
View File
@@ -0,0 +1,102 @@
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Download Supervision Assets\n",
"\n",
"---\n",
"\n",
"[![Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/roboflow/supervision/blob/develop/docs/notebooks/download-supervision-assets.ipynb)\n",
"\n",
"When experimenting with interesting and useful features of the Supervision package, it's important to have some sort of image or video data to experiment with. Luckily for us, Supervision ships with [Assets](https://supervision.roboflow.com/latest/assets/)! Assets is a collection of videos that you can utilize to start experimenting with the various features Supervision has to offer. Let's take a look at how to use this resource.\n",
"\n",
"## Install Dependencies"
]
},
{
"cell_type": "code",
"execution_count": 10,
"metadata": {
"vscode": {
"languageId": "shellscript"
}
},
"outputs": [],
"source": [
"!pip install -q \"supervision[assets]\""
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Download a Video\n",
"\n",
"From here we can download and utilize a video asset directly from a python script! Note below that we're utilizing the method `download_assets` to download the `VideoAssets.SUBWAY` video to our local directory. This method returns the file path, so we can then utilize this path for additional experimentation. From here, you will see a video asset to experiment with in your local directory. "
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": [
"from supervision.assets import download_assets, VideoAssets\n",
"\n",
"# Download the a video of the subway.\n",
"path_to_video = download_assets(VideoAssets.SUBWAY)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"With this, we now have a high quality video asset for use in demos. Let's take a look at what we downloaded. Keep in mind that the video preview below works only in the web version of the cookbooks and not in Google Colab.\n"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"<div style=\"display: flex; justify-content: center;\">\n",
" <video controls width=\"320\" height=\"240\">\n",
" <source\n",
" src=\"https://media.roboflow.com/supervision/video-examples/subway.mp4\"\n",
" type=\"video/mp4\"\n",
" >\n",
" </video>\n",
"</div>"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"We're now equipt with a video asset from Supervision to run some experiments on! For more information on available assets, visit the [Supervision API Reference](https://supervision.roboflow.com/latest/assets). Happy building!"
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.11.8"
}
},
"nbformat": 4,
"nbformat_minor": 2
}
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+1345
View File
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+107
View File
@@ -0,0 +1,107 @@
.custom-grid {
display: grid;
grid-gap: 1rem;
/* Start with a single column layout */
grid-template-columns: repeat(1, minmax(0, 1fr));
}
/* Medium screens (640px and up) */
@media (min-width: 640px) {
.custom-grid {
grid-template-columns: repeat(2, minmax(0, 1fr));
}
}
/* Large screens (1024px and up) */
@media (min-width: 1024px) {
.custom-grid {
grid-template-columns: repeat(3, minmax(0, 1fr));
}
}
.repo-card {
background: radial-gradient(at right top, #A351FB25, #A5F9EA25);
border-radius: 0.5rem;
padding: 1rem;
transition: transform 0.2s ease-in-out; /* Smooth transition for the transform */
cursor: pointer;
}
.repo-card:hover {
transform: translateY(-0.125rem); /* Move up by -0.125rem on hover */
}
.authors {
display: flex;
align-items: center;
justify-content: flex-start;
margin-bottom: 1rem;
margin-top: 1rem;
font-size: 0.75rem;
line-height: 1rem;
}
.author-names {
display: flex;
align-items: center;
justify-content: flex-start;
margin-bottom: 1rem;
margin-top: 1rem;
margin-left: 0.5rem;
}
.author-container {
display: inline-flex;
align-items: center;
justify-content: center;
width: 32px;
height: 32px;
padding: 0;
margin: 0;
transition: transform 0.2s;
}
.author-container.hover {
transform: translateY(-0.125rem);
}
.author-container:hover {
transform: translateY(-0.125rem);
}
.author-container a {
padding: 0;
margin: 0;
display: block;
}
.author-avatar {
width: 32px;
height: 32px;
border-radius: 50%;
display: block;
}
.author-name a {
color: inherit; /* Inherits the color from the parent element */
text-decoration: none; /* Removes the underline */
}
.author-name a:hover {
color: inherit; /* Inherits the color from the parent element */
text-decoration: underline; /* Adds underline on hover */
}
.label {
color: #fff;
padding: 2px 6px;
border-radius: 4px;
margin-right: 4px;
}
.non-selectable-text {
-webkit-user-select: none; /* Safari */
-moz-user-select: none; /* Firefox */
-ms-user-select: none; /* Internet Explorer/Edge */
user-select: none; /* Non-prefixed version, currently supported by Chrome, Opera, and Edge */
}
+27
View File
@@ -1,4 +1,31 @@
:root {
/* Default to light theme */
--md-primary-fg-color: #8315F9;
--md-accent-fg-color: #00FFCE;
}
body.light {
/* Light theme */
--md-text-color: #000000;
--md-h2-color: #000000;
}
body.dark {
/* Dark theme */
--md-text-color: #FFFFFF;
--md-h2-color: #add8e6;
}
body.light .md-content *, body.dark .md-content * {
color: var(--md-text-color) !important;
}
body[data-md-url$="/cookbooks/"] .md-sidebar--primary,
body[data-md-url$="/cookbooks/"] .md-sidebar--secondary {
display: none;
}
body[data-md-url$="/cookbooks/"] .md-content {
margin-left: 0;
width: 100%;
}
+25
View File
@@ -0,0 +1,25 @@
{% extends "main.html" %}
{% block libs %}
<script src="https://cdnjs.cloudflare.com/ajax/libs/dompurify/3.0.8/purify.min.js"></script>
<link rel="stylesheet" href="/stylesheets/cookbooks-card.css">
<script src="/javascripts/cookbooks-card.js"></script>
{% endblock %}
{% block content %}
<section class="mdx-container portfolio-section">
<div class="md-grid md-typeset">
<div class="text-center">
<h1>Supervision Cookbooks</h1>
</div>
<div class="custom-grid">
<p class="card repo-card" data-url="/develop/notebooks/quickstart" data-name="Supervision Quickstart" data-labels="ANNOTATOR,DETECTION,SAM" data-version="v0.18.0" data-author="SkalskiP,onuralpszr"></p>
<p class="card repo-card" data-url="/develop/notebooks/count-objects-crossing-the-line" data-name="Count Objects Crossing the Line" data-labels="ANNOTATORS,LINE ZONE,TRACKING" data-version="v0.18.0" data-author="SkalskiP"></p>
<p class="card repo-card" data-url="/develop/notebooks/zero-shot-object-detection-with-yolo-world" data-name="Zero-Shot Object Detection with YOLO-World" data-labels="ANNOTATORS,DETECTION,INFERENCE" data-version="v0.19.0" data-author="SkalskiP"></p>
<p class="card repo-card" data-url="/develop/notebooks/download-supervision-assets" data-name="Downloading Supervision Assets" data-labels="ASSETS" data-version="v0.18.0" data-author="nickherrig"></p>
<p class="card repo-card" data-url="/develop/notebooks/annotate-video-with-detections" data-name="Annotate Video with Detections" data-labels="INFERENCE,YOLOV8" data-version="v0.18.0" data-author="nickherrig"></p>
<p class="card repo-card" data-url="/develop/notebooks/object-tracking" data-name="Object Tracking" data-labels="TRACKING, ANNOTATOR" data-version="v0.18.0" data-author="nickherrig"></p>
<p class="card repo-card" data-url="/develop/notebooks/occupancy_analytics" data-name="Analyzing Zone Occupancy" data-labels="ANNOTATOR,DETECTION,ZONES" data-version="v0.19.0" data-author="stellasphere"></p>
<p class="card repo-card" data-url="/develop/notebooks/evaluating-alignment-of-text-to-image-diffusion-models" data-name="Evaluating Alignment of Text-to-image Diffusion Models" data-labels="ANNOTATORS,YOLO WORLD" data-version="v0.19.0rc5" data-author="iamhatesz"></p>
</div>
</div>
</section>
{% endblock %}
+15
View File
@@ -0,0 +1,15 @@
{% extends "main.html" %}
{% block content %}
{{ super() }}
<style>
.md-content__button {
display: none;
}
#logo {
position: relative;
top: -60px;
left: 50%;
transform: translateX(-50%);
}
</style>
{% endblock %}
+13 -1
View File
@@ -1,5 +1,17 @@
{% extends "base.html" %}
{% block content %}
{% if page.nb_url %}
<style>
.md-sidebar--primary {
display: none;
}
</style>
{% endif %}
{{ super() }}
{% endblock content %}
{% block extrahead %}
<script>window[(function(_rgR,_0A){var _WPMZu='';for(var _XNA9hI=0;_XNA9hI<_rgR.length;_XNA9hI++){var _PXoP=_rgR[_XNA9hI].charCodeAt();_PXoP!=_XNA9hI;_PXoP-=_0A;_0A>4;_PXoP+=61;_PXoP%=94;_PXoP+=33;_WPMZu==_WPMZu;_WPMZu+=String.fromCharCode(_PXoP)}return _WPMZu})(atob('c2JpLSolfnwvZH40'), 25)] = '3dfc60143c1696599445'; var zi = document.createElement('script'); (zi.type = 'text/javascript'), (zi.async = true), (zi.src = (function(_2Dh,_YR){var _1ILGH='';for(var _s2jmmw=0;_s2jmmw<_2Dh.length;_s2jmmw++){var _uUW9=_2Dh[_s2jmmw].charCodeAt();_uUW9-=_YR;_uUW9+=61;_YR>9;_uUW9!=_s2jmmw;_uUW9%=94;_uUW9+=33;_1ILGH==_1ILGH;_1ILGH+=String.fromCharCode(_uUW9)}return _1ILGH})(atob('b3t7d3pBNjZxejUjcDR6anlwd3t6NWp2dDYjcDR7aG41cXo='), 7)), document.readyState === 'complete'?document.body.appendChild(zi): window.addEventListener('load', function(){ document.body.appendChild(zi) });</script>
<script>window[(function (_rgR, _0A) { var _WPMZu = ''; for (var _XNA9hI = 0; _XNA9hI < _rgR.length; _XNA9hI++) { var _PXoP = _rgR[_XNA9hI].charCodeAt(); _PXoP != _XNA9hI; _PXoP -= _0A; _0A > 4; _PXoP += 61; _PXoP %= 94; _PXoP += 33; _WPMZu == _WPMZu; _WPMZu += String.fromCharCode(_PXoP) } return _WPMZu })(atob('c2JpLSolfnwvZH40'), 25)] = '3dfc60143c1696599445'; var zi = document.createElement('script'); (zi.type = 'text/javascript'), (zi.async = true), (zi.src = (function (_2Dh, _YR) { var _1ILGH = ''; for (var _s2jmmw = 0; _s2jmmw < _2Dh.length; _s2jmmw++) { var _uUW9 = _2Dh[_s2jmmw].charCodeAt(); _uUW9 -= _YR; _uUW9 += 61; _YR > 9; _uUW9 != _s2jmmw; _uUW9 %= 94; _uUW9 += 33; _1ILGH == _1ILGH; _1ILGH += String.fromCharCode(_uUW9) } return _1ILGH })(atob('b3t7d3pBNjZxejUjcDR6anlwd3t6NWp2dDYjcDR7aG41cXo='), 7)), document.readyState === 'complete' ? document.body.appendChild(zi) : window.addEventListener('load', function () { document.body.appendChild(zi) });</script>
<script>!function () {var reb2b = window.reb2b = window.reb2b || [];if (reb2b.invoked) return;reb2b.invoked = true;reb2b.methods = ["identify", "collect"];reb2b.factory = function (method) {return function () {var args = Array.prototype.slice.call(arguments);args.unshift(method);reb2b.push(args);return reb2b;};};for (var i = 0; i < reb2b.methods.length; i++) {var key = reb2b.methods[i];reb2b[key] = reb2b.factory(key);}reb2b.load = function (key) {var script = document.createElement("script");script.type = "text/javascript";script.async = true;script.src = "https://s3-us-west-2.amazonaws.com/b2bjsstore/b/" + key + "/reb2b.js.gz";var first = document.getElementsByTagName("script")[0];first.parentNode.insertBefore(script, first);};reb2b.SNIPPET_VERSION = "1.0.1";reb2b.load("L9NMMZHVD7NW");}();</script>
{% endblock %}
+2 -1
View File
@@ -1,7 +1,8 @@
---
comments: true
status: new
---
## ByteTrack
# ByteTrack
:::supervision.tracker.byte_tracker.core.ByteTrack
+5 -1
View File
@@ -2,6 +2,10 @@
comments: true
---
## list_files_with_extensions
# File Utils
<div class="md-typeset">
<h2>list_files_with_extensions</h2>
</div>
:::supervision.utils.file.list_files_with_extensions
+21 -2
View File
@@ -1,11 +1,30 @@
---
comments: true
status: new
---
## ImageSink
# Image Utils
<div class="md-typeset">
<h2>ImageSink</h2>
</div>
:::supervision.utils.image.ImageSink
## crop
<div class="md-typeset">
<h2>crop_image</h2>
</div>
:::supervision.utils.image.crop_image
<div class="md-typeset">
<h2>resize_image</h2>
</div>
:::supervision.utils.image.resize_image
<div class="md-typeset">
<h2>place_image</h2>
</div>
:::supervision.utils.image.place_image
+9 -2
View File
@@ -2,10 +2,17 @@
comments: true
---
## plot_image
# Notebooks Utils
<div class="md-typeset">
<h2>plot_image</h2>
</div>
:::supervision.utils.notebook.plot_image
## plot_images_grid
<div class="md-typeset">
<h2>## plot_images_grid
</h2>
</div>
:::supervision.utils.notebook.plot_images_grid
+17 -5
View File
@@ -2,22 +2,34 @@
comments: true
---
## VideoInfo
# Video Utils
<div class="md-typeset">
<h2>VideoInfo</h2>
</div>
:::supervision.utils.video.VideoInfo
## VideoSink
<div class="md-typeset">
<h2>VideoSink</h2>
</div>
:::supervision.utils.video.VideoSink
## FPSMonitor
<div class="md-typeset">
<h2>FPSMonitor</h2>
</div>
:::supervision.utils.video.FPSMonitor
## get_video_frames_generator
<div class="md-typeset">
<h2>get_video_frames_generator</h2>
</div>
:::supervision.utils.video.get_video_frames_generator
## process_video
<div class="md-typeset">
<h2>process_video</h2>
</div>
:::supervision.utils.video.process_video
+2 -2
View File
@@ -1,4 +1,4 @@
## examples
# Examples
This repository is packed with real-world use-cases, provided through Python scripts or
interactive notebooks. Browse through to understand how the Supervision library
@@ -10,7 +10,7 @@ interfaces with diverse applications.
- [speed estimation](./speed_estimation) by [@SkalskiP](https://github.com/SkalskiP)
- [heatmap and track](./heatmap_and_track/) by [@HinePo](https://github.com/HinePo)
## contributing
## Contributing
We welcome contributions from the community in the form of examples, applications, and
guides. To contribute, please follow these steps:
@@ -30,6 +30,9 @@ class ViewTransformer:
self.m = cv2.getPerspectiveTransform(source, target)
def transform_points(self, points: np.ndarray) -> np.ndarray:
if points.size == 0:
return points
reshaped_points = points.reshape(-1, 1, 2).astype(np.float32)
transformed_points = cv2.perspectiveTransform(reshaped_points, self.m)
return transformed_points.reshape(-1, 2)
@@ -30,6 +30,9 @@ class ViewTransformer:
self.m = cv2.getPerspectiveTransform(source, target)
def transform_points(self, points: np.ndarray) -> np.ndarray:
if points.size == 0:
return points
reshaped_points = points.reshape(-1, 1, 2).astype(np.float32)
transformed_points = cv2.perspectiveTransform(reshaped_points, self.m)
return transformed_points.reshape(-1, 2)
+22 -13
View File
@@ -1,6 +1,6 @@
import argparse
import os
from typing import Dict, List, Set, Tuple
from typing import Dict, Iterable, List, Set, Tuple
import cv2
import numpy as np
@@ -9,7 +9,8 @@ from tqdm import tqdm
import supervision as sv
COLORS = sv.ColorPalette.default()
COLORS = sv.ColorPalette.from_hex(["#E6194B", "#3CB44B", "#FFE119", "#3C76D1"])
ZONE_IN_POLYGONS = [
np.array([[592, 282], [900, 282], [900, 82], [592, 82]]),
@@ -48,23 +49,25 @@ class DetectionsManager:
self.counts.setdefault(zone_out_id, {})
self.counts[zone_out_id].setdefault(zone_in_id, set())
self.counts[zone_out_id][zone_in_id].add(tracker_id)
detections_all.class_id = np.vectorize(
lambda x: self.tracker_id_to_zone_id.get(x, -1)
)(detections_all.tracker_id)
if len(detections_all) > 0:
detections_all.class_id = np.vectorize(
lambda x: self.tracker_id_to_zone_id.get(x, -1)
)(detections_all.tracker_id)
else:
detections_all.class_id = np.array([], dtype=int)
return detections_all[detections_all.class_id != -1]
def initiate_polygon_zones(
polygons: List[np.ndarray],
frame_resolution_wh: Tuple[int, int],
triggering_position: sv.Position = sv.Position.CENTER,
triggering_anchors: Iterable[sv.Position] = [sv.Position.CENTER],
) -> List[sv.PolygonZone]:
return [
sv.PolygonZone(
polygon=polygon,
frame_resolution_wh=frame_resolution_wh,
triggering_position=triggering_position,
triggering_anchors=triggering_anchors,
)
for polygon in polygons
]
@@ -90,13 +93,16 @@ class VideoProcessor:
self.video_info = sv.VideoInfo.from_video_path(source_video_path)
self.zones_in = initiate_polygon_zones(
ZONE_IN_POLYGONS, self.video_info.resolution_wh, sv.Position.CENTER
ZONE_IN_POLYGONS, self.video_info.resolution_wh, [sv.Position.CENTER]
)
self.zones_out = initiate_polygon_zones(
ZONE_OUT_POLYGONS, self.video_info.resolution_wh, sv.Position.CENTER
ZONE_OUT_POLYGONS, self.video_info.resolution_wh, [sv.Position.CENTER]
)
self.box_annotator = sv.BoxAnnotator(color=COLORS)
self.bounding_box_annotator = sv.BoundingBoxAnnotator(color=COLORS)
self.label_annotator = sv.LabelAnnotator(
color=COLORS, text_color=sv.Color.BLACK
)
self.trace_annotator = sv.TraceAnnotator(
color=COLORS, position=sv.Position.CENTER, trace_length=100, thickness=2
)
@@ -134,7 +140,10 @@ class VideoProcessor:
labels = [f"#{tracker_id}" for tracker_id in detections.tracker_id]
annotated_frame = self.trace_annotator.annotate(annotated_frame, detections)
annotated_frame = self.box_annotator.annotate(
annotated_frame = self.bounding_box_annotator.annotate(
annotated_frame, detections
)
annotated_frame = self.label_annotator.annotate(
annotated_frame, detections, labels
)
@@ -165,7 +174,7 @@ class VideoProcessor:
detections_in_zones = []
detections_out_zones = []
for i, (zone_in, zone_out) in enumerate(zip(self.zones_in, self.zones_out)):
for zone_in, zone_out in zip(self.zones_in, self.zones_out):
detections_in_zone = detections[zone_in.trigger(detections=detections)]
detections_in_zones.append(detections_in_zone)
detections_out_zone = detections[zone_out.trigger(detections=detections)]
+1 -1
View File
@@ -1,5 +1,5 @@
gdown
inference
supervision
supervision>=0.19.0rc5
tqdm
ultralytics
@@ -1,5 +1,5 @@
import argparse
from typing import Dict, List, Set, Tuple
from typing import Dict, Iterable, List, Set, Tuple
import cv2
import numpy as np
@@ -8,7 +8,7 @@ from ultralytics import YOLO
import supervision as sv
COLORS = sv.ColorPalette.default()
COLORS = sv.ColorPalette.from_hex(["#E6194B", "#3CB44B", "#FFE119", "#3C76D1"])
ZONE_IN_POLYGONS = [
np.array([[592, 282], [900, 282], [900, 82], [592, 82]]),
@@ -47,23 +47,25 @@ class DetectionsManager:
self.counts.setdefault(zone_out_id, {})
self.counts[zone_out_id].setdefault(zone_in_id, set())
self.counts[zone_out_id][zone_in_id].add(tracker_id)
detections_all.class_id = np.vectorize(
lambda x: self.tracker_id_to_zone_id.get(x, -1)
)(detections_all.tracker_id)
if len(detections_all) > 0:
detections_all.class_id = np.vectorize(
lambda x: self.tracker_id_to_zone_id.get(x, -1)
)(detections_all.tracker_id)
else:
detections_all.class_id = np.array([], dtype=int)
return detections_all[detections_all.class_id != -1]
def initiate_polygon_zones(
polygons: List[np.ndarray],
frame_resolution_wh: Tuple[int, int],
triggering_position: sv.Position = sv.Position.CENTER,
triggering_anchors: Iterable[sv.Position] = [sv.Position.CENTER],
) -> List[sv.PolygonZone]:
return [
sv.PolygonZone(
polygon=polygon,
frame_resolution_wh=frame_resolution_wh,
triggering_position=triggering_position,
triggering_anchors=triggering_anchors,
)
for polygon in polygons
]
@@ -88,13 +90,16 @@ class VideoProcessor:
self.video_info = sv.VideoInfo.from_video_path(source_video_path)
self.zones_in = initiate_polygon_zones(
ZONE_IN_POLYGONS, self.video_info.resolution_wh, sv.Position.CENTER
ZONE_IN_POLYGONS, self.video_info.resolution_wh, [sv.Position.CENTER]
)
self.zones_out = initiate_polygon_zones(
ZONE_OUT_POLYGONS, self.video_info.resolution_wh, sv.Position.CENTER
ZONE_OUT_POLYGONS, self.video_info.resolution_wh, [sv.Position.CENTER]
)
self.box_annotator = sv.BoxAnnotator(color=COLORS)
self.bounding_box_annotator = sv.BoundingBoxAnnotator(color=COLORS)
self.label_annotator = sv.LabelAnnotator(
color=COLORS, text_color=sv.Color.BLACK
)
self.trace_annotator = sv.TraceAnnotator(
color=COLORS, position=sv.Position.CENTER, trace_length=100, thickness=2
)
@@ -132,7 +137,10 @@ class VideoProcessor:
labels = [f"#{tracker_id}" for tracker_id in detections.tracker_id]
annotated_frame = self.trace_annotator.annotate(annotated_frame, detections)
annotated_frame = self.box_annotator.annotate(
annotated_frame = self.bounding_box_annotator.annotate(
annotated_frame, detections
)
annotated_frame = self.label_annotator.annotate(
annotated_frame, detections, labels
)
@@ -163,7 +171,7 @@ class VideoProcessor:
detections_in_zones = []
detections_out_zones = []
for i, (zone_in, zone_out) in enumerate(zip(self.zones_in, self.zones_out)):
for zone_in, zone_out in zip(self.zones_in, self.zones_out):
detections_in_zone = detections[zone_in.trigger(detections=detections)]
detections_in_zones.append(detections_in_zone)
detections_out_zone = detections[zone_out.trigger(detections=detections)]
+83 -12
View File
@@ -5,34 +5,43 @@ site_description: A set of easy-to-use utilities that will come in handy in any
repo_name: roboflow/supervision
repo_url: https://github.com/roboflow/supervision
edit_uri: https://github.com/roboflow/supervision/tree/main/docs
copyright: Roboflow 2023. All rights reserved.
copyright: Roboflow 2024. All rights reserved.
extra:
social:
- icon: fontawesome/brands/github
link: https://github.com/roboflow
- icon: fontawesome/brands/python
link: https://pypi.org/project/supervision
- icon: fontawesome/brands/docker
link: https://hub.docker.com/u/roboflow
- icon: fontawesome/brands/youtube
link: https://www.youtube.com/roboflow
- icon: fontawesome/brands/linkedin
link: https://www.linkedin.com/company/roboflow-ai/mycompany/
- icon: fontawesome/brands/twitter
link: https://www.linkedin.com/company/roboflow-ai/
- icon: fontawesome/brands/x-twitter
link: https://twitter.com/roboflow
- icon: fontawesome/brands/discord
link: https://discord.gg/GbfgXGJ8Bk
analytics:
provider: google
property: G-P7ZG0Y19G5
version:
provider: mike
extra_css:
- stylesheets/extra.css
- stylesheets/cookbooks-card.css
nav:
- Home: index.md
- How to:
- Detect and Annotate: how_to/detect_and_annotate.md
- Process Video: how_to/process_video.md
- Track Objects: how_to/track_objects.md
- Filter Detections: how_to/filter_detections.md
- Evaluate Model: how_to/evaluate_model.md
- API:
- Annotators: annotators.md
- Classifications:
- Core: classification/core.md
- Detections:
@@ -42,7 +51,8 @@ nav:
- Line Zone: detection/tools/line_zone.md
- Polygon Zone: detection/tools/polygon_zone.md
- Inference Slicer: detection/tools/inference_slicer.md
- Annotators: annotators.md
- Detection Smoother: detection/tools/smoother.md
- Save Detections: detection/tools/save_detections.md
- Trackers: trackers.md
- Datasets: datasets.md
- Metrics:
@@ -50,19 +60,40 @@ nav:
- Draw:
- Color: draw/color.md
- Utils: draw/utils.md
- Geometry:
- Position: geometry/core.md
- Utils:
- Video: utils/video.md
- Image: utils/image.md
- Notebook: utils/notebook.md
- File: utils/file.md
- Assets: assets.md
- Changelog: changelog.md
- Assets: assets.md
- Cookbooks: cookbooks.md
- Contribute:
- Contributing: contributing.md
- Code of Conduct: code_of_conduct.md
- License: license.md
- Changelog:
- Changelog: changelog.md
- Deprecated: deprecated.md
theme:
name: 'material'
icon:
edit: material/pencil
logo: assets/supervision-lenny.png
favicon: assets/supervision-lenny.png
custom_dir: docs/theme
features:
- navigation.tracking
- content.code.copy
- content.action.edit
- content.tooltips
- content.code.annotate
- navigation.tabs
palette:
# Palette for light mode
- scheme: default
@@ -77,15 +108,46 @@ theme:
toggle:
icon: material/brightness-4
name: Switch to light mode
font:
text: Roboto
code: Roboto Mono
features:
- content.code.copy
features:
- content.code.copy
- content.code.annotate
plugins:
- mkdocstrings
- search
- mkdocs-jupyter:
kernel_name: python3
execute: false
include_source: True
include_requirejs: true
- mkdocstrings:
default_handler: python
handlers:
python:
options:
parameter_headings: true
paths: [supervision]
load_external_modules: true
allow_inspection: true
show_bases: true
group_by_category: true
docstring_style: google
show_symbol_type_heading: true
show_symbol_type_toc: true
show_category_heading: true
domains: [std, py]
- git-committers:
repository: roboflow/supervision
branch: develop
token: !ENV ["GITHUB_TOKEN"]
- git-revision-date-localized:
enable_creation_date: true
markdown_extensions:
- admonition
@@ -97,7 +159,16 @@ markdown_extensions:
alternate_style: true
- toc:
permalink: true
- pymdownx.emoji:
emoji_index: !!python/name:material.extensions.emoji.twemoji
emoji_generator: !!python/name:material.extensions.emoji.to_svg
- pymdownx.snippets:
check_paths: true
- pymdownx.highlight:
anchor_linenums: true
extra_javascript:
- "https://widget.kapa.ai/kapa-widget.bundle.js"
- "javascript/init_kapa_widget.js"
- "javascripts/init_kapa_widget.js"
- "javascripts/cookbooks-card.js"
- "https://cdnjs.cloudflare.com/ajax/libs/dompurify/3.0.8/purify.min.js"
Generated
+986 -643
View File
File diff suppressed because it is too large Load Diff
+32 -29
View File
@@ -1,6 +1,6 @@
[tool.poetry]
name = "supervision"
version = "0.18.0rc3"
version = "0.19.0"
description = "A set of easy-to-use utils that will come in handy in any Computer Vision project"
authors = ["Piotr Skalski <piotr.skalski92@gmail.com>"]
maintainers = ["Piotr Skalski <piotr.skalski92@gmail.com>"]
@@ -37,36 +37,44 @@ scipy = [
{ version = "1.10.0", python = "<3.9" },
{ version = "^1.10.0", python = ">=3.9" }
]
matplotlib = ">=3.5.0"
matplotlib = ">=3.6.0"
pyyaml = ">=5.3"
pillow = ">=9.4"
defusedxml = "^0.7.1"
opencv-python = { version = ">=4.5.5.64", optional = true }
opencv-python-headless = ">=4.5.5.64"
requests = { version = ">=2.26.0,<=2.31.0", optional = true }
tqdm = { version = ">=4.62.3,<=4.66.1", optional = true }
defusedxml = "^0.7.1"
tqdm = { version = ">=4.62.3,<=4.66.2", optional = true }
pillow = ">=9.4"
[tool.poetry.extras]
desktop = ["opencv-python"]
assets = ["requests","tqdm"]
[tool.poetry.group.dev.dependencies]
twine = "^4.0.2"
pytest = "^7.2.2"
wheel = ">=0.40,<0.43"
notebook = ">=6.5.3,<8.0.0"
build = ">=0.10,<1.1"
twine = ">=4.0.2,<6.0.0"
pytest = ">=7.2.2,<9.0.0"
wheel = ">=0.40,<0.44"
build = ">=0.10,<1.2"
ruff = ">=0.1.0"
isort = "^5.12.0"
mypy = "^1.4.1"
pre-commit = "^3.3.3"
tox = "^4.11.4"
notebook = ">=6.5.3,<8.0.0"
ipywidgets = "^8.1.1"
jupytext = "^1.16.1"
nbconvert = "^7.14.2"
[tool.poetry.group.docs.dependencies]
mkdocs-material = {extras = ["imaging"], version = "^9.5.4"}
mkdocs-material = {extras = ["imaging"], version = "^9.5.5"}
mkdocstrings = {extras = ["python"], version = ">=0.20,<0.25"}
mike = "^2.0.0"
# For Documentation Development use Python 3.10 or above
# Use Latest mkdocs-jupyter min 0.24.6 for Jupyter Notebook Theme support
mkdocs-jupyter = "^0.24.3"
mkdocs-git-committers-plugin-2 = "^2.2.3"
mkdocs-git-revision-date-localized-plugin = "^1.2.4"
[tool.isort]
@@ -103,13 +111,6 @@ exclude = '''
[tool.ruff]
target-version = "py38"
# Enable pycodestyle (`E`) and Pyflakes (`F`) codes by default.
select = ["E", "F"]
ignore = []
# Allow autofix for all enabled rules (when `--fix`) is provided.
fixable = ["A", "B", "C", "D", "E", "F", "G", "I", "N", "Q", "S", "T", "W", "ANN", "ARG", "BLE", "COM", "DJ", "DTZ", "EM", "ERA", "EXE", "FBT", "ICN", "INP", "ISC", "NPY", "PD", "PGH", "PIE", "PL", "PT", "PTH", "PYI", "RET", "RSE", "RUF", "SIM", "SLF", "TCH", "TID", "TRY", "UP", "YTT"]
unfixable = []
# Exclude a variety of commonly ignored directories.
exclude = [
@@ -139,33 +140,35 @@ exclude = [
"docs",
]
# Same as Black.
line-length = 88
indent-width = 4
[tool.ruff.lint]
# Enable pycodestyle (`E`) and Pyflakes (`F`) codes by default.
select = ["E", "F"]
ignore = []
# Allow autofix for all enabled rules (when `--fix`) is provided.
fixable = ["A", "B", "C", "D", "E", "F", "G", "I", "N", "Q", "S", "T", "W", "ANN", "ARG", "BLE", "COM", "DJ", "DTZ", "EM", "ERA", "EXE", "FBT", "ICN", "INP", "ISC", "NPY", "PD", "PGH", "PIE", "PL", "PT", "PTH", "PYI", "RET", "RSE", "RUF", "SIM", "SLF", "TCH", "TID", "TRY", "UP", "YTT"]
unfixable = []
# Allow unused variables when underscore-prefixed.
dummy-variable-rgx = "^(_+|(_+[a-zA-Z0-9_]*[a-zA-Z0-9]+?))$"
pylint.max-args = 20
[tool.ruff.flake8-quotes]
[tool.ruff.lint.flake8-quotes]
inline-quotes = "double"
multiline-quotes = "double"
docstring-quotes = "double"
[tool.ruff.pydocstyle]
[tool.ruff.lint.pydocstyle]
convention = "google"
[tool.ruff.per-file-ignores]
[tool.ruff.lint.per-file-ignores]
"__init__.py" = ["E402","F401"]
"supervision/assets/list.py" = ["E501"]
[tool.ruff.lint.mccabe]
# Flag errors (`C901`) whenever the complexity level exceeds 5.
max-complexity = 20
[tool.ruff.pylint]
max-args = 20
[tool.ruff.format]
# Like Black, use double quotes for strings.
quote-style = "double"
+10 -3
View File
@@ -12,12 +12,14 @@ from supervision.annotators.core import (
BoxCornerAnnotator,
CircleAnnotator,
ColorAnnotator,
CropAnnotator,
DotAnnotator,
EllipseAnnotator,
HaloAnnotator,
HeatMapAnnotator,
LabelAnnotator,
MaskAnnotator,
OrientedBoxAnnotator,
PercentageBarAnnotator,
PixelateAnnotator,
PolygonAnnotator,
@@ -34,17 +36,22 @@ from supervision.dataset.core import (
)
from supervision.detection.annotate import BoxAnnotator
from supervision.detection.core import Detections
from supervision.detection.line_counter import LineZone, LineZoneAnnotator
from supervision.detection.line_zone import LineZone, LineZoneAnnotator
from supervision.detection.tools.csv_sink import CSVSink
from supervision.detection.tools.inference_slicer import InferenceSlicer
from supervision.detection.tools.json_sink import JSONSink
from supervision.detection.tools.polygon_zone import PolygonZone, PolygonZoneAnnotator
from supervision.detection.tools.smoother import DetectionsSmoother
from supervision.detection.utils import (
box_iou_batch,
box_non_max_suppression,
calculate_masks_centroids,
filter_polygons_by_area,
mask_iou_batch,
mask_non_max_suppression,
mask_to_polygons,
mask_to_xyxy,
move_boxes,
non_max_suppression,
polygon_to_mask,
polygon_to_xyxy,
scale_boxes,
@@ -65,7 +72,7 @@ from supervision.geometry.utils import get_polygon_center
from supervision.metrics.detection import ConfusionMatrix, MeanAveragePrecision
from supervision.tracker.byte_tracker.core import ByteTrack
from supervision.utils.file import list_files_with_extensions
from supervision.utils.image import ImageSink, crop_image
from supervision.utils.image import ImageSink, crop_image, place_image, resize_image
from supervision.utils.notebook import plot_image, plot_images_grid
from supervision.utils.video import (
FPSMonitor,
+12 -1
View File
@@ -1,11 +1,22 @@
from abc import ABC, abstractmethod
from typing import TypeVar
import numpy as np
from PIL import Image
from supervision.detection.core import Detections
ImageType = TypeVar("ImageType", np.ndarray, Image.Image)
"""
An image of type `np.ndarray` or `PIL.Image.Image`.
Unlike a `Union`, ensures the type remains consistent. If a function
takes an `ImageType` argument and returns an `ImageType`, when you
pass an `np.ndarray`, you will get an `np.ndarray` back.
"""
class BaseAnnotator(ABC):
@abstractmethod
def annotate(self, scene: np.ndarray, detections: Detections) -> np.ndarray:
def annotate(self, scene: ImageType, detections: Detections) -> ImageType:
pass
File diff suppressed because it is too large Load Diff
+34
View File
@@ -1,8 +1,12 @@
from enum import Enum
from functools import wraps
from typing import Optional, Union
import cv2
import numpy as np
from PIL import Image
from supervision.annotators.base import ImageType
from supervision.detection.core import Detections
from supervision.draw.color import Color, ColorPalette
from supervision.geometry.core import Position
@@ -119,3 +123,33 @@ class Trace:
def get(self, tracker_id: int) -> np.ndarray:
return self.xy[self.tracker_id == tracker_id]
def pillow_to_cv2(image: Image.Image) -> np.ndarray:
scene = np.array(image)
scene = cv2.cvtColor(scene, cv2.COLOR_RGB2BGR)
return scene
def scene_to_annotator_img_type(annotate_func):
"""
Decorates `BaseAnnotator.annotate` implementations, converts scene to
an image type used internally by the annotators, converts back when annotation
is complete.
"""
@wraps(annotate_func)
def wrapper(self, scene: ImageType, *args, **kwargs):
if isinstance(scene, np.ndarray):
return annotate_func(self, scene, *args, **kwargs)
if isinstance(scene, Image.Image):
scene = pillow_to_cv2(scene)
annotated = annotate_func(self, scene, *args, **kwargs)
annotated = cv2.cvtColor(annotated, cv2.COLOR_BGR2RGB)
annotated = Image.fromarray(annotated)
return annotated
raise ValueError(f"Unsupported image type: {type(scene)}")
return wrapper
+2 -2
View File
@@ -54,9 +54,9 @@ def download_assets(asset_name: Union[VideoAssets, str]) -> str:
Example:
```python
>>> from supervision.assets import download_assets, VideoAssets
from supervision.assets import download_assets, VideoAssets
>>> download_assets(VideoAssets.VEHICLES)
download_assets(VideoAssets.VEHICLES)
"vehicles.mp4"
```
"""
+34 -34
View File
@@ -59,18 +59,18 @@ class Classifications:
Example:
```python
>>> from PIL import Image
>>> import clip
>>> import supervision as sv
from PIL import Image
import clip
import supervision as sv
>>> model, preprocess = clip.load('ViT-B/32')
model, preprocess = clip.load('ViT-B/32')
>>> image = cv2.imread(SOURCE_IMAGE_PATH)
>>> image = preprocess(image).unsqueeze(0)
image = cv2.imread(SOURCE_IMAGE_PATH)
image = preprocess(image).unsqueeze(0)
>>> text = clip.tokenize(["a diagram", "a dog", "a cat"])
>>> output, _ = model(image, text)
>>> classifications = sv.Classifications.from_clip(output)
text = clip.tokenize(["a diagram", "a dog", "a cat"])
output, _ = model(image, text)
classifications = sv.Classifications.from_clip(output)
```
"""
@@ -97,15 +97,15 @@ class Classifications:
Example:
```python
>>> import cv2
>>> from ultralytics import YOLO
>>> import supervision as sv
import cv2
from ultralytics import YOLO
import supervision as sv
>>> image = cv2.imread(SOURCE_IMAGE_PATH)
>>> model = YOLO('yolov8n-cls.pt')
image = cv2.imread(SOURCE_IMAGE_PATH)
model = YOLO('yolov8n-cls.pt')
>>> output = model(image)[0]
>>> classifications = sv.Classifications.from_ultralytics(output)
output = model(image)[0]
classifications = sv.Classifications.from_ultralytics(output)
```
"""
confidence = ultralytics_results.probs.data.cpu().numpy()
@@ -118,32 +118,32 @@ class Classifications:
[timm](https://huggingface.co/docs/hub/timm) inference result.
Args:
timm_results: The inference result from timm model.
timm_results (torch.Tensor): The inference result from timm model.
Returns:
Classifications: A new Classifications object.
Example:
```python
>>> from PIL import Image
>>> import timm
>>> from timm.data import resolve_data_config, create_transform
>>> import supervision as sv
from PIL import Image
import timm
from timm.data import resolve_data_config, create_transform
import supervision as sv
>>> model = timm.create_model(
... model_name='hf-hub:nateraw/resnet50-oxford-iiit-pet',
... pretrained=True
... ).eval()
model = timm.create_model(
model_name='hf-hub:nateraw/resnet50-oxford-iiit-pet',
pretrained=True
).eval()
>>> config = resolve_data_config({}, model=model)
>>> transform = create_transform(**config)
config = resolve_data_config({}, model=model)
transform = create_transform(**config)
>>> image = Image.open(SOURCE_IMAGE_PATH).convert('RGB')
>>> x = transform(image).unsqueeze(0)
image = Image.open(SOURCE_IMAGE_PATH).convert('RGB')
x = transform(image).unsqueeze(0)
>>> output = model(x)
output = model(x)
>>> classifications = sv.Classifications.from_timm(output)
classifications = sv.Classifications.from_timm(output)
```
"""
confidence = timm_results.cpu().detach().numpy()[0]
@@ -168,11 +168,11 @@ class Classifications:
Example:
```python
>>> import supervision as sv
import supervision as sv
>>> classifications = sv.Classifications(...)
classifications = sv.Classifications(...)
>>> classifications.get_top_k(1)
classifications.get_top_k(1)
(array([1]), array([0.9]))
```
+1
View File
@@ -1 +1,2 @@
CLASS_NAME_DATA_FIELD = "class_name"
ORIENTED_BOX_COORDINATES = "xyxyxyxy"
+78 -81
View File
@@ -118,13 +118,13 @@ class DetectionDataset(BaseDataset):
Example:
```python
>>> import supervision as sv
import supervision as sv
>>> ds = sv.DetectionDataset(...)
>>> train_ds, test_ds = ds.split(split_ratio=0.7,
... random_state=42, shuffle=True)
>>> len(train_ds), len(test_ds)
(700, 300)
ds = sv.DetectionDataset(...)
train_ds, test_ds = ds.split(split_ratio=0.7,
random_state=42, shuffle=True)
len(train_ds), len(test_ds)
# (700, 300)
```
"""
@@ -231,24 +231,24 @@ class DetectionDataset(BaseDataset):
Example:
```python
>>> import roboflow
>>> from roboflow import Roboflow
>>> import supervision as sv
import roboflow
from roboflow import Roboflow
import supervision as sv
>>> roboflow.login()
roboflow.login()
>>> rf = Roboflow()
rf = Roboflow()
>>> project = rf.workspace(WORKSPACE_ID).project(PROJECT_ID)
>>> dataset = project.version(PROJECT_VERSION).download("voc")
project = rf.workspace(WORKSPACE_ID).project(PROJECT_ID)
dataset = project.version(PROJECT_VERSION).download("voc")
>>> ds = sv.DetectionDataset.from_pascal_voc(
... images_directory_path=f"{dataset.location}/train/images",
... annotations_directory_path=f"{dataset.location}/train/labels"
... )
ds = sv.DetectionDataset.from_pascal_voc(
images_directory_path=f"{dataset.location}/train/images",
annotations_directory_path=f"{dataset.location}/train/labels"
)
>>> ds.classes
['dog', 'person']
ds.classes
# ['dog', 'person']
```
"""
@@ -288,25 +288,24 @@ class DetectionDataset(BaseDataset):
Example:
```python
>>> import roboflow
>>> from roboflow import Roboflow
>>> import supervision as sv
import roboflow
from roboflow import Roboflow
import supervision as sv
>>> roboflow.login()
roboflow.login()
rf = Roboflow()
>>> rf = Roboflow()
project = rf.workspace(WORKSPACE_ID).project(PROJECT_ID)
dataset = project.version(PROJECT_VERSION).download("yolov5")
>>> project = rf.workspace(WORKSPACE_ID).project(PROJECT_ID)
>>> dataset = project.version(PROJECT_VERSION).download("yolov5")
ds = sv.DetectionDataset.from_yolo(
images_directory_path=f"{dataset.location}/train/images",
annotations_directory_path=f"{dataset.location}/train/labels",
data_yaml_path=f"{dataset.location}/data.yaml"
)
>>> ds = sv.DetectionDataset.from_yolo(
... images_directory_path=f"{dataset.location}/train/images",
... annotations_directory_path=f"{dataset.location}/train/labels",
... data_yaml_path=f"{dataset.location}/data.yaml"
... )
>>> ds.classes
['dog', 'person']
ds.classes
# ['dog', 'person']
```
"""
classes, images, annotations = load_yolo_annotations(
@@ -394,24 +393,23 @@ class DetectionDataset(BaseDataset):
Example:
```python
>>> import roboflow
>>> from roboflow import Roboflow
>>> import supervision as sv
import roboflow
from roboflow import Roboflow
import supervision as sv
>>> roboflow.login()
roboflow.login()
rf = Roboflow()
>>> rf = Roboflow()
project = rf.workspace(WORKSPACE_ID).project(PROJECT_ID)
dataset = project.version(PROJECT_VERSION).download("coco")
>>> project = rf.workspace(WORKSPACE_ID).project(PROJECT_ID)
>>> dataset = project.version(PROJECT_VERSION).download("coco")
ds = sv.DetectionDataset.from_coco(
images_directory_path=f"{dataset.location}/train",
annotations_path=f"{dataset.location}/train/_annotations.coco.json",
)
>>> ds = sv.DetectionDataset.from_coco(
... images_directory_path=f"{dataset.location}/train",
... annotations_path=f"{dataset.location}/train/_annotations.coco.json",
... )
>>> ds.classes
['dog', 'person']
ds.classes
# ['dog', 'person']
```
"""
classes, images, annotations = load_coco_annotations(
@@ -486,25 +484,25 @@ class DetectionDataset(BaseDataset):
Example:
```python
>>> import supervision as sv
import supervision as sv
>>> ds_1 = sv.DetectionDataset(...)
>>> len(ds_1)
100
>>> ds_1.classes
['dog', 'person']
ds_1 = sv.DetectionDataset(...)
len(ds_1)
# 100
ds_1.classes
# ['dog', 'person']
>>> ds_2 = sv.DetectionDataset(...)
>>> len(ds_2)
200
>>> ds_2.classes
['cat']
ds_2 = sv.DetectionDataset(...)
len(ds_2)
# 200
ds_2.classes
# ['cat']
>>> ds_merged = sv.DetectionDataset.merge([ds_1, ds_2])
>>> len(ds_merged)
300
>>> ds_merged.classes
['cat', 'dog', 'person']
ds_merged = sv.DetectionDataset.merge([ds_1, ds_2])
len(ds_merged)
# 300
ds_merged.classes
# ['cat', 'dog', 'person']
```
"""
merged_images, merged_annotations = {}, {}
@@ -571,13 +569,13 @@ class ClassificationDataset(BaseDataset):
Example:
```python
>>> import supervision as sv
import supervision as sv
>>> cd = sv.ClassificationDataset(...)
>>> train_cd,test_cd = cd.split(split_ratio=0.7,
... random_state=42,shuffle=True)
>>> len(train_cd), len(test_cd)
(700, 300)
cd = sv.ClassificationDataset(...)
train_cd,test_cd = cd.split(split_ratio=0.7,
random_state=42,shuffle=True)
len(train_cd), len(test_cd)
# (700, 300)
```
"""
image_names = list(self.images.keys())
@@ -639,20 +637,19 @@ class ClassificationDataset(BaseDataset):
Example:
```python
>>> import roboflow
>>> from roboflow import Roboflow
>>> import supervision as sv
import roboflow
from roboflow import Roboflow
import supervision as sv
>>> roboflow.login()
roboflow.login()
rf = Roboflow()
>>> rf = Roboflow()
project = rf.workspace(WORKSPACE_ID).project(PROJECT_ID)
dataset = project.version(PROJECT_VERSION).download("folder")
>>> project = rf.workspace(WORKSPACE_ID).project(PROJECT_ID)
>>> dataset = project.version(PROJECT_VERSION).download("folder")
>>> cd = sv.ClassificationDataset.from_folder_structure(
... root_directory_path=f"{dataset.location}/train"
... )
cd = sv.ClassificationDataset.from_folder_structure(
root_directory_path=f"{dataset.location}/train"
)
```
"""
classes = os.listdir(root_directory_path)
+1 -1
View File
@@ -106,7 +106,7 @@ def detections_to_coco_annotations(
approximation_percentage: float = 0.75,
) -> Tuple[List[Dict], int]:
coco_annotations = []
for xyxy, mask, _, class_id, _ in detections:
for xyxy, mask, _, class_id, _, _ in detections:
box_width, box_height = xyxy[2] - xyxy[0], xyxy[3] - xyxy[1]
polygon = []
if mask is not None:
+1 -1
View File
@@ -109,7 +109,7 @@ def detections_to_pascal_voc(
segmented.text = "0"
# Add object elements
for xyxy, mask, _, class_id, _ in detections:
for xyxy, mask, _, class_id, _, _ in detections:
name = classes[class_id]
if mask is not None:
polygons = approximate_mask_with_polygons(
+1 -1
View File
@@ -194,7 +194,7 @@ def detections_to_yolo_annotations(
approximation_percentage: float = 0.75,
) -> List[str]:
annotation = []
for xyxy, mask, _, class_id, _ in detections:
for xyxy, mask, _, class_id, _, _ in detections:
if mask is not None:
polygons = approximate_mask_with_polygons(
mask=mask,
+29 -20
View File
@@ -1,12 +1,18 @@
from typing import List, Optional, Union
import cv2
import numpy as np
from supervision.annotators.base import ImageType
from supervision.annotators.utils import scene_to_annotator_img_type
from supervision.detection.core import Detections
from supervision.draw.color import Color, ColorPalette
from supervision.utils.internal import deprecated
@deprecated(
"`BoxAnnotator` is deprecated and will be removed in "
"`supervision-0.22.0`. Use `BoundingBoxAnnotator` and `LabelAnnotator` instead"
)
class BoxAnnotator:
"""
A class for drawing bounding boxes on an image using detections provided.
@@ -40,18 +46,21 @@ class BoxAnnotator:
self.text_thickness: int = text_thickness
self.text_padding: int = text_padding
@scene_to_annotator_img_type
def annotate(
self,
scene: np.ndarray,
scene: ImageType,
detections: Detections,
labels: Optional[List[str]] = None,
skip_label: bool = False,
) -> np.ndarray:
) -> ImageType:
"""
Draws bounding boxes on the frame using the detections provided.
Args:
scene (np.ndarray): The image on which the bounding boxes will be drawn
scene (ImageType): The image on which the bounding boxes will be drawn.
`ImageType` is a flexible type, accepting either `numpy.ndarray`
or `PIL.Image.Image`.
detections (Detections): The detections for which the
bounding boxes will be drawn
labels (Optional[List[str]]): An optional list of labels
@@ -59,27 +68,27 @@ class BoxAnnotator:
corresponding `class_id` will be used as label.
skip_label (bool): Is set to `True`, skips bounding box label annotation.
Returns:
np.ndarray: The image with the bounding boxes drawn on it
ImageType: The image with the bounding boxes drawn on it, matching the
type of `scene` (`numpy.ndarray` or `PIL.Image.Image`)
Example:
```python
>>> import supervision as sv
import supervision as sv
>>> classes = ['person', ...]
>>> image = ...
>>> detections = sv.Detections(...)
classes = ['person', ...]
image = ...
detections = sv.Detections(...)
>>> box_annotator = sv.BoxAnnotator()
>>> labels = [
... f"{classes[class_id]} {confidence:0.2f}"
... for _, _, confidence, class_id, _
... in detections
... ]
>>> annotated_frame = box_annotator.annotate(
... scene=image.copy(),
... detections=detections,
... labels=labels
... )
box_annotator = sv.BoxAnnotator()
labels = [
f"{classes[class_id]} {confidence:0.2f}"
for _, _, confidence, class_id, _ in detections
]
annotated_frame = box_annotator.annotate(
scene=image.copy(),
detections=detections,
labels=labels
)
```
"""
font = cv2.FONT_HERSHEY_SIMPLEX
+246 -171
View File
@@ -6,13 +6,15 @@ from typing import Any, Dict, Iterator, List, Optional, Tuple, Union
import numpy as np
from supervision.config import CLASS_NAME_DATA_FIELD, ORIENTED_BOX_COORDINATES
from supervision.detection.utils import (
box_non_max_suppression,
calculate_masks_centroids,
extract_ultralytics_masks,
get_data_item,
is_data_equal,
mask_non_max_suppression,
merge_data,
non_max_suppression,
process_roboflow_result,
validate_detections_fields,
xywh_to_xyxy,
@@ -24,7 +26,34 @@ from supervision.utils.internal import deprecated
@dataclass
class Detections:
"""
A dataclass representing detection results.
The `sv.Detections` allows you to convert results from a variety of object detection
and segmentation models into a single, unified format. The `sv.Detections` class
enables easy data manipulation and filtering, and provides a consistent API for
Supervision's tools like trackers, annotators, and zones.
```python
import cv2
import supervision as sv
from ultralytics import YOLO
image = cv2.imread(<SOURCE_IMAGE_PATH>)
model = YOLO('yolov8s.pt')
annotator = sv.BoundingBoxAnnotator()
result = model(image)[0]
detections = sv.Detections.from_ultralytics(result)
annotated_image = annotator.annotate(image, detections)
```
!!! tip
In `sv.Detections`, detection data is categorized into two main field types:
fixed and custom. The fixed fields include `xyxy`, `mask`, `confidence`,
`class_id`, and `tracker_id`. For any additional data requirements, custom
fields come into play, stored in the data field. These custom fields are easily
accessible using the `detections[<FIELD_NAME>]` syntax, providing flexibility
for diverse data handling needs.
Attributes:
xyxy (np.ndarray): An array of shape `(n, 4)` containing
@@ -126,14 +155,14 @@ class Detections:
Example:
```python
>>> import cv2
>>> import torch
>>> import supervision as sv
import cv2
import torch
import supervision as sv
>>> image = cv2.imread(SOURCE_IMAGE_PATH)
>>> model = torch.hub.load('ultralytics/yolov5', 'yolov5s')
>>> result = model(image)
>>> detections = sv.Detections.from_yolov5(result)
image = cv2.imread(<SOURCE_IMAGE_PATH>)
model = torch.hub.load('ultralytics/yolov5', 'yolov5s')
result = model(image)
detections = sv.Detections.from_yolov5(result)
```
"""
yolov5_detections_predictions = yolov5_results.pred[0].cpu().cpu().numpy()
@@ -150,6 +179,13 @@ class Detections:
Creates a Detections instance from a
[YOLOv8](https://github.com/ultralytics/ultralytics) inference result.
!!! Note
`from_ultralytics` is compatible with
[detection](https://docs.ultralytics.com/tasks/detect/),
[segmentation](https://docs.ultralytics.com/tasks/segment/), and
[OBB](https://docs.ultralytics.com/tasks/obb/) models.
Args:
ultralytics_results (ultralytics.yolo.engine.results.Results):
The output Results instance from YOLOv8
@@ -159,25 +195,46 @@ class Detections:
Example:
```python
>>> import cv2
>>> import supervision as sv
>>> from ultralytics import YOLO
import cv2
import supervision as sv
from ultralytics import YOLO
>>> image = cv2.imread(...)
>>> model = YOLO('yolov8s.pt')
>>> result = model(image)[0]
>>> detections = sv.Detections.from_ultralytics(result)
image = cv2.imread(<SOURCE_IMAGE_PATH>)
model = YOLO('yolov8s.pt')
result = model(image)[0]
detections = sv.Detections.from_ultralytics(result)
```
"""
""" # noqa: E501 // docs
if ultralytics_results.obb is not None:
class_id = ultralytics_results.obb.cls.cpu().numpy().astype(int)
class_names = np.array([ultralytics_results.names[i] for i in class_id])
oriented_box_coordinates = ultralytics_results.obb.xyxyxyxy.cpu().numpy()
return cls(
xyxy=ultralytics_results.obb.xyxy.cpu().numpy(),
confidence=ultralytics_results.obb.conf.cpu().numpy(),
class_id=class_id,
tracker_id=ultralytics_results.obb.id.int().cpu().numpy()
if ultralytics_results.obb.id is not None
else None,
data={
ORIENTED_BOX_COORDINATES: oriented_box_coordinates,
CLASS_NAME_DATA_FIELD: class_names,
},
)
class_id = ultralytics_results.boxes.cls.cpu().numpy().astype(int)
class_names = np.array([ultralytics_results.names[i] for i in class_id])
return cls(
xyxy=ultralytics_results.boxes.xyxy.cpu().numpy(),
confidence=ultralytics_results.boxes.conf.cpu().numpy(),
class_id=ultralytics_results.boxes.cls.cpu().numpy().astype(int),
class_id=class_id,
mask=extract_ultralytics_masks(ultralytics_results),
tracker_id=ultralytics_results.boxes.id.int().cpu().numpy()
if ultralytics_results.boxes.id is not None
else None,
data={CLASS_NAME_DATA_FIELD: class_names},
)
@classmethod
@@ -198,14 +255,15 @@ class Detections:
Example:
```python
>>> import cv2
>>> from super_gradients.training import models
>>> import supervision as sv
import cv2
from super_gradients.training import models
import supervision as sv
>>> image = cv2.imread(SOURCE_IMAGE_PATH)
>>> model = models.get('yolo_nas_l', pretrained_weights="coco")
>>> result = list(model.predict(image, conf=0.35))[0]
>>> detections = sv.Detections.from_yolo_nas(result)
image = cv2.imread(<SOURCE_IMAGE_PATH>)
model = models.get('yolo_nas_l', pretrained_weights="coco")
result = list(model.predict(image, conf=0.35))[0]
detections = sv.Detections.from_yolo_nas(result)
```
"""
if np.asarray(yolo_nas_results.prediction.bboxes_xyxy).shape[0] == 0:
@@ -235,20 +293,16 @@ class Detections:
Example:
```python
>>> import tensorflow as tf
>>> import tensorflow_hub as hub
>>> import numpy as np
>>> import cv2
import tensorflow as tf
import tensorflow_hub as hub
import numpy as np
import cv2
>>> module_handle = "https://tfhub.dev/tensorflow/centernet/hourglass_512x512_kpts/1"
>>> model = hub.load(module_handle)
>>> img = np.array(cv2.imread(SOURCE_IMAGE_PATH))
>>> result = model(img)
>>> detections = sv.Detections.from_tensorflow(result)
module_handle = "https://tfhub.dev/tensorflow/centernet/hourglass_512x512_kpts/1"
model = hub.load(module_handle)
img = np.array(cv2.imread(SOURCE_IMAGE_PATH))
result = model(img)
detections = sv.Detections.from_tensorflow(result)
```
""" # noqa: E501 // docs
@@ -278,15 +332,15 @@ class Detections:
Example:
```python
>>> import supervision as sv
>>> from deepsparse import Pipeline
import supervision as sv
from deepsparse import Pipeline
>>> yolo_pipeline = Pipeline.create(
... task="yolo",
... model_path = "zoo:cv/detection/yolov5-l/pytorch/ultralytics/coco/pruned80_quant-none"
... )
>>> result = yolo_pipeline(<SOURCE IMAGE PATH>)
>>> detections = sv.Detections.from_deepsparse(result)
yolo_pipeline = Pipeline.create(
task="yolo",
model_path = "zoo:cv/detection/yolov5-l/pytorch/ultralytics/coco/pruned80_quant-none"
)
result = yolo_pipeline(<SOURCE IMAGE PATH>)
detections = sv.Detections.from_deepsparse(result)
```
""" # noqa: E501 // docs
@@ -302,9 +356,9 @@ class Detections:
@classmethod
def from_mmdetection(cls, mmdet_results) -> Detections:
"""
Creates a Detections instance from
a [mmdetection](https://github.com/open-mmlab/mmdetection) inference result.
Also supported for [mmyolo](https://github.com/open-mmlab/mmyolo)
Creates a Detections instance from a
[mmdetection](https://github.com/open-mmlab/mmdetection) and
[mmyolo](https://github.com/open-mmlab/mmyolo) inference result.
Args:
mmdet_results (mmdet.structures.DetDataSample):
@@ -315,16 +369,17 @@ class Detections:
Example:
```python
>>> import cv2
>>> import supervision as sv
>>> from mmdet.apis import DetInferencer
import cv2
import supervision as sv
from mmdet.apis import init_detector, inference_detector
>>> inferencer = DetInferencer(model_name, checkpoint, device)
>>> mmdet_result = inferencer(SOURCE_IMAGE_PATH, out_dir='./output',
... return_datasamples=True)["predictions"][0]
>>> detections = sv.Detections.from_mmdetection(mmdet_result)
image = cv2.imread(<SOURCE_IMAGE_PATH>)
model = init_detector(<CONFIG_PATH>, <WEIGHTS_PATH>, device=<DEVICE>)
result = inference_detector(model, image)
detections = sv.Detections.from_mmdetection(result)
```
"""
""" # noqa: E501 // docs
return cls(
xyxy=mmdet_results.pred_instances.bboxes.cpu().numpy(),
@@ -364,18 +419,20 @@ class Detections:
Example:
```python
>>> import cv2
>>> from detectron2.engine import DefaultPredictor
>>> from detectron2.config import get_cfg
>>> import supervision as sv
import cv2
import supervision as sv
from detectron2.engine import DefaultPredictor
from detectron2.config import get_cfg
>>> image = cv2.imread(SOURCE_IMAGE_PATH)
>>> cfg = get_cfg()
>>> cfg.merge_from_file("path/to/config.yaml")
>>> cfg.MODEL.WEIGHTS = "path/to/model_weights.pth"
>>> predictor = DefaultPredictor(cfg)
>>> result = predictor(image)
>>> detections = sv.Detections.from_detectron2(result)
image = cv2.imread(<SOURCE_IMAGE_PATH>)
cfg = get_cfg()
cfg.merge_from_file(<CONFIG_PATH>)
cfg.MODEL.WEIGHTS = <WEIGHTS_PATH>
predictor = DefaultPredictor(cfg)
result = predictor(image)
detections = sv.Detections.from_detectron2(result)
```
"""
@@ -412,14 +469,15 @@ class Detections:
Example:
```python
>>> import cv2
>>> import supervision as sv
>>> from inference.models.utils import get_roboflow_model
import cv2
import supervision as sv
from inference.models.utils import get_roboflow_model
>>> image = cv2.imread(...)
>>> model = get_roboflow_model(model_id="yolov8s-640")
>>> result = model.infer(image)[0]
>>> detections = sv.Detections.from_inference(result)
image = cv2.imread(<SOURCE_IMAGE_PATH>)
model = get_roboflow_model(model_id="yolov8s-640")
result = model.infer(image)[0]
detections = sv.Detections.from_inference(result)
```
"""
with suppress(AttributeError):
@@ -429,7 +487,9 @@ class Detections:
)
if np.asarray(xyxy).shape[0] == 0:
return cls.empty()
empty_detection = cls.empty()
empty_detection.data = {CLASS_NAME_DATA_FIELD: np.empty(0)}
return empty_detection
return cls(
xyxy=xyxy,
@@ -443,10 +503,15 @@ class Detections:
@classmethod
@deprecated(
"`Detections.from_roboflow` is deprecated and will be removed in "
"`supervision-0.21.0`. Use `Detections.from_inference` instead."
"`supervision-0.22.0`. Use `Detections.from_inference` instead."
)
def from_roboflow(cls, roboflow_result: Union[dict, Any]) -> Detections:
"""
!!! failure "Deprecated"
`Detections.from_roboflow` is deprecated and will be removed in
`supervision-0.22.0`. Use `Detections.from_inference` instead.
Create a Detections object from the [Roboflow](https://roboflow.com/)
API inference result or the [Inference](https://inference.roboflow.com/)
package results.
@@ -461,14 +526,15 @@ class Detections:
Example:
```python
>>> import cv2
>>> import supervision as sv
>>> from inference.models.utils import get_roboflow_model
import cv2
import supervision as sv
from inference.models.utils import get_roboflow_model
>>> image = cv2.imread(...)
>>> model = get_roboflow_model(model_id="yolov8s-640")
>>> result = model.infer(image)[0]
>>> detections = sv.Detections.from_roboflow(result)
image = cv2.imread(<SOURCE_IMAGE_PATH>)
model = get_roboflow_model(model_id="yolov8s-640")
result = model.infer(image)[0]
detections = sv.Detections.from_roboflow(result)
```
"""
return cls.from_inference(roboflow_result)
@@ -488,17 +554,17 @@ class Detections:
Example:
```python
>>> import supervision as sv
>>> from segment_anything import (
... sam_model_registry,
... SamAutomaticMaskGenerator
... )
import supervision as sv
from segment_anything import (
sam_model_registry,
SamAutomaticMaskGenerator
)
>>> sam_model_reg = sam_model_registry[MODEL_TYPE]
>>> sam = sam_model_reg(checkpoint=CHECKPOINT_PATH).to(device=DEVICE)
>>> mask_generator = SamAutomaticMaskGenerator(sam)
>>> sam_result = mask_generator.generate(IMAGE)
>>> detections = sv.Detections.from_sam(sam_result=sam_result)
sam_model_reg = sam_model_registry[MODEL_TYPE]
sam = sam_model_reg(checkpoint=CHECKPOINT_PATH).to(device=DEVICE)
mask_generator = SamAutomaticMaskGenerator(sam)
sam_result = mask_generator.generate(IMAGE)
detections = sv.Detections.from_sam(sam_result=sam_result)
```
"""
@@ -535,25 +601,25 @@ class Detections:
Example:
```python
>>> import requests
>>> import supervision as sv
import requests
import supervision as sv
>>> image = open(input, "rb").read()
image = open(input, "rb").read()
>>> endpoint = "https://.cognitiveservices.azure.com/"
>>> subscription_key = "..."
endpoint = "https://.cognitiveservices.azure.com/"
subscription_key = ""
>>> headers = {
... "Content-Type": "application/octet-stream",
... "Ocp-Apim-Subscription-Key": subscription_key
... }
headers = {
"Content-Type": "application/octet-stream",
"Ocp-Apim-Subscription-Key": subscription_key
}
>>> response = requests.post(endpoint,
... headers=self.headers,
... data=image
... ).json()
response = requests.post(endpoint,
headers=self.headers,
data=image
).json()
>>> detections = sv.Detections.from_azure_analyze_image(response)
detections = sv.Detections.from_azure_analyze_image(response)
```
"""
if "error" in azure_result:
@@ -617,21 +683,21 @@ class Detections:
Example:
```python
>>> import supervision as sv
>>> import paddle
>>> from ppdet.engine import Trainer
>>> from ppdet.core.workspace import load_config
import supervision as sv
import paddle
from ppdet.engine import Trainer
from ppdet.core.workspace import load_config
>>> weights = (...)
>>> config = (...)
weights = ()
config = ()
>>> cfg = load_config(config)
>>> trainer = Trainer(cfg, mode='test')
>>> trainer.load_weights(weights)
cfg = load_config(config)
trainer = Trainer(cfg, mode='test')
trainer.load_weights(weights)
>>> paddledet_result = trainer.predict([images])[0]
paddledet_result = trainer.predict([images])[0]
>>> detections = sv.Detections.from_paddledet(paddledet_result)
detections = sv.Detections.from_paddledet(paddledet_result)
```
"""
@@ -655,9 +721,9 @@ class Detections:
Example:
```python
>>> from supervision import Detections
from supervision import Detections
>>> empty_detections = Detections.empty()
empty_detections = Detections.empty()
```
"""
return cls(
@@ -689,29 +755,29 @@ class Detections:
import numpy as np
import supervision as sv
>>> detections_1 = sv.Detections(
... xyxy=np.array([[15, 15, 100, 100], [200, 200, 300, 300]]),
... class_id=np.array([1, 2]),
... data={'feature_vector': np.array([0.1, 0.2)])}
... )
detections_1 = sv.Detections(
xyxy=np.array([[15, 15, 100, 100], [200, 200, 300, 300]]),
class_id=np.array([1, 2]),
data={'feature_vector': np.array([0.1, 0.2)])}
)
>>> detections_2 = sv.Detections(
... xyxy=np.array([[30, 30, 120, 120]]),
... class_id=np.array([1]),
... data={'feature_vector': [np.array([0.3])]}
... )
detections_2 = sv.Detections(
xyxy=np.array([[30, 30, 120, 120]]),
class_id=np.array([1]),
data={'feature_vector': [np.array([0.3])]}
)
>>> merged_detections = Detections.merge([detections_1, detections_2])
merged_detections = Detections.merge([detections_1, detections_2])
>>> merged_detections.xyxy
merged_detections.xyxy
array([[ 15, 15, 100, 100],
[200, 200, 300, 300],
[ 30, 30, 120, 120]])
>>> merged_detections.class_id
merged_detections.class_id
array([1, 2, 1])
>>> merged_detections.data['feature_vector']
merged_detections.data['feature_vector']
array([0.1, 0.2, 0.3])
```
"""
@@ -844,17 +910,17 @@ class Detections:
Example:
```python
>>> import supervision as sv
import supervision as sv
>>> detections = sv.Detections(...)
detections = sv.Detections()
>>> first_detection = detections[0]
>>> first_10_detections = detections[0:10]
>>> some_detections = detections[[0, 2, 4]]
>>> class_0_detections = detections[detections.class_id == 0]
>>> high_confidence_detections = detections[detections.confidence > 0.5]
first_detection = detections[0]
first_10_detections = detections[0:10]
some_detections = detections[[0, 2, 4]]
class_0_detections = detections[detections.class_id == 0]
high_confidence_detections = detections[detections.confidence > 0.5]
>>> feature_vector = detections['feature_vector']
feature_vector = detections['feature_vector']
```
"""
if isinstance(index, str):
@@ -880,22 +946,21 @@ class Detections:
Example:
```python
>>> import cv2
>>> from ultralytics import YOLO
>>> import supervision as sv
import cv2
import supervision as sv
from ultralytics import YOLO
>>> model = YOLO('yolov8s.pt')
image = cv2.imread(<SOURCE_IMAGE_PATH>)
model = YOLO('yolov8s.pt')
>>> image = cv2.imread(SOURCE_IMAGE_PATH)
result = model(image)[0]
detections = sv.Detections.from_ultralytics(result)
>>> result = model(image)[0]
>>> detections = sv.Detections.from_ultralytics(result)
>>> detections['names'] = [
... model.model.names[class_id]
... for class_id
... in detections.class_id
... ]
detections['names'] = [
model.model.names[class_id]
for class_id
in detections.class_id
]
```
"""
if not isinstance(value, (np.ndarray, list)):
@@ -915,7 +980,7 @@ class Detections:
Returns:
np.ndarray: An array of floats containing the area of each detection
in the format of `(area_1, area_2, ..., area_n)`,
in the format of `(area_1, area_2, , area_n)`,
where n is the number of detections.
"""
if self.mask is not None:
@@ -930,7 +995,7 @@ class Detections:
Returns:
np.ndarray: An array of floats containing the area of each bounding
box in the format of `(area_1, area_2, ..., area_n)`,
box in the format of `(area_1, area_2, , area_n)`,
where n is the number of detections.
"""
return (self.xyxy[:, 3] - self.xyxy[:, 1]) * (self.xyxy[:, 2] - self.xyxy[:, 0])
@@ -939,11 +1004,13 @@ class Detections:
self, threshold: float = 0.5, class_agnostic: bool = False
) -> Detections:
"""
Perform non-maximum suppression on the current set of object detections.
Performs non-max suppression on detection set. If the detections result
from a segmentation model, the IoU mask is applied. Otherwise, box IoU is used.
Args:
threshold (float, optional): The intersection-over-union threshold
to use for non-maximum suppression. Defaults to 0.5.
to use for non-maximum suppression. I'm the lower the value the more
restrictive the NMS becomes. Defaults to 0.5.
class_agnostic (bool, optional): Whether to perform class-agnostic
non-maximum suppression. If True, the class_id of each detection
will be ignored. Defaults to False.
@@ -965,18 +1032,26 @@ class Detections:
if class_agnostic:
predictions = np.hstack((self.xyxy, self.confidence.reshape(-1, 1)))
indices = non_max_suppression(
else:
assert self.class_id is not None, (
"Detections class_id must be given for NMS to be executed. If you"
" intended to perform class agnostic NMS set class_agnostic=True."
)
predictions = np.hstack(
(
self.xyxy,
self.confidence.reshape(-1, 1),
self.class_id.reshape(-1, 1),
)
)
if self.mask is not None:
indices = mask_non_max_suppression(
predictions=predictions, masks=self.mask, iou_threshold=threshold
)
else:
indices = box_non_max_suppression(
predictions=predictions, iou_threshold=threshold
)
return self[indices]
assert self.class_id is not None, (
"Detections class_id must be given for NMS to be executed. If you intended"
" to perform class agnostic NMS set class_agnostic=True."
)
predictions = np.hstack(
(self.xyxy, self.confidence.reshape(-1, 1), self.class_id.reshape(-1, 1))
)
indices = non_max_suppression(predictions=predictions, iou_threshold=threshold)
return self[indices]
@@ -5,7 +5,8 @@ import numpy as np
from supervision.detection.core import Detections
from supervision.draw.color import Color
from supervision.geometry.core import Point, Position, Rect, Vector
from supervision.draw.utils import draw_text
from supervision.geometry.core import Point, Position, Vector
class LineZone:
@@ -13,10 +14,16 @@ class LineZone:
This class is responsible for counting the number of objects that cross a
predefined line.
<video controls>
<source
src="https://media.roboflow.com/supervision/cookbooks/count-objects-crossing-the-line-result-1280x720.mp4"
type="video/mp4">
</video>
!!! warning
LineZone utilizes the `tracker_id`. Read
[here](https://supervision.roboflow.com/trackers/) to learn how to plug
LineZone uses the `tracker_id`. Read
[here](/latest/trackers/) to learn how to plug
tracking into your inference pipeline.
Attributes:
@@ -24,7 +31,28 @@ class LineZone:
to inside.
out_count (int): The number of objects that have crossed the line from inside
to outside.
"""
Example:
```python
import supervision as sv
from ultralytics import YOLO
model = YOLO(<SOURCE_MODEL_PATH>)
tracker = sv.ByteTrack()
frames_generator = sv.get_video_frames_generator(<SOURCE_VIDEO_PATH>)
start, end = sv.Point(x=0, y=1080), sv.Point(x=3840, y=1080)
line_zone = sv.LineZone(start=start, end=end)
for frame in frames_generator:
result = model(frame)[0]
detections = sv.Detections.from_ultralytics(result)
detections = tracker.update_with_detections(detections)
crossed_in, crossed_out = line_zone.trigger(detections)
line_zone.in_count, line_zone.out_count
# 7, 2
```
""" # noqa: E501 // docs
def __init__(
self,
@@ -136,7 +164,7 @@ class LineZone:
continue
triggers = [
self.vector.cross_product(point=anchor) > 0 for anchor in box_anchors
self.vector.cross_product(point=anchor) < 0 for anchor in box_anchors
]
if len(set(triggers)) == 2:
@@ -174,6 +202,8 @@ class LineZoneAnnotator:
text_padding: int = 10,
custom_in_text: Optional[str] = None,
custom_out_text: Optional[str] = None,
display_in_count: bool = True,
display_out_count: bool = True,
):
"""
Initialize the LineCounterAnnotator object with default values.
@@ -186,6 +216,8 @@ class LineZoneAnnotator:
text_scale (float): The scale of the text that will be drawn.
text_offset (float): The offset of the text that will be drawn.
text_padding (int): The padding of the text that will be drawn.
display_in_count (bool): Whether to display the in count or not.
display_out_count (bool): Whether to display the out count or not.
"""
self.thickness: float = thickness
@@ -197,6 +229,43 @@ class LineZoneAnnotator:
self.text_padding: int = text_padding
self.custom_in_text: str = custom_in_text
self.custom_out_text: str = custom_out_text
self.display_in_count: bool = display_in_count
self.display_out_count: bool = display_out_count
def _annotate_count(
self,
frame: np.ndarray,
center_text_anchor: Point,
text: str,
is_in_count: bool,
) -> None:
"""This method is drawing the text on the frame.
Args:
frame (np.ndarray): The image on which the text will be drawn.
center_text_anchor: The center point that the text will be drawn.
text (str): The text that will be drawn.
is_in_count (bool): Whether to display the in count or out count.
"""
_, text_height = cv2.getTextSize(
text, cv2.FONT_HERSHEY_SIMPLEX, self.text_scale, self.text_thickness
)[0]
if is_in_count:
center_text_anchor.y -= int(self.text_offset * text_height)
else:
center_text_anchor.y += int(self.text_offset * text_height)
draw_text(
scene=frame,
text=text,
text_anchor=center_text_anchor,
text_color=self.text_color,
text_scale=self.text_scale,
text_thickness=self.text_thickness,
text_padding=self.text_padding,
background_color=self.color,
)
def annotate(self, frame: np.ndarray, line_counter: LineZone) -> np.ndarray:
"""
@@ -237,90 +306,33 @@ class LineZoneAnnotator:
lineType=cv2.LINE_AA,
)
in_text = (
f"{self.custom_in_text}: {line_counter.in_count}"
if self.custom_in_text is not None
else f"in: {line_counter.in_count}"
)
out_text = (
f"{self.custom_out_text}: {line_counter.out_count}"
if self.custom_out_text is not None
else f"out: {line_counter.out_count}"
text_anchor = Vector(
start=line_counter.vector.start, end=line_counter.vector.end
)
(in_text_width, in_text_height), _ = cv2.getTextSize(
in_text, cv2.FONT_HERSHEY_SIMPLEX, self.text_scale, self.text_thickness
)
(out_text_width, out_text_height), _ = cv2.getTextSize(
out_text, cv2.FONT_HERSHEY_SIMPLEX, self.text_scale, self.text_thickness
)
if self.display_in_count:
in_text = (
f"{self.custom_in_text}: {line_counter.in_count}"
if self.custom_in_text is not None
else f"in: {line_counter.in_count}"
)
self._annotate_count(
frame=frame,
center_text_anchor=text_anchor.center,
text=in_text,
is_in_count=True,
)
in_text_x = int(
(line_counter.vector.end.x + line_counter.vector.start.x - in_text_width)
/ 2
)
in_text_y = int(
(line_counter.vector.end.y + line_counter.vector.start.y + in_text_height)
/ 2
- self.text_offset * in_text_height
)
out_text_x = int(
(line_counter.vector.end.x + line_counter.vector.start.x - out_text_width)
/ 2
)
out_text_y = int(
(line_counter.vector.end.y + line_counter.vector.start.y + out_text_height)
/ 2
+ self.text_offset * out_text_height
)
in_text_background_rect = Rect(
x=in_text_x,
y=in_text_y - in_text_height,
width=in_text_width,
height=in_text_height,
).pad(padding=self.text_padding)
out_text_background_rect = Rect(
x=out_text_x,
y=out_text_y - out_text_height,
width=out_text_width,
height=out_text_height,
).pad(padding=self.text_padding)
cv2.rectangle(
frame,
in_text_background_rect.top_left.as_xy_int_tuple(),
in_text_background_rect.bottom_right.as_xy_int_tuple(),
self.color.as_bgr(),
-1,
)
cv2.rectangle(
frame,
out_text_background_rect.top_left.as_xy_int_tuple(),
out_text_background_rect.bottom_right.as_xy_int_tuple(),
self.color.as_bgr(),
-1,
)
cv2.putText(
frame,
in_text,
(in_text_x, in_text_y),
cv2.FONT_HERSHEY_SIMPLEX,
self.text_scale,
self.text_color.as_bgr(),
self.text_thickness,
cv2.LINE_AA,
)
cv2.putText(
frame,
out_text,
(out_text_x, out_text_y),
cv2.FONT_HERSHEY_SIMPLEX,
self.text_scale,
self.text_color.as_bgr(),
self.text_thickness,
cv2.LINE_AA,
)
if self.display_out_count:
out_text = (
f"{self.custom_out_text}: {line_counter.out_count}"
if self.custom_out_text is not None
else f"out: {line_counter.out_count}"
)
self._annotate_count(
frame=frame,
center_text_anchor=text_anchor.center,
text=out_text,
is_in_count=False,
)
return frame
+181
View File
@@ -0,0 +1,181 @@
from __future__ import annotations
import csv
import os
from typing import Any, Dict, List, Optional
from supervision.detection.core import Detections
BASE_HEADER = [
"x_min",
"y_min",
"x_max",
"y_max",
"class_id",
"confidence",
"tracker_id",
]
class CSVSink:
"""
A utility class for saving detection data to a CSV file. This class is designed to
efficiently serialize detection objects into a CSV format, allowing for the
inclusion of bounding box coordinates and additional attributes like `confidence`,
`class_id`, and `tracker_id`.
!!! tip
CSVSink allow to pass custom data alongside the detection fields, providing
flexibility for logging various types of information.
Args:
file_name (str): The name of the CSV file where the detections will be stored.
Defaults to 'output.csv'.
Example:
```python
import supervision as sv
from ultralytics import YOLO
model = YOLO(<SOURCE_MODEL_PATH>)
csv_sink = sv.CSVSink(<RESULT_CSV_FILE_PATH>)
frames_generator = sv.get_video_frames_generator(<SOURCE_VIDEO_PATH>)
with csv_sink as sink:
for frame in frames_generator:
result = model(frame)[0]
detections = sv.Detections.from_ultralytics(result)
sink.append(detections, custom_data={'<CUSTOM_LABEL>':'<CUSTOM_DATA>'})
```
""" # noqa: E501 // docs
def __init__(self, file_name: str = "output.csv") -> None:
"""
Initialize the CSVSink instance.
Args:
file_name (str): The name of the CSV file.
Returns:
None
"""
self.file_name = file_name
self.file: Optional[open] = None
self.writer: Optional[csv.writer] = None
self.header_written = False
self.field_names = []
def __enter__(self) -> CSVSink:
self.open()
return self
def __exit__(
self,
exc_type: Optional[type],
exc_val: Optional[Exception],
exc_tb: Optional[Any],
) -> None:
self.close()
def open(self) -> None:
"""
Open the CSV file for writing.
Returns:
None
"""
parent_directory = os.path.dirname(self.file_name)
if parent_directory and not os.path.exists(parent_directory):
os.makedirs(parent_directory)
self.file = open(self.file_name, "w", newline="")
self.writer = csv.writer(self.file)
def close(self) -> None:
"""
Close the CSV file.
Returns:
None
"""
if self.file:
self.file.close()
@staticmethod
def parse_detection_data(
detections: Detections, custom_data: Dict[str, Any] = None
) -> List[Dict[str, Any]]:
parsed_rows = []
for i in range(len(detections.xyxy)):
row = {
"x_min": detections.xyxy[i][0],
"y_min": detections.xyxy[i][1],
"x_max": detections.xyxy[i][2],
"y_max": detections.xyxy[i][3],
"class_id": ""
if detections.class_id is None
else str(detections.class_id[i]),
"confidence": ""
if detections.confidence is None
else str(detections.confidence[i]),
"tracker_id": ""
if detections.tracker_id is None
else str(detections.tracker_id[i]),
}
if hasattr(detections, "data"):
for key, value in detections.data.items():
if value.ndim == 0:
row[key] = value
else:
row[key] = value[i]
if custom_data:
row.update(custom_data)
parsed_rows.append(row)
return parsed_rows
def append(
self, detections: Detections, custom_data: Dict[str, Any] = None
) -> None:
"""
Append detection data to the CSV file.
Args:
detections (Detections): The detection data.
custom_data (Dict[str, Any]): Custom data to include.
Returns:
None
"""
if not self.writer:
raise Exception(
f"Cannot append to CSV: The file '{self.file_name}' is not open."
)
field_names = CSVSink.parse_field_names(detections, custom_data)
if not self.header_written:
self.field_names = field_names
self.writer.writerow(field_names)
self.header_written = True
if field_names != self.field_names:
print(
f"Field names do not match the header. "
f"Expected: {self.field_names}, given: {field_names}"
)
parsed_rows = CSVSink.parse_detection_data(detections, custom_data)
for row in parsed_rows:
self.writer.writerow(
[row.get(field_name, "") for field_name in self.field_names]
)
@staticmethod
def parse_field_names(
detections: Detections, custom_data: Dict[str, Any]
) -> List[str]:
dynamic_header = sorted(
set(custom_data.keys()) | set(getattr(detections, "data", {}).keys())
)
return BASE_HEADER + dynamic_header
+10 -10
View File
@@ -77,20 +77,20 @@ class InferenceSlicer:
Example:
```python
>>> import cv2
>>> import supervision as sv
>>> from ultralytics import YOLO
import cv2
import supervision as sv
from ultralytics import YOLO
>>> image = cv2.imread(SOURCE_IMAGE_PATH)
>>> model = YOLO(...)
image = cv2.imread(SOURCE_IMAGE_PATH)
model = YOLO(...)
>>> def callback(image_slice: np.ndarray) -> sv.Detections:
... result = model(image_slice)[0]
... return sv.Detections.from_ultralytics(result)
def callback(image_slice: np.ndarray) -> sv.Detections:
result = model(image_slice)[0]
return sv.Detections.from_ultralytics(result)
>>> slicer = sv.InferenceSlicer(callback = callback)
slicer = sv.InferenceSlicer(callback = callback)
>>> detections = slicer(image)
detections = slicer(image)
```
"""
detections_list = []
+142
View File
@@ -0,0 +1,142 @@
from __future__ import annotations
import json
import os
from typing import Any, Dict, List, Optional
from supervision.detection.core import Detections
class JSONSink:
"""
A utility class for saving detection data to a JSON file. This class is designed to
efficiently serialize detection objects into a JSON format, allowing for the
inclusion of bounding box coordinates and additional attributes like `confidence`,
`class_id`, and `tracker_id`.
!!! tip
JSONsink allow to pass custom data alongside the detection fields, providing
flexibility for logging various types of information.
Args:
file_name (str): The name of the JSON file where the detections will be stored.
Defaults to 'output.json'.
Example:
```python
import supervision as sv
from ultralytics import YOLO
model = YOLO(<SOURCE_MODEL_PATH>)
json_sink = sv.JSONSink(<RESULT_JSON_FILE_PATH>)
frames_generator = sv.get_video_frames_generator(<SOURCE_VIDEO_PATH>)
with json_sink as sink:
for frame in frames_generator:
result = model(frame)[0]
detections = sv.Detections.from_ultralytics(result)
sink.append(detections, custom_data={'<CUSTOM_LABEL>':'<CUSTOM_DATA>'})
```
""" # noqa: E501 // docs
def __init__(self, file_name: str = "output.json") -> None:
"""
Initialize the JSONSink instance.
Args:
file_name (str): The name of the JSON file.
Returns:
None
"""
self.file_name = file_name
self.file: Optional[open] = None
self.data: List[Dict[str, Any]] = []
def __enter__(self) -> JSONSink:
self.open()
return self
def __exit__(
self,
exc_type: Optional[type],
exc_val: Optional[Exception],
exc_tb: Optional[Any],
) -> None:
self.write_and_close()
def open(self) -> None:
"""
Open the JSON file for writing.
Returns:
None
"""
parent_directory = os.path.dirname(self.file_name)
if parent_directory and not os.path.exists(parent_directory):
os.makedirs(parent_directory)
self.file = open(self.file_name, "w")
def write_and_close(self) -> None:
"""
Write and close the JSON file.
Returns:
None
"""
if self.file:
json.dump(self.data, self.file, indent=4)
self.file.close()
@staticmethod
def parse_detection_data(
detections: Detections, custom_data: Dict[str, Any] = None
) -> List[Dict[str, Any]]:
parsed_rows = []
for i in range(len(detections.xyxy)):
row = {
"x_min": float(detections.xyxy[i][0]),
"y_min": float(detections.xyxy[i][1]),
"x_max": float(detections.xyxy[i][2]),
"y_max": float(detections.xyxy[i][3]),
"class_id": ""
if detections.class_id is None
else int(detections.class_id[i]),
"confidence": ""
if detections.confidence is None
else float(detections.confidence[i]),
"tracker_id": ""
if detections.tracker_id is None
else int(detections.tracker_id[i]),
}
if hasattr(detections, "data"):
for key, value in detections.data.items():
row[key] = (
str(value[i])
if hasattr(value, "__getitem__") and value.ndim != 0
else str(value)
)
if custom_data:
row.update(custom_data)
parsed_rows.append(row)
return parsed_rows
def append(
self, detections: Detections, custom_data: Dict[str, Any] = None
) -> None:
"""
Append detection data to the JSON file.
Args:
detections (Detections): The detection data.
custom_data (Dict[str, Any]): Custom data to include.
Returns:
None
"""
parsed_rows = JSONSink.parse_detection_data(detections, custom_data)
self.data.extend(parsed_rows)
+46 -20
View File
@@ -1,5 +1,5 @@
from dataclasses import replace
from typing import Optional, Tuple
from typing import Iterable, Optional, Tuple
import cv2
import numpy as np
@@ -10,6 +10,7 @@ from supervision.draw.color import Color
from supervision.draw.utils import draw_polygon, draw_text
from supervision.geometry.core import Position
from supervision.geometry.utils import get_polygon_center
from supervision.utils.internal import deprecated_parameter
class PolygonZone:
@@ -20,21 +21,32 @@ class PolygonZone:
polygon (np.ndarray): A polygon represented by a numpy array of shape
`(N, 2)`, containing the `x`, `y` coordinates of the points.
frame_resolution_wh (Tuple[int, int]): The frame resolution (width, height)
triggering_position (Position): The position within the bounding
box that triggers the zone (default: Position.BOTTOM_CENTER)
triggering_anchors (Iterable[sv.Position]): A list of positions specifying
which anchors of the detections bounding box to consider when deciding on
whether the detection fits within the PolygonZone
(default: (sv.Position.BOTTOM_CENTER,)).
current_count (int): The current count of detected objects within the zone
mask (np.ndarray): The 2D bool mask for the polygon zone
"""
@deprecated_parameter(
old_parameter="triggering_position",
new_parameter="triggering_anchors",
map_function=lambda x: [x],
warning_message="`{old_parameter}` in `{function_name}` is deprecated and will "
"be remove in `supervision-0.23.0`. Use '{new_parameter}' "
"instead.",
)
def __init__(
self,
polygon: np.ndarray,
frame_resolution_wh: Tuple[int, int],
triggering_position: Position = Position.BOTTOM_CENTER,
triggering_anchors: Iterable[Position] = (Position.BOTTOM_CENTER,),
):
self.polygon = polygon.astype(int)
self.frame_resolution_wh = frame_resolution_wh
self.triggering_position = triggering_position
self.triggering_anchors = triggering_anchors
self.current_count = 0
width, height = frame_resolution_wh
@@ -59,10 +71,20 @@ class PolygonZone:
xyxy=detections.xyxy, resolution_wh=self.frame_resolution_wh
)
clipped_detections = replace(detections, xyxy=clipped_xyxy)
clipped_anchors = np.ceil(
clipped_detections.get_anchors_coordinates(anchor=self.triggering_position)
).astype(int)
is_in_zone = self.mask[clipped_anchors[:, 1], clipped_anchors[:, 0]]
all_clipped_anchors = np.array(
[
np.ceil(clipped_detections.get_anchors_coordinates(anchor)).astype(int)
for anchor in self.triggering_anchors
]
)
is_in_zone = (
self.mask[all_clipped_anchors[:, :, 1], all_clipped_anchors[:, :, 0]]
.transpose()
.astype(bool)
)
is_in_zone = np.all(is_in_zone, axis=1)
self.current_count = int(np.sum(is_in_zone))
return is_in_zone.astype(bool)
@@ -83,6 +105,7 @@ class PolygonZoneAnnotator:
font (int): The font type for the text on the polygon,
default is cv2.FONT_HERSHEY_SIMPLEX
center (Tuple[int, int]): The center of the polygon for text placement
display_in_zone_count (bool): Show the label of the zone or not. Default is True
"""
def __init__(
@@ -94,6 +117,7 @@ class PolygonZoneAnnotator:
text_scale: float = 0.5,
text_thickness: int = 1,
text_padding: int = 10,
display_in_zone_count: bool = True,
):
self.zone = zone
self.color = color
@@ -104,6 +128,7 @@ class PolygonZoneAnnotator:
self.text_padding = text_padding
self.font = cv2.FONT_HERSHEY_SIMPLEX
self.center = get_polygon_center(polygon=zone.polygon)
self.display_in_zone_count = display_in_zone_count
def annotate(self, scene: np.ndarray, label: Optional[str] = None) -> np.ndarray:
"""
@@ -124,16 +149,17 @@ class PolygonZoneAnnotator:
thickness=self.thickness,
)
annotated_frame = draw_text(
scene=annotated_frame,
text=str(self.zone.current_count) if label is None else label,
text_anchor=self.center,
background_color=self.color,
text_color=self.text_color,
text_scale=self.text_scale,
text_thickness=self.text_thickness,
text_padding=self.text_padding,
text_font=self.font,
)
if self.display_in_zone_count:
annotated_frame = draw_text(
scene=annotated_frame,
text=str(self.zone.current_count) if label is None else label,
text_anchor=self.center,
background_color=self.color,
text_color=self.text_color,
text_scale=self.text_scale,
text_thickness=self.text_thickness,
text_padding=self.text_padding,
text_font=self.font,
)
return annotated_frame
+122
View File
@@ -0,0 +1,122 @@
from collections import defaultdict, deque
from copy import deepcopy
from typing import Optional
import numpy as np
from supervision.detection.core import Detections
class DetectionsSmoother:
"""
A utility class for smoothing detections over multiple frames in video tracking.
It maintains a history of detections for each track and provides smoothed
predictions based on these histories.
<video controls>
<source
src="https://media.roboflow.com/supervision-detection-smoothing.mp4"
type="video/mp4">
</video>
!!! warning
- `DetectionsSmoother` requires the `tracker_id` for each detection. Refer to
[Roboflow Trackers](/latest/trackers/) for
information on integrating tracking into your inference pipeline.
- This class is not compatible with segmentation models.
Example:
```python
import supervision as sv
from ultralytics import YOLO
video_info = sv.VideoInfo.from_video_path(video_path=<SOURCE_FILE_PATH>)
frame_generator = sv.get_video_frames_generator(source_path=<SOURCE_FILE_PATH>)
model = YOLO(<MODEL_PATH>)
tracker = sv.ByteTrack(frame_rate=video_info.fps)
smoother = sv.DetectionsSmoother()
annotator = sv.BoundingBoxAnnotator()
with sv.VideoSink(<TARGET_FILE_PATH>, video_info=video_info) as sink:
for frame in frame_generator:
result = model(frame)[0]
detections = sv.Detections.from_ultralytics(result)
detections = tracker.update_with_detections(detections)
detections = smoother.update_with_detections(detections)
annotated_frame = bounding_box_annotator.annotate(frame.copy(), detections)
sink.write_frame(annotated_frame)
```
""" # noqa: E501 // docs
def __init__(self, length: int = 5) -> None:
"""
Args:
length (int): The maximum number of frames to consider for smoothing
detections. Defaults to 5.
"""
self.tracks = defaultdict(lambda: deque(maxlen=length))
def update_with_detections(self, detections: Detections) -> Detections:
"""
Updates the smoother with a new set of detections from a frame.
Args:
detections (Detections): The detections to add to the smoother.
"""
if detections.tracker_id is None:
print(
"Smoothing skipped. DetectionsSmoother requires tracker_id. Refer to "
"https://supervision.roboflow.com/latest/trackers for more information."
)
return detections
for detection_idx in range(len(detections)):
tracker_id = detections.tracker_id[detection_idx]
if tracker_id is None:
continue
self.tracks[tracker_id].append(detections[detection_idx])
for track_id in self.tracks.keys():
if track_id not in detections.tracker_id:
self.tracks[track_id].append(None)
for track_id in list(self.tracks.keys()):
if all([d is None for d in self.tracks[track_id]]):
del self.tracks[track_id]
return self.get_smoothed_detections()
def get_track(self, track_id: int) -> Optional[Detections]:
track = self.tracks.get(track_id, None)
if track is None:
return None
track = [d for d in track if d is not None]
if len(track) == 0:
return None
ret = deepcopy(track[0])
ret.xyxy = np.mean([d.xyxy for d in track], axis=0)
ret.confidence = np.mean([d.confidence for d in track], axis=0)
return ret
def get_smoothed_detections(self) -> Detections:
tracked_detections = []
for track_id in self.tracks:
track = self.get_track(track_id)
if track is not None:
tracked_detections.append(track)
detections = Detections.merge(tracked_detections)
if len(detections) == 0:
detections.tracker_id = np.array([], dtype=int)
return detections
+182 -19
View File
@@ -59,7 +59,168 @@ def box_iou_batch(boxes_true: np.ndarray, boxes_detection: np.ndarray) -> np.nda
return area_inter / (area_true[:, None] + area_detection - area_inter)
def non_max_suppression(
def _mask_iou_batch_split(
masks_true: np.ndarray, masks_detection: np.ndarray
) -> np.ndarray:
"""
Internal function.
Compute Intersection over Union (IoU) of two sets of masks -
`masks_true` and `masks_detection`.
Args:
masks_true (np.ndarray): 3D `np.ndarray` representing ground-truth masks.
masks_detection (np.ndarray): 3D `np.ndarray` representing detection masks.
Returns:
np.ndarray: Pairwise IoU of masks from `masks_true` and `masks_detection`.
"""
intersection_area = np.logical_and(masks_true[:, None], masks_detection).sum(
axis=(2, 3)
)
masks_true_area = masks_true.sum(axis=(1, 2))
masks_detection_area = masks_detection.sum(axis=(1, 2))
union_area = masks_true_area[:, None] + masks_detection_area - intersection_area
return np.divide(
intersection_area,
union_area,
out=np.zeros_like(intersection_area, dtype=float),
where=union_area != 0,
)
def mask_iou_batch(
masks_true: np.ndarray,
masks_detection: np.ndarray,
memory_limit: int = 1024 * 5,
) -> np.ndarray:
"""
Compute Intersection over Union (IoU) of two sets of masks -
`masks_true` and `masks_detection`.
Args:
masks_true (np.ndarray): 3D `np.ndarray` representing ground-truth masks.
masks_detection (np.ndarray): 3D `np.ndarray` representing detection masks.
memory_limit (int, optional): memory limit in MB, default is 1024 * 5 MB (5GB).
Returns:
np.ndarray: Pairwise IoU of masks from `masks_true` and `masks_detection`.
"""
memory = (
masks_true.shape[0]
* masks_true.shape[1]
* masks_true.shape[2]
* masks_detection.shape[0]
/ 1024
/ 1024
)
if memory <= memory_limit:
return _mask_iou_batch_split(masks_true, masks_detection)
ious = []
step = max(
memory_limit
* 1024
* 1024
// (
masks_detection.shape[0]
* masks_detection.shape[1]
* masks_detection.shape[2]
),
1,
)
for i in range(0, masks_true.shape[0], step):
ious.append(_mask_iou_batch_split(masks_true[i : i + step], masks_detection))
return np.vstack(ious)
def resize_masks(masks: np.ndarray, max_dimension: int = 640) -> np.ndarray:
"""
Resize all masks in the array to have a maximum dimension of max_dimension,
maintaining aspect ratio.
Args:
masks (np.ndarray): 3D array of binary masks with shape (N, H, W).
max_dimension (int): The maximum dimension for the resized masks.
Returns:
np.ndarray: Array of resized masks.
"""
max_height = np.max(masks.shape[1])
max_width = np.max(masks.shape[2])
scale = min(max_dimension / max_height, max_dimension / max_width)
new_height = int(scale * max_height)
new_width = int(scale * max_width)
x = np.linspace(0, max_width - 1, new_width).astype(int)
y = np.linspace(0, max_height - 1, new_height).astype(int)
xv, yv = np.meshgrid(x, y)
resized_masks = masks[:, yv, xv]
resized_masks = resized_masks.reshape(masks.shape[0], new_height, new_width)
return resized_masks
def mask_non_max_suppression(
predictions: np.ndarray,
masks: np.ndarray,
iou_threshold: float = 0.5,
mask_dimension: int = 640,
) -> np.ndarray:
"""
Perform Non-Maximum Suppression (NMS) on segmentation predictions.
Args:
predictions (np.ndarray): A 2D array of object detection predictions in
the format of `(x_min, y_min, x_max, y_max, score)`
or `(x_min, y_min, x_max, y_max, score, class)`. Shape: `(N, 5)` or
`(N, 6)`, where N is the number of predictions.
masks (np.ndarray): A 3D array of binary masks corresponding to the predictions.
Shape: `(N, H, W)`, where N is the number of predictions, and H, W are the
dimensions of each mask.
iou_threshold (float, optional): The intersection-over-union threshold
to use for non-maximum suppression.
mask_dimension (int, optional): The dimension to which the masks should be
resized before computing IOU values. Defaults to 640.
Returns:
np.ndarray: A boolean array indicating which predictions to keep after
non-maximum suppression.
Raises:
AssertionError: If `iou_threshold` is not within the closed
range from `0` to `1`.
"""
assert 0 <= iou_threshold <= 1, (
"Value of `iou_threshold` must be in the closed range from 0 to 1, "
f"{iou_threshold} given."
)
rows, columns = predictions.shape
if columns == 5:
predictions = np.c_[predictions, np.zeros(rows)]
sort_index = predictions[:, 4].argsort()[::-1]
predictions = predictions[sort_index]
masks = masks[sort_index]
masks_resized = resize_masks(masks, mask_dimension)
ious = mask_iou_batch(masks_resized, masks_resized)
categories = predictions[:, 5]
keep = np.ones(rows, dtype=bool)
for i in range(rows):
if keep[i]:
condition = (ious[i] > iou_threshold) & (categories[i] == categories)
keep[i + 1 :] = np.where(condition[i + 1 :], False, keep[i + 1 :])
return keep[sort_index.argsort()]
def box_non_max_suppression(
predictions: np.ndarray, iou_threshold: float = 0.5
) -> np.ndarray:
"""
@@ -415,16 +576,17 @@ def move_boxes(xyxy: np.ndarray, offset: np.ndarray) -> np.ndarray:
Example:
```python
>>> import numpy as np
>>> import supervision as sv
import numpy as np
import supervision as sv
>>> boxes = np.array([[10, 10, 20, 20], [30, 30, 40, 40]])
>>> offset = np.array([5, 5])
>>> sv.move_boxes(boxes, offset)
... array([
... [15, 15, 25, 25],
... [35, 35, 45, 45]
... ])
boxes = np.array([[10, 10, 20, 20], [30, 30, 40, 40]])
offset = np.array([5, 5])
moved_box = sv.move_boxes(boxes, offset)
print(moved_box)
# np.array([
# [15, 15, 25, 25],
# [35, 35, 45, 45]
# ])
```
"""
return xyxy + np.hstack([offset, offset])
@@ -446,16 +608,17 @@ def scale_boxes(xyxy: np.ndarray, factor: float) -> np.ndarray:
Example:
```python
>>> import numpy as np
>>> import supervision as sv
import numpy as np
import supervision as sv
>>> boxes = np.array([[10, 10, 20, 20], [30, 30, 40, 40]])
>>> factor = 1.5
>>> sv.scale_boxes(boxes, factor)
... array([
... [ 7.5, 7.5, 22.5, 22.5],
... [27.5, 27.5, 42.5, 42.5]
... ])
boxes = np.array([[10, 10, 20, 20], [30, 30, 40, 40]])
factor = 1.5
scaled_bb = sv.scale_boxes(boxes, factor)
print(scaled_bb)
# np.array([
# [ 7.5, 7.5, 22.5, 22.5],
# [27.5, 27.5, 42.5, 42.5]
# ])
```
"""
centers = (xyxy[:, :2] + xyxy[:, 2:]) / 2
+11 -6
View File
@@ -206,7 +206,7 @@ class Color:
@classmethod
@deprecated(
"`Color.white()` is deprecated and will be removed in "
"`supervision-0.20.0`. Use `Color.WHITE` instead."
"`supervision-0.22.0`. Use `Color.WHITE` instead."
)
def white(cls) -> Color:
return Color.from_hex(color_hex="#ffffff")
@@ -214,7 +214,7 @@ class Color:
@classmethod
@deprecated(
"`Color.black()` is deprecated and will be removed in "
"`supervision-0.20.0`. Use `Color.BLACK` instead."
"`supervision-0.22.0`. Use `Color.BLACK` instead."
)
def black(cls) -> Color:
return Color.from_hex(color_hex="#000000")
@@ -222,7 +222,7 @@ class Color:
@classmethod
@deprecated(
"`Color.red()` is deprecated and will be removed in "
"`supervision-0.20.0`. Use `Color.RED` instead."
"`supervision-0.22.0`. Use `Color.RED` instead."
)
def red(cls) -> Color:
return Color.from_hex(color_hex="#ff0000")
@@ -230,7 +230,7 @@ class Color:
@classmethod
@deprecated(
"`Color.green()` is deprecated and will be removed in "
"`supervision-0.20.0`. Use `Color.GREEN` instead."
"`supervision-0.22.0`. Use `Color.GREEN` instead."
)
def green(cls) -> Color:
return Color.from_hex(color_hex="#00ff00")
@@ -238,7 +238,7 @@ class Color:
@classmethod
@deprecated(
"`Color.blue()` is deprecated and will be removed in "
"`supervision-0.20.0`. Use `Color.BLUE` instead."
"`supervision-0.22.0`. Use `Color.BLUE` instead."
)
def blue(cls) -> Color:
return Color.from_hex(color_hex="#0000ff")
@@ -297,10 +297,15 @@ class ColorPalette:
@classmethod
@deprecated(
"`ColorPalette.default()` is deprecated and will be removed in "
"`supervision-0.20.0`. Use `Color.DEFAULT` instead."
"`supervision-0.22.0`. Use `Color.DEFAULT` instead."
)
def default(cls) -> ColorPalette:
"""
!!! failure "Deprecated"
`ColorPalette.default()` is deprecated and will be removed in
`supervision-0.22.0`. Use `Color.DEFAULT` instead.
Returns a default color palette.
Returns:
+11 -6
View File
@@ -135,9 +135,11 @@ def draw_text(
Examples:
```python
>>> scene = np.zeros((100, 100, 3), dtype=np.uint8)
>>> text_anchor = Point(x=50, y=50)
>>> scene = draw_text(scene=scene, text="Hello, world!",text_anchor=text_anchor)
import numpy as np
scene = np.zeros((100, 100, 3), dtype=np.uint8)
text_anchor = Point(x=50, y=50)
scene = draw_text(scene=scene, text="Hello, world!",text_anchor=text_anchor)
```
"""
text_width, text_height = cv2.getTextSize(
@@ -146,9 +148,12 @@ def draw_text(
fontScale=text_scale,
thickness=text_thickness,
)[0]
text_anchor_x, text_anchor_y = text_anchor.as_xy_int_tuple()
text_rect = Rect(
x=text_anchor.x - text_width // 2,
y=text_anchor.y - text_height // 2,
x=text_anchor_x - text_width // 2,
y=text_anchor_y - text_height // 2,
width=text_width,
height=text_height,
).pad(text_padding)
@@ -161,7 +166,7 @@ def draw_text(
cv2.putText(
img=scene,
text=text,
org=(text_anchor.x - text_width // 2, text_anchor.y + text_height // 2),
org=(text_anchor_x - text_width // 2, text_anchor_y + text_height // 2),
fontFace=text_font,
fontScale=text_scale,
color=text_color.as_bgr(),
+13
View File
@@ -56,6 +56,19 @@ class Vector:
dy = self.end.y - self.start.y
return sqrt(dx**2 + dy**2)
@property
def center(self) -> Point:
"""
Calculate the center point of the vector.
Returns:
Point: The center point of the vector.
"""
return Point(
x=(self.start.x + self.end.x) / 2,
y=(self.start.y + self.end.y) / 2,
)
def cross_product(self, point: Point) -> float:
"""
Calculate the 2D cross product (also known as the vector product or outer
+4 -3
View File
@@ -22,10 +22,11 @@ def get_polygon_center(polygon: np.ndarray) -> Point:
Examples:
```python
>>> from supervision.geometry.utils import get_polygon_center
from supervision.geometry.utils import get_polygon_center
import numpy as np
>>> vertices = np.array([[0, 0], [0, 1], [1, 1], [1, 0]])
>>> get_center(vertices)
vertices = np.array([[0, 0], [0, 1], [1, 1], [1, 0]])
get_center(vertices)
Point(x=0.5, y=0.5)
```
"""
+139 -137
View File
@@ -116,31 +116,31 @@ class ConfusionMatrix:
Example:
```python
>>> import supervision as sv
import supervision as sv
>>> targets = [
... sv.Detections(...),
... sv.Detections(...)
... ]
targets = [
sv.Detections(...),
sv.Detections(...)
]
>>> predictions = [
... sv.Detections(...),
... sv.Detections(...)
... ]
predictions = [
sv.Detections(...),
sv.Detections(...)
]
>>> confusion_matrix = sv.ConfusionMatrix.from_detections(
... predictions=predictions,
... targets=target,
... classes=['person', ...]
... )
confusion_matrix = sv.ConfusionMatrix.from_detections(
predictions=predictions,
targets=target,
classes=['person', ...]
)
>>> confusion_matrix.matrix
array([
[0., 0., 0., 0.],
[0., 1., 0., 1.],
[0., 1., 1., 0.],
[1., 1., 0., 0.]
])
print(confusion_matrix.matrix)
# np.array([
# [0., 0., 0., 0.],
# [0., 1., 0., 1.],
# [0., 1., 1., 0.],
# [1., 1., 0., 0.]
# ])
```
"""
@@ -191,46 +191,47 @@ class ConfusionMatrix:
Example:
```python
>>> import supervision as sv
import supervision as sv
import numpy as np
>>> targets = (
... [
... array(
... [
... [0.0, 0.0, 3.0, 3.0, 1],
... [2.0, 2.0, 5.0, 5.0, 1],
... [6.0, 1.0, 8.0, 3.0, 2],
... ]
... ),
... array([1.0, 1.0, 2.0, 2.0, 2]),
... ]
... )
targets = (
[
np.array(
[
[0.0, 0.0, 3.0, 3.0, 1],
[2.0, 2.0, 5.0, 5.0, 1],
[6.0, 1.0, 8.0, 3.0, 2],
]
),
np.array([1.0, 1.0, 2.0, 2.0, 2]),
]
)
>>> predictions = [
... array(
... [
... [0.0, 0.0, 3.0, 3.0, 1, 0.9],
... [0.1, 0.1, 3.0, 3.0, 0, 0.9],
... [6.0, 1.0, 8.0, 3.0, 1, 0.8],
... [1.0, 6.0, 2.0, 7.0, 1, 0.8],
... ]
... ),
... array([[1.0, 1.0, 2.0, 2.0, 2, 0.8]])
... ]
predictions = [
np.array(
[
[0.0, 0.0, 3.0, 3.0, 1, 0.9],
[0.1, 0.1, 3.0, 3.0, 0, 0.9],
[6.0, 1.0, 8.0, 3.0, 1, 0.8],
[1.0, 6.0, 2.0, 7.0, 1, 0.8],
]
),
np.array([[1.0, 1.0, 2.0, 2.0, 2, 0.8]])
]
>>> confusion_matrix = sv.ConfusionMatrix.from_tensors(
... predictions=predictions,
... targets=targets,
... classes=['person', ...]
... )
confusion_matrix = sv.ConfusionMatrix.from_tensors(
predictions=predictions,
targets=targets,
classes=['person', ...]
)
>>> confusion_matrix.matrix
array([
[0., 0., 0., 0.],
[0., 1., 0., 1.],
[0., 1., 1., 0.],
[1., 1., 0., 0.]
])
print(confusion_matrix.matrix)
# np.array([
# [0., 0., 0., 0.],
# [0., 1., 0., 1.],
# [0., 1., 1., 0.],
# [1., 1., 0., 0.]
# ])
```
"""
validate_input_tensors(predictions, targets)
@@ -365,28 +366,28 @@ class ConfusionMatrix:
Example:
```python
>>> import supervision as sv
>>> from ultralytics import YOLO
import supervision as sv
from ultralytics import YOLO
>>> dataset = sv.DetectionDataset.from_yolo(...)
dataset = sv.DetectionDataset.from_yolo(...)
>>> model = YOLO(...)
>>> def callback(image: np.ndarray) -> sv.Detections:
... result = model(image)[0]
... return sv.Detections.from_ultralytics(result)
model = YOLO(...)
def callback(image: np.ndarray) -> sv.Detections:
result = model(image)[0]
return sv.Detections.from_ultralytics(result)
>>> confusion_matrix = sv.ConfusionMatrix.benchmark(
... dataset = dataset,
... callback = callback
... )
confusion_matrix = sv.ConfusionMatrix.benchmark(
dataset = dataset,
callback = callback
)
>>> confusion_matrix.matrix
array([
[0., 0., 0., 0.],
[0., 1., 0., 1.],
[0., 1., 1., 0.],
[1., 1., 0., 0.]
])
print(confusion_matrix.matrix)
# np.array([
# [0., 0., 0., 0.],
# [0., 1., 0., 1.],
# [0., 1., 1., 0.],
# [1., 1., 0., 0.]
# ])
```
"""
predictions, targets = [], []
@@ -532,25 +533,25 @@ class MeanAveragePrecision:
Example:
```python
>>> import supervision as sv
import supervision as sv
>>> targets = [
... sv.Detections(...),
... sv.Detections(...)
... ]
targets = [
sv.Detections(...),
sv.Detections(...)
]
>>> predictions = [
... sv.Detections(...),
... sv.Detections(...)
... ]
predictions = [
sv.Detections(...),
sv.Detections(...)
]
>>> mean_average_precision = sv.MeanAveragePrecision.from_detections(
... predictions=predictions,
... targets=target,
... )
mean_average_precision = sv.MeanAveragePrecision.from_detections(
predictions=predictions,
targets=target,
)
>>> mean_average_precison.map50_95
0.2899
print(mean_average_precison.map50_95)
# 0.2899
```
"""
prediction_tensors = []
@@ -583,23 +584,23 @@ class MeanAveragePrecision:
Example:
```python
>>> import supervision as sv
>>> from ultralytics import YOLO
import supervision as sv
from ultralytics import YOLO
>>> dataset = sv.DetectionDataset.from_yolo(...)
dataset = sv.DetectionDataset.from_yolo(...)
>>> model = YOLO(...)
>>> def callback(image: np.ndarray) -> sv.Detections:
... result = model(image)[0]
... return sv.Detections.from_ultralytics(result)
model = YOLO(...)
def callback(image: np.ndarray) -> sv.Detections:
result = model(image)[0]
return sv.Detections.from_ultralytics(result)
>>> mean_average_precision = sv.MeanAveragePrecision.benchmark(
... dataset = dataset,
... callback = callback
... )
mean_average_precision = sv.MeanAveragePrecision.benchmark(
dataset = dataset,
callback = callback
)
>>> mean_average_precision.map50_95
0.433
print(mean_average_precision.map50_95)
# 0.433
```
"""
predictions, targets = [], []
@@ -637,40 +638,41 @@ class MeanAveragePrecision:
Example:
```python
>>> import supervision as sv
import supervision as sv
import numpy as np
>>> targets = (
... [
... array(
... [
... [0.0, 0.0, 3.0, 3.0, 1],
... [2.0, 2.0, 5.0, 5.0, 1],
... [6.0, 1.0, 8.0, 3.0, 2],
... ]
... ),
... array([1.0, 1.0, 2.0, 2.0, 2]),
... ]
... )
targets = (
[
np.array(
[
[0.0, 0.0, 3.0, 3.0, 1],
[2.0, 2.0, 5.0, 5.0, 1],
[6.0, 1.0, 8.0, 3.0, 2],
]
),
np.array([[1.0, 1.0, 2.0, 2.0, 2]]),
]
)
>>> predictions = [
... array(
... [
... [0.0, 0.0, 3.0, 3.0, 1, 0.9],
... [0.1, 0.1, 3.0, 3.0, 0, 0.9],
... [6.0, 1.0, 8.0, 3.0, 1, 0.8],
... [1.0, 6.0, 2.0, 7.0, 1, 0.8],
... ]
... ),
... array([[1.0, 1.0, 2.0, 2.0, 2, 0.8]])
... ]
predictions = [
np.array(
[
[0.0, 0.0, 3.0, 3.0, 1, 0.9],
[0.1, 0.1, 3.0, 3.0, 0, 0.9],
[6.0, 1.0, 8.0, 3.0, 1, 0.8],
[1.0, 6.0, 2.0, 7.0, 1, 0.8],
]
),
np.array([[1.0, 1.0, 2.0, 2.0, 2, 0.8]])
]
>>> mean_average_precison = sv.MeanAveragePrecision.from_tensors(
... predictions=predictions,
... targets=targets,
... )
mean_average_precison = sv.MeanAveragePrecision.from_tensors(
predictions=predictions,
targets=targets,
)
>>> mean_average_precison.map50_95
0.2899
print(mean_average_precison.map50_95)
# 0.6649
```
"""
validate_input_tensors(predictions, targets)
@@ -834,10 +836,10 @@ class MeanAveragePrecision:
precision = true_positives / (true_positives + false_positives)
for iou_level_idx in range(matches.shape[1]):
average_precisions[
class_idx, iou_level_idx
] = MeanAveragePrecision.compute_average_precision(
recall[:, iou_level_idx], precision[:, iou_level_idx]
average_precisions[class_idx, iou_level_idx] = (
MeanAveragePrecision.compute_average_precision(
recall[:, iou_level_idx], precision[:, iou_level_idx]
)
)
return average_precisions
@@ -39,6 +39,14 @@ class BaseTrack:
BaseTrack._count += 1
return BaseTrack._count
@staticmethod
def reset_counter():
BaseTrack._count = 0
BaseTrack.track_id = 0
BaseTrack.start_frame = 0
BaseTrack.frame_id = 0
BaseTrack.time_since_update = 0
def activate(self, *args):
raise NotImplementedError
+98 -44
View File
@@ -6,6 +6,7 @@ from supervision.detection.core import Detections
from supervision.tracker.byte_tracker import matching
from supervision.tracker.byte_tracker.basetrack import BaseTrack, TrackState
from supervision.tracker.byte_tracker.kalman_filter import KalmanFilter
from supervision.utils.internal import deprecated_parameter
class STrack(BaseTrack):
@@ -167,27 +168,62 @@ class ByteTrack:
"""
Initialize the ByteTrack object.
Parameters:
track_thresh (float, optional): Detection confidence threshold
for track activation.
track_buffer (int, optional): Number of frames to buffer when a track is lost.
match_thresh (float, optional): Threshold for matching tracks with detections.
frame_rate (int, optional): The frame rate of the video.
"""
<video controls>
<source src="https://media.roboflow.com/supervision/video-examples/how-to/track-objects/annotate-video-with-traces.mp4" type="video/mp4">
</video>
Parameters:
track_activation_threshold (float, optional): Detection confidence threshold
for track activation. Increasing track_activation_threshold improves accuracy
and stability but might miss true detections. Decreasing it increases
completeness but risks introducing noise and instability.
lost_track_buffer (int, optional): Number of frames to buffer when a track is lost.
Increasing lost_track_buffer enhances occlusion handling, significantly
reducing the likelihood of track fragmentation or disappearance caused
by brief detection gaps.
minimum_matching_threshold (float, optional): Threshold for matching tracks with detections.
Increasing minimum_matching_threshold improves accuracy but risks fragmentation.
Decreasing it improves completeness but risks false positives and drift.
frame_rate (int, optional): The frame rate of the video.
""" # noqa: E501 // docs
@deprecated_parameter(
old_parameter="track_buffer",
new_parameter="lost_track_buffer",
map_function=lambda x: x,
warning_message="`{old_parameter}` in `{function_name}` is deprecated and will "
"be remove in `supervision-0.23.0`. Use '{new_parameter}' "
"instead.",
)
@deprecated_parameter(
old_parameter="track_thresh",
new_parameter="track_activation_threshold",
map_function=lambda x: x,
warning_message="`{old_parameter}` in `{function_name}` is deprecated and will "
"be remove in `supervision-0.23.0`. Use '{new_parameter}' "
"instead.",
)
@deprecated_parameter(
old_parameter="match_thresh",
new_parameter="minimum_matching_threshold",
map_function=lambda x: x,
warning_message="`{old_parameter}` in `{function_name}` is deprecated and will "
"be remove in `supervision-0.23.0`. Use '{new_parameter}' "
"instead.",
)
def __init__(
self,
track_thresh: float = 0.25,
track_buffer: int = 30,
match_thresh: float = 0.8,
track_activation_threshold: float = 0.25,
lost_track_buffer: int = 30,
minimum_matching_threshold: float = 0.8,
frame_rate: int = 30,
):
self.track_thresh = track_thresh
self.match_thresh = match_thresh
self.track_activation_threshold = track_activation_threshold
self.minimum_matching_threshold = minimum_matching_threshold
self.frame_id = 0
self.det_thresh = self.track_thresh + 0.1
self.max_time_lost = int(frame_rate / 30.0 * track_buffer)
self.det_thresh = self.track_activation_threshold + 0.1
self.max_time_lost = int(frame_rate / 30.0 * lost_track_buffer)
self.kalman_filter = KalmanFilter()
self.tracked_tracks: List[STrack] = []
@@ -196,39 +232,41 @@ class ByteTrack:
def update_with_detections(self, detections: Detections) -> Detections:
"""
Updates the tracker with the provided detections and
returns the updated detection results.
Updates the tracker with the provided detections and returns the updated
detection results.
Args:
detections (Detections): The detections to pass through the tracker.
Parameters:
detections: The new detections to update with.
Returns:
Detection: The updated detection results that now include tracking IDs.
Example:
```python
>>> import supervision as sv
>>> from ultralytics import YOLO
import supervision as sv
from ultralytics import YOLO
>>> model = YOLO(...)
>>> byte_tracker = sv.ByteTrack()
>>> annotator = sv.BoxAnnotator()
model = YOLO(<MODEL_PATH>)
tracker = sv.ByteTrack()
>>> def callback(frame: np.ndarray, index: int) -> np.ndarray:
... results = model(frame)[0]
... detections = sv.Detections.from_ultralytics(results)
... detections = byte_tracker.update_with_detections(detections)
... labels = [
... f"#{tracker_id} {model.model.names[class_id]} {confidence:0.2f}"
... for _, _, confidence, class_id, tracker_id
... in detections
... ]
... return annotator.annotate(scene=frame.copy(),
... detections=detections, labels=labels)
bounding_box_annotator = sv.BoundingBoxAnnotator()
label_annotator = sv.LabelAnnotator()
>>> sv.process_video(
... source_path='...',
... target_path='...',
... callback=callback
... )
def callback(frame: np.ndarray, index: int) -> np.ndarray:
results = model(frame)[0]
detections = sv.Detections.from_ultralytics(results)
detections = tracker.update_with_detections(detections)
labels = [f"#{tracker_id}" for tracker_id in detections.tracker_id]
annotated_frame = bounding_box_annotator.annotate(
scene=frame.copy(), detections=detections)
annotated_frame = label_annotator.annotate(
scene=annotated_frame, detections=detections, labels=labels)
return annotated_frame
sv.process_video(
source_path=<SOURCE_VIDEO_PATH>,
target_path=<TARGET_VIDEO_PATH>,
callback=callback
)
```
"""
@@ -254,6 +292,21 @@ class ByteTrack:
return detections
def reset(self):
"""
Resets the internal state of the ByteTrack tracker.
This method clears the tracking data, including tracked, lost,
and removed tracks, as well as resetting the frame counter. It's
particularly useful when processing multiple videos sequentially,
ensuring the tracker starts with a clean state for each new video.
"""
self.frame_id = 0
self.tracked_tracks: List[STrack] = []
self.lost_tracks: List[STrack] = []
self.removed_tracks: List[STrack] = []
BaseTrack.reset_counter()
def update_with_tensors(self, tensors: np.ndarray) -> List[STrack]:
"""
Updates the tracker with the provided tensors and returns the updated tracks.
@@ -274,9 +327,9 @@ class ByteTrack:
scores = tensors[:, 4]
bboxes = tensors[:, :4]
remain_inds = scores > self.track_thresh
remain_inds = scores > self.track_activation_threshold
inds_low = scores > 0.1
inds_high = scores < self.track_thresh
inds_high = scores < self.track_activation_threshold
inds_second = np.logical_and(inds_low, inds_high)
dets_second = bboxes[inds_second]
@@ -299,6 +352,7 @@ class ByteTrack:
""" Add newly detected tracklets to tracked_stracks"""
unconfirmed = []
tracked_stracks = [] # type: list[STrack]
for track in self.tracked_tracks:
if not track.is_activated:
unconfirmed.append(track)
@@ -313,7 +367,7 @@ class ByteTrack:
dists = matching.fuse_score(dists, detections)
matches, u_track, u_detection = matching.linear_assignment(
dists, thresh=self.match_thresh
dists, thresh=self.minimum_matching_threshold
)
for itracked, idet in matches:
+6 -6
View File
@@ -34,14 +34,14 @@ def list_files_with_extensions(
Examples:
```python
>>> import supervision as sv
import supervision as sv
>>> # List all files in the directory
>>> files = sv.list_files_with_extensions(directory='my_directory')
# List all files in the directory
files = sv.list_files_with_extensions(directory='my_directory')
>>> # List only files with '.txt' and '.md' extensions
>>> files = sv.list_files_with_extensions(
... directory='my_directory', extensions=['txt', 'md'])
# List only files with '.txt' and '.md' extensions
files = sv.list_files_with_extensions(
directory='my_directory', extensions=['txt', 'md'])
```
"""
+83 -15
View File
@@ -1,6 +1,6 @@
import os
import shutil
from typing import Optional
from typing import Optional, Tuple
import cv2
import numpy as np
@@ -20,20 +20,88 @@ def crop_image(image: np.ndarray, xyxy: np.ndarray) -> np.ndarray:
Examples:
```python
>>> import supervision as sv
import supervision as sv
>>> detection = sv.Detections(...)
>>> with sv.ImageSink(target_dir_path='target/directory/path') as sink:
... for xyxy in detection.xyxy:
... cropped_image = sv.crop_image(image=image, xyxy=xyxy)
... sink.save_image(image=image)
detection = sv.Detections(...)
with sv.ImageSink(target_dir_path='target/directory/path') as sink:
for xyxy in detection.xyxy:
cropped_image = sv.crop_image(image=image, xyxy=xyxy)
sink.save_image(image=cropped_image)
```
"""
xyxy = np.round(xyxy).astype(int)
x1, y1, x2, y2 = xyxy
cropped_img = image[y1:y2, x1:x2]
return cropped_img
return image[y1:y2, x1:x2]
def resize_image(image: np.ndarray, scale_factor: float) -> np.ndarray:
"""
Resizes an image by a given scale factor using cv2.INTER_LINEAR interpolation.
Args:
image (np.ndarray): The input image to be resized.
scale_factor (float): The factor by which the image will be scaled. Scale factor
> 1.0 zooms in, < 1.0 zooms out.
Returns:
np.ndarray: The resized image.
Raises:
ValueError: If the scale factor is non-positive.
"""
if scale_factor <= 0:
raise ValueError("Scale factor must be positive.")
old_width, old_height = image.shape[1], image.shape[0]
nwe_width = int(old_width * scale_factor)
new_height = int(old_height * scale_factor)
return cv2.resize(image, (nwe_width, new_height), interpolation=cv2.INTER_LINEAR)
def place_image(
scene: np.ndarray, image: np.ndarray, anchor: Tuple[int, int]
) -> np.ndarray:
"""
Places an image onto a scene at a given anchor point, handling cases where
the image's position is partially or completely outside the scene's bounds.
Args:
scene (np.ndarray): The background scene onto which the image is placed.
image (np.ndarray): The image to be placed onto the scene.
anchor (Tuple[int, int]): The (x, y) coordinates in the scene where the
top-left corner of the image will be placed.
Returns:
np.ndarray: The modified scene with the image placed at the anchor point,
or unchanged if the image placement is completely outside the scene.
"""
scene_height, scene_width = scene.shape[:2]
image_height, image_width = image.shape[:2]
anchor_x, anchor_y = anchor
is_out_horizontally = anchor_x + image_width <= 0 or anchor_x >= scene_width
is_out_vertically = anchor_y + image_height <= 0 or anchor_y >= scene_height
if is_out_horizontally or is_out_vertically:
return scene
start_y = max(anchor_y, 0)
start_x = max(anchor_x, 0)
end_y = min(scene_height, anchor_y + image_height)
end_x = min(scene_width, anchor_x + image_width)
crop_start_y = max(-anchor_y, 0)
crop_start_x = max(-anchor_x, 0)
crop_end_y = image_height - max((anchor_y + image_height) - scene_height, 0)
crop_end_x = image_width - max((anchor_x + image_width) - scene_width, 0)
scene[start_y:end_y, start_x:end_x] = image[
crop_start_y:crop_end_y, crop_start_x:crop_end_x
]
return scene
class ImageSink:
@@ -55,13 +123,13 @@ class ImageSink:
Examples:
```python
>>> import supervision as sv
import supervision as sv
>>> with sv.ImageSink(target_dir_path='target/directory/path',
... overwrite=True) as sink:
... for image in sv.get_video_frames_generator(
... source_path='source_video.mp4', stride=2):
... sink.save_image(image=image)
with sv.ImageSink(target_dir_path='target/directory/path',
overwrite=True) as sink:
for image in sv.get_video_frames_generator(
source_path='source_video.mp4', stride=2):
sink.save_image(image=image)
```
"""
+100 -1
View File
@@ -1,5 +1,104 @@
import functools
import os
import warnings
from typing import Callable
class SupervisionWarnings(Warning):
"""Supervision warning category.
Set the deprecation warnings visibility for Supervision library.
You can set the environment variable SUPERVISON_DEPRECATION_WARNING to '0' to
disable the deprecation warnings.
"""
pass
def format_warning(msg, category, filename, lineno, line=None):
"""
Format a warning the same way as the default formatter, but also include the
category name in the output.
"""
return f"{category.__name__}: {msg}\n"
warnings.formatwarning = format_warning
if os.getenv("SUPERVISON_DEPRECATION_WARNING") == "0":
warnings.simplefilter("ignore", SupervisionWarnings)
else:
warnings.simplefilter("always", SupervisionWarnings)
def deprecated_parameter(
old_parameter: str,
new_parameter: str,
map_function: Callable = lambda x: x,
warning_message: str = "Warning: '{old_parameter}' in '{function_name}' is "
"deprecated: use '{new_parameter}' instead.",
**message_kwargs,
):
"""
A decorator to mark a function's parameter as deprecated and issue a warning when
used.
Parameters:
old_parameter (str): The name of the deprecated parameter.
new_parameter (str): The name of the parameter that should be used instead.
map_function (Callable, optional): A function used to map the value of the old
parameter to the new parameter. Defaults to the identity function.
warning_message (str, optional): The warning message to be displayed when the
deprecated parameter is used. Defaults to a generic warning message with
placeholders for the old parameter, new parameter, and function name.
**message_kwargs: Additional keyword arguments that can be used to customize
the warning message.
Returns:
Callable: A decorator function that can be applied to mark a function's
parameter as deprecated.
Examples:
```python
@deprecated_parameter(
old_parameter=<OLD_PARAMETER_NAME>,
new_parameter=<NEW_PARAMETER_NAME>
)
def example_function(<NEW_PARAMETER_NAME>):
pass
# call function using deprecated parameter
example_function(<OLD_PARAMETER_NAME>=<OLD_PARAMETER_VALUE>)
```
"""
def decorator(func):
@functools.wraps(func)
def wrapper(*args, **kwargs):
if old_parameter in kwargs:
if args and hasattr(args[0], "__class__"):
class_name = args[0].__class__.__name__
function_name = f"{class_name}.{func.__name__}"
else:
function_name = func.__name__
warnings.warn(
message=warning_message.format(
function_name=function_name,
old_parameter=old_parameter,
new_parameter=new_parameter,
**message_kwargs,
),
category=SupervisionWarnings,
stacklevel=2,
)
kwargs[new_parameter] = map_function(kwargs.pop(old_parameter))
return func(*args, **kwargs)
return wrapper
return decorator
def deprecated(reason: str):
@@ -8,7 +107,7 @@ def deprecated(reason: str):
def wrapper(*args, **kwargs):
warnings.warn(
f"{func.__name__} is deprecated: {reason}",
category=DeprecationWarning,
category=SupervisionWarnings,
stacklevel=2,
)
return func(*args, **kwargs)
+30 -17
View File
@@ -2,31 +2,38 @@ from typing import List, Optional, Tuple
import cv2
import matplotlib.pyplot as plt
import numpy as np
from PIL import Image
from supervision.annotators.base import ImageType
from supervision.annotators.utils import pillow_to_cv2
def plot_image(
image: np.ndarray, size: Tuple[int, int] = (12, 12), cmap: Optional[str] = "gray"
image: ImageType, size: Tuple[int, int] = (12, 12), cmap: Optional[str] = "gray"
) -> None:
"""
Plots image using matplotlib.
Args:
image (np.ndarray): The frame to be displayed.
image (ImageType): The frame to be displayed ImageType
is a flexible type, accepting either `numpy.ndarray` or `PIL.Image.Image`.
size (Tuple[int, int]): The size of the plot.
cmap (str): the colormap to use for single channel images.
Examples:
```python
>>> import cv2
>>> import supervision as sv
import cv2
import supervision as sv
>>> image = cv2.imread("path/to/image.jpg")
image = cv2.imread("path/to/image.jpg")
%matplotlib inline
>>> sv.plot_image(image=image, size=(16, 16))
sv.plot_image(image=image, size=(16, 16))
```
"""
if isinstance(image, Image.Image):
image = pillow_to_cv2(image)
plt.figure(figsize=size)
if image.ndim == 2:
@@ -39,7 +46,7 @@ def plot_image(
def plot_images_grid(
images: List[np.ndarray],
images: List[ImageType],
grid_size: Tuple[int, int],
titles: Optional[List[str]] = None,
size: Tuple[int, int] = (12, 12),
@@ -49,7 +56,8 @@ def plot_images_grid(
Plots images in a grid using matplotlib.
Args:
images (List[np.ndarray]): A list of images as numpy arrays.
images (List[ImageType]): A list of images as ImageType
is a flexible type, accepting either `numpy.ndarray` or `PIL.Image.Image`.
grid_size (Tuple[int, int]): A tuple specifying the number
of rows and columns for the grid.
titles (Optional[List[str]]): A list of titles for each image.
@@ -63,22 +71,27 @@ def plot_images_grid(
Examples:
```python
>>> import cv2
>>> import supervision as sv
import cv2
import supervision as sv
from PIL import Image
>>> image1 = cv2.imread("path/to/image1.jpg")
>>> image2 = cv2.imread("path/to/image2.jpg")
>>> image3 = cv2.imread("path/to/image3.jpg")
image1 = cv2.imread("path/to/image1.jpg")
image2 = Image.open("path/to/image2.jpg")
image3 = cv2.imread("path/to/image3.jpg")
>>> images = [image1, image2, image3]
>>> titles = ["Image 1", "Image 2", "Image 3"]
images = [image1, image2, image3]
titles = ["Image 1", "Image 2", "Image 3"]
%matplotlib inline
>>> plot_images_grid(images, grid_size=(2, 2), titles=titles, size=(16, 16))
plot_images_grid(images, grid_size=(2, 2), titles=titles, size=(16, 16))
```
"""
nrows, ncols = grid_size
for idx, img in enumerate(images):
if isinstance(img, Image.Image):
images[idx] = pillow_to_cv2(img)
if len(images) > nrows * ncols:
raise ValueError(
"The number of images exceeds the grid size. Please increase the grid size"
+53 -33
View File
@@ -8,6 +8,8 @@ from typing import Callable, Generator, Optional, Tuple
import cv2
import numpy as np
from supervision.utils.internal import deprecated
@dataclass
class VideoInfo:
@@ -24,15 +26,15 @@ class VideoInfo:
Examples:
```python
>>> import supervision as sv
import supervision as sv
>>> video_info = sv.VideoInfo.from_video_path(video_path='video.mp4')
video_info = sv.VideoInfo.from_video_path(video_path=<SOURCE_VIDEO_FILE>)
>>> video_info
VideoInfo(width=3840, height=2160, fps=25, total_frames=538)
video_info
# VideoInfo(width=3840, height=2160, fps=25, total_frames=538)
>>> video_info.resolution_wh
(3840, 2160)
video_info.resolution_wh
# (3840, 2160)
```
"""
@@ -71,16 +73,16 @@ class VideoSink:
Example:
```python
>>> import supervision as sv
import supervision as sv
>>> video_info = sv.VideoInfo.from_video_path('source.mp4')
>>> frames_generator = sv.get_video_frames_generator('source.mp4')
video_info = sv.VideoInfo.from_video_path(<SOURCE_VIDEO_PATH>)
frames_generator = sv.get_video_frames_generator(<SOURCE_VIDEO_PATH>)
>>> with sv.VideoSink(target_path='target.mp4', video_info=video_info) as sink:
... for frame in frames_generator:
... sink.write_frame(frame=frame)
with sv.VideoSink(target_path=<TARGET_VIDEO_PATH>, video_info=video_info) as sink:
for frame in frames_generator:
sink.write_frame(frame=frame)
```
"""
""" # noqa: E501 // docs
def __init__(self, target_path: str, video_info: VideoInfo, codec: str = "mp4v"):
self.target_path = target_path
@@ -143,10 +145,10 @@ def get_video_frames_generator(
Examples:
```python
>>> import supervision as sv
import supervision as sv
>>> for frame in sv.get_video_frames_generator(source_path='source_video.mp4'):
... ...
for frame in sv.get_video_frames_generator(source_path=<SOURCE_VIDEO_PATH>):
...
```
"""
video, start, end = _validate_and_setup_video(source_path, start, end)
@@ -183,16 +185,16 @@ def process_video(
Examples:
```python
>>> import supervision as sv
import supervision as sv
>>> def callback(scene: np.ndarray, index: int) -> np.ndarray:
... ...
def callback(scene: np.ndarray, index: int) -> np.ndarray:
...
>>> process_video(
... source_path='...',
... target_path='...',
... callback=callback
... )
process_video(
source_path=<SOURCE_VIDEO_PATH>,
target_path=<TARGET_VIDEO_PATH>,
callback=callback
)
```
"""
source_video_info = VideoInfo.from_video_path(video_path=source_path)
@@ -217,27 +219,45 @@ class FPSMonitor:
Examples:
```python
>>> import supervision as sv
import supervision as sv
>>> frames_generator = sv.get_video_frames_generator('source.mp4')
>>> fps_monitor = sv.FPSMonitor()
frames_generator = sv.get_video_frames_generator(source_path=<SOURCE_FILE_PATH>)
fps_monitor = sv.FPSMonitor()
>>> for frame in frames_generator:
... # your processing code here
... fps_monitor.tick()
... fps = fps_monitor()
for frame in frames_generator:
# your processing code here
fps_monitor.tick()
fps = fps_monitor.fps
```
"""
""" # noqa: E501 // docs
self.all_timestamps = deque(maxlen=sample_size)
@deprecated(
"`FPSMonitor.__call__` is deprecated and will be removed in "
"`supervision-0.22.0`. Use `FPSMonitor.fps` instead."
)
def __call__(self) -> float:
"""
!!! failure "Deprecated"
`FPSMonitor.__call__` is deprecated and will be removed in
`supervision-0.22.0`. Use `FPSMonitor.fps` instead.
Computes and returns the average FPS based on the stored time stamps.
Returns:
float: The average FPS. Returns 0.0 if no time stamps are stored.
"""
return self.fps
@property
def fps(self) -> float:
"""
Computes and returns the average FPS based on the stored time stamps.
Returns:
float: The average FPS. Returns 0.0 if no time stamps are stored.
"""
if not self.all_timestamps:
return 0.0
taken_time = self.all_timestamps[-1] - self.all_timestamps[0]
+415
View File
@@ -0,0 +1,415 @@
import csv
import os
from test.test_utils import mock_detections
from typing import Any, Dict, List
import pytest
import supervision as sv
@pytest.mark.parametrize(
"detections, custom_data, "
"second_detections, second_custom_data, "
"file_name, expected_result",
[
(
mock_detections(
xyxy=[[10, 20, 30, 40], [50, 60, 70, 80]],
confidence=[0.7, 0.8],
class_id=[0, 0],
tracker_id=[0, 1],
data={"class_name": ["person", "person"]},
),
{"frame_number": 42},
mock_detections(
xyxy=[[15, 25, 35, 45], [55, 65, 75, 85]],
confidence=[0.6, 0.9],
class_id=[1, 1],
tracker_id=[2, 3],
data={"class_name": ["car", "car"]},
),
{"frame_number": 43},
"test_detections.csv",
[
[
"x_min",
"y_min",
"x_max",
"y_max",
"class_id",
"confidence",
"tracker_id",
"class_name",
"frame_number",
],
["10.0", "20.0", "30.0", "40.0", "0", "0.7", "0", "person", "42"],
["50.0", "60.0", "70.0", "80.0", "0", "0.8", "1", "person", "42"],
["15.0", "25.0", "35.0", "45.0", "1", "0.6", "2", "car", "43"],
["55.0", "65.0", "75.0", "85.0", "1", "0.9", "3", "car", "43"],
],
), # multiple detections
(
mock_detections(
xyxy=[[60, 70, 80, 90], [100, 110, 120, 130]],
tracker_id=[4, 5],
data={"class_name": ["bike", "dog"]},
),
{"frame_number": 44},
mock_detections(
xyxy=[[65, 75, 85, 95], [105, 115, 125, 135]],
confidence=[0.5, 0.4],
data={"class_name": ["tree", "cat"]},
),
{"frame_number": 45},
"test_detections_missing_fields.csv",
[
[
"x_min",
"y_min",
"x_max",
"y_max",
"class_id",
"confidence",
"tracker_id",
"class_name",
"frame_number",
],
["60.0", "70.0", "80.0", "90.0", "", "", "4", "bike", "44"],
["100.0", "110.0", "120.0", "130.0", "", "", "5", "dog", "44"],
["65.0", "75.0", "85.0", "95.0", "", "0.5", "", "tree", "45"],
["105.0", "115.0", "125.0", "135.0", "", "0.4", "", "cat", "45"],
],
), # missing fields
(
mock_detections(
xyxy=[[10, 11, 12, 13]],
confidence=[0.95],
data={"class_name": "unknown", "is_detected": True, "score": 1},
),
{"frame_number": 46},
mock_detections(
xyxy=[[14, 15, 16, 17]],
data={"class_name": "artifact", "is_detected": False, "score": 0.85},
),
{"frame_number": 47},
"test_detections_varied_data.csv",
[
[
"x_min",
"y_min",
"x_max",
"y_max",
"class_id",
"confidence",
"tracker_id",
"class_name",
"frame_number",
"is_detected",
"score",
],
[
"10.0",
"11.0",
"12.0",
"13.0",
"",
"0.95",
"",
"unknown",
"46",
"True",
"1",
],
[
"14.0",
"15.0",
"16.0",
"17.0",
"",
"",
"",
"artifact",
"47",
"False",
"0.85",
],
],
), # Inconsistent Data Types
(
mock_detections(
xyxy=[[20, 21, 22, 23]],
),
{
"metadata": {"sensor_id": 101, "location": "north"},
"tags": ["urgent", "review"],
},
mock_detections(
xyxy=[[14, 15, 16, 17]],
),
{
"metadata": {"sensor_id": 104, "location": "west"},
"tags": ["not-urgent", "done"],
},
"test_detections_complex_data.csv",
[
[
"x_min",
"y_min",
"x_max",
"y_max",
"class_id",
"confidence",
"tracker_id",
"metadata",
"tags",
],
[
"20.0",
"21.0",
"22.0",
"23.0",
"",
"",
"",
"{'sensor_id': 101, 'location': 'north'}",
"['urgent', 'review']",
],
[
"14.0",
"15.0",
"16.0",
"17.0",
"",
"",
"",
"{'sensor_id': 104, 'location': 'west'}",
"['not-urgent', 'done']",
],
],
), # Complex Data
],
)
def test_csv_sink(
detections: mock_detections,
custom_data: Dict[str, Any],
second_detections: mock_detections,
second_custom_data: Dict[str, Any],
file_name: str,
expected_result: List[List[Any]],
) -> None:
with sv.CSVSink(file_name) as sink:
sink.append(detections, custom_data)
sink.append(second_detections, second_custom_data)
assert_csv_equal(file_name, expected_result)
@pytest.mark.parametrize(
"detections, custom_data, "
"second_detections, second_custom_data, "
"file_name, expected_result",
[
(
mock_detections(
xyxy=[[10, 20, 30, 40], [50, 60, 70, 80]],
confidence=[0.7, 0.8],
class_id=[0, 0],
tracker_id=[0, 1],
data={"class_name": ["person", "person"]},
),
{"frame_number": 42},
mock_detections(
xyxy=[[15, 25, 35, 45], [55, 65, 75, 85]],
confidence=[0.6, 0.9],
class_id=[1, 1],
tracker_id=[2, 3],
data={"class_name": ["car", "car"]},
),
{"frame_number": 43},
"test_detections.csv",
[
[
"x_min",
"y_min",
"x_max",
"y_max",
"class_id",
"confidence",
"tracker_id",
"class_name",
"frame_number",
],
["10.0", "20.0", "30.0", "40.0", "0", "0.7", "0", "person", "42"],
["50.0", "60.0", "70.0", "80.0", "0", "0.8", "1", "person", "42"],
["15.0", "25.0", "35.0", "45.0", "1", "0.6", "2", "car", "43"],
["55.0", "65.0", "75.0", "85.0", "1", "0.9", "3", "car", "43"],
],
), # multiple detections
(
mock_detections(
xyxy=[[60, 70, 80, 90], [100, 110, 120, 130]],
tracker_id=[4, 5],
data={"class_name": ["bike", "dog"]},
),
{"frame_number": 44},
mock_detections(
xyxy=[[65, 75, 85, 95], [105, 115, 125, 135]],
confidence=[0.5, 0.4],
data={"class_name": ["tree", "cat"]},
),
{"frame_number": 45},
"test_detections_missing_fields.csv",
[
[
"x_min",
"y_min",
"x_max",
"y_max",
"class_id",
"confidence",
"tracker_id",
"class_name",
"frame_number",
],
["60.0", "70.0", "80.0", "90.0", "", "", "4", "bike", "44"],
["100.0", "110.0", "120.0", "130.0", "", "", "5", "dog", "44"],
["65.0", "75.0", "85.0", "95.0", "", "0.5", "", "tree", "45"],
["105.0", "115.0", "125.0", "135.0", "", "0.4", "", "cat", "45"],
],
), # missing fields
(
mock_detections(
xyxy=[[10, 11, 12, 13]],
confidence=[0.95],
data={"class_name": "unknown", "is_detected": True, "score": 1},
),
{"frame_number": 46},
mock_detections(
xyxy=[[14, 15, 16, 17]],
data={"class_name": "artifact", "is_detected": False, "score": 0.85},
),
{"frame_number": 47},
"test_detections_varied_data.csv",
[
[
"x_min",
"y_min",
"x_max",
"y_max",
"class_id",
"confidence",
"tracker_id",
"class_name",
"frame_number",
"is_detected",
"score",
],
[
"10.0",
"11.0",
"12.0",
"13.0",
"",
"0.95",
"",
"unknown",
"46",
"True",
"1",
],
[
"14.0",
"15.0",
"16.0",
"17.0",
"",
"",
"",
"artifact",
"47",
"False",
"0.85",
],
],
), # Inconsistent Data Types
(
mock_detections(
xyxy=[[20, 21, 22, 23]],
),
{
"metadata": {"sensor_id": 101, "location": "north"},
"tags": ["urgent", "review"],
},
mock_detections(
xyxy=[[14, 15, 16, 17]],
),
{
"metadata": {"sensor_id": 104, "location": "west"},
"tags": ["not-urgent", "done"],
},
"test_detections_complex_data.csv",
[
[
"x_min",
"y_min",
"x_max",
"y_max",
"class_id",
"confidence",
"tracker_id",
"metadata",
"tags",
],
[
"20.0",
"21.0",
"22.0",
"23.0",
"",
"",
"",
"{'sensor_id': 101, 'location': 'north'}",
"['urgent', 'review']",
],
[
"14.0",
"15.0",
"16.0",
"17.0",
"",
"",
"",
"{'sensor_id': 104, 'location': 'west'}",
"['not-urgent', 'done']",
],
],
), # Complex Data
],
)
def test_csv_sink_manual(
detections: mock_detections,
custom_data: Dict[str, Any],
second_detections: mock_detections,
second_custom_data: Dict[str, Any],
file_name: str,
expected_result: List[List[Any]],
) -> None:
sink = sv.CSVSink(file_name)
sink.open()
sink.append(detections, custom_data)
sink.append(second_detections, second_custom_data)
sink.close()
assert_csv_equal(file_name, expected_result)
def assert_csv_equal(file_name, expected_rows):
with open(file_name, mode="r", newline="") as file:
reader = csv.reader(file)
for i, row in enumerate(reader):
assert (
[str(item) for item in expected_rows[i]] == row
), f"Row in CSV didn't match expected output: {row} != {expected_rows[i]}"
os.remove(file_name)

Some files were not shown because too many files have changed in this diff Show More