Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
87b1b86f39 | ||
|
|
1170a90ffc | ||
|
|
2e0e8d9132 | ||
|
|
15730b2b5d | ||
|
|
2db1e3af34 | ||
|
|
840226afce | ||
|
|
dc03ceac31 | ||
|
|
f9ab57afde | ||
|
|
fb19852919 | ||
|
|
60f8d28535 | ||
|
|
153cde5854 | ||
|
|
de87030a21 | ||
|
|
5a59dcdec6 | ||
|
|
87e8153876 | ||
|
|
c4a3038c57 | ||
|
|
6069c477b0 | ||
|
|
6beabe3fb4 | ||
|
|
8df86e2599 | ||
|
|
06beb6ff2f | ||
|
|
5d165e04c2 | ||
|
|
a5c4ebad08 | ||
|
|
9590b72f44 | ||
|
|
77dd68ee27 | ||
|
|
c61fbf6355 | ||
|
|
62efdee025 | ||
|
|
f28874c0c2 | ||
|
|
982c801db7 | ||
|
|
0ce6846880 | ||
|
|
f5baeef7ae | ||
|
|
09f3ea13e7 | ||
|
|
b7ad4c1df0 | ||
|
|
ed7606f886 | ||
|
|
a0f5c9a41a | ||
|
|
23fca01cfc | ||
|
|
35cb41bd21 | ||
|
|
6dce8ba38d | ||
|
|
10f4b86b70 | ||
|
|
6fa7395b99 | ||
|
|
eddcf3d09f | ||
|
|
e275a239ad | ||
|
|
cd36ae05e9 | ||
|
|
3997182ee7 | ||
|
|
845e47f472 | ||
|
|
565cd919e9 | ||
|
|
e514142b3d | ||
|
|
72fc49f124 | ||
|
|
51dd062407 | ||
|
|
e19f3120ca | ||
|
|
6b5eed2ba1 | ||
|
|
5a29ad9525 | ||
|
|
9b7099d3fc | ||
|
|
ee8a61a3e7 | ||
|
|
48035c14e2 | ||
|
|
ddb3515b56 | ||
|
|
85ba8be9dd | ||
|
|
129118817a | ||
|
|
9ed1f07ca0 | ||
|
|
38be1be4b2 | ||
|
|
d33715464b | ||
|
|
e6fab4b7fa | ||
|
|
8b60ee1a0e | ||
|
|
a6ee3e98c7 | ||
|
|
8b2f961ba8 | ||
|
|
c8a8540698 | ||
|
|
d6a24d0dd9 | ||
|
|
d94db74493 | ||
|
|
fdaadacbe3 | ||
|
|
819fcde7e4 | ||
|
|
ad7a9988e7 | ||
|
|
cee411689d | ||
|
|
600099e8ab | ||
|
|
7912e7e5bb | ||
|
|
2dee466abc | ||
|
|
c010656161 | ||
|
|
ca9bff184c | ||
|
|
e4cedb6861 | ||
|
|
664bf3cf79 | ||
|
|
a673640aad | ||
|
|
7d8b2b3fc5 | ||
|
|
93f5622d15 | ||
|
|
a78bf58c6d | ||
|
|
e5fef4501b | ||
|
|
0c69d0d333 | ||
|
|
6d92214718 | ||
|
|
eef16454e2 | ||
|
|
87c63fe7a1 | ||
|
|
9eba61de10 | ||
|
|
b385508606 | ||
|
|
d70bc4f58b | ||
|
|
c2dedba3db | ||
|
|
6ca9555efd | ||
|
|
ae2c356321 | ||
|
|
f8f62891de | ||
|
|
162a46cae1 | ||
|
|
b5ccf6882d | ||
|
|
6576a846d9 | ||
|
|
49a0f372d7 | ||
|
|
91c5f3f106 | ||
|
|
0b4cc5ff5b | ||
|
|
0ed48f0227 | ||
|
|
acbaf4ff25 | ||
|
|
124be19928 | ||
|
|
839d117f6c | ||
|
|
9955f0137a | ||
|
|
9fcabc8b9a | ||
|
|
e5ff27b0aa | ||
|
|
a00ea2087f | ||
|
|
2dd1bc5df6 | ||
|
|
83dfc87ef5 | ||
|
|
00c96c03ee | ||
|
|
6f1eb63825 | ||
|
|
e4d0be777d | ||
|
|
54328e37a0 | ||
|
|
3dd9e56da4 | ||
|
|
6d35301672 | ||
|
|
8e4fedf3f1 | ||
|
|
cd0aac2655 | ||
|
|
6969e7a78c | ||
|
|
ea3a0e9a4e | ||
|
|
53950fd426 | ||
|
|
c67d977682 | ||
|
|
5c5bfe5544 | ||
|
|
0ebab21e9c | ||
|
|
6566063e2b | ||
|
|
ecdbea340e | ||
|
|
5ce6e484b8 | ||
|
|
2d0404e67c | ||
|
|
d89ebde4d1 | ||
|
|
a897905955 | ||
|
|
b8a2a6996c | ||
|
|
2ca9bee083 | ||
|
|
6af1ab31f4 | ||
|
|
5b56d40ef9 | ||
|
|
2abdccbe1d | ||
|
|
d925cdf666 | ||
|
|
c592cd9ff3 | ||
|
|
66c49b2e80 | ||
|
|
0efb55ec19 | ||
|
|
11f483b75e | ||
|
|
1688e71ed9 | ||
|
|
45aedbda7e | ||
|
|
6a1b2b8eb4 | ||
|
|
0dc9188c5b | ||
|
|
a4de1a0f47 | ||
|
|
195f4618a3 | ||
|
|
fd2d63c1d7 | ||
|
|
c1887da1e8 | ||
|
|
efbb5e2599 | ||
|
|
6149bacc77 | ||
|
|
86b268d396 | ||
|
|
a5b51a11e5 | ||
|
|
2b1abb1f5b | ||
|
|
cfaea751f2 | ||
|
|
6e8e6fb276 | ||
|
|
6c2c3f8862 | ||
|
|
64acee9bec | ||
|
|
5f17003f17 | ||
|
|
cda79458a9 | ||
|
|
566844f591 | ||
|
|
4c35dee692 | ||
|
|
e2ca285610 | ||
|
|
c999fad06f | ||
|
|
a542406945 | ||
|
|
00a123b5fb | ||
|
|
3d939fd4a2 | ||
|
|
f005ea1d17 | ||
|
|
f6326d5590 | ||
|
|
b4262bb08e | ||
|
|
a9dad95fa7 | ||
|
|
91ff090168 | ||
|
|
6d68a825ab | ||
|
|
2043ba7feb | ||
|
|
5ac08abcf3 | ||
|
|
1c37d143b4 | ||
|
|
f78b891011 | ||
|
|
f2fc5b2952 | ||
|
|
09565ddacd | ||
|
|
780db7520d | ||
|
|
fd9083ae76 | ||
|
|
ebe3fd4d2f | ||
|
|
ce4204adc1 | ||
|
|
48450b5da3 | ||
|
|
fbd6f4dc5a | ||
|
|
4c1f33189b | ||
|
|
dcce0e4807 | ||
|
|
b8e88bf9c5 | ||
|
|
3b09a6356a | ||
|
|
5ced8c4ea0 | ||
|
|
b25556dae9 | ||
|
|
beaa0be014 | ||
|
|
a765bd9bd7 | ||
|
|
7bf03f5a3c | ||
|
|
93d419d7c6 | ||
|
|
44614dea94 | ||
|
|
ac379e467a | ||
|
|
7507d3a68c | ||
|
|
06bd638f15 | ||
|
|
5d60d78362 | ||
|
|
377a87dbba | ||
|
|
c2c7ca03d3 | ||
|
|
21482e9109 | ||
|
|
0bf55b7ac7 | ||
|
|
0b48ad1c22 | ||
|
|
31e478b84c | ||
|
|
2bbb9ef2ed | ||
|
|
b85b41d5f1 | ||
|
|
8419279fb9 | ||
|
|
1bab3fff8f | ||
|
|
82a0aa2463 | ||
|
|
f5a8bb93e8 | ||
|
|
a90a1c967b | ||
|
|
e2c380acbc | ||
|
|
819d74f57c | ||
|
|
47e6a4bc88 | ||
|
|
09de0f4f06 | ||
|
|
f1e0c9cdd7 | ||
|
|
72d55a2938 | ||
|
|
3abb6245c1 | ||
|
|
a352e23d95 | ||
|
|
75a2036ea3 | ||
|
|
3d7642c09e | ||
|
|
fabbff2b60 | ||
|
|
751eddc0ce | ||
|
|
8df7aea949 | ||
|
|
bbc96e14c9 | ||
|
|
5695b7f58f | ||
|
|
a1c58a92e2 | ||
|
|
886a44b102 | ||
|
|
9b91c779e5 | ||
|
|
3697b2298c | ||
|
|
e861878a22 | ||
|
|
834fd8db05 | ||
|
|
fba1713944 | ||
|
|
b143121859 | ||
|
|
132cc056f6 | ||
|
|
f6e0896278 | ||
|
|
de4f060d3b | ||
|
|
14b7f91c5c | ||
|
|
5016ed3c8a | ||
|
|
d570366fb4 | ||
|
|
95ef33a102 | ||
|
|
fc11beac78 | ||
|
|
cb1fcecaf2 | ||
|
|
afdbdc55f7 | ||
|
|
28dfc39c02 | ||
|
|
793f246ebc | ||
|
|
9aa9ef5bbe | ||
|
|
6e18804c55 | ||
|
|
bca3c60bb3 | ||
|
|
7f7b25d7e7 | ||
|
|
72506888c0 | ||
|
|
c5cc24f22d | ||
|
|
47574ed29d | ||
|
|
6119f2017e | ||
|
|
bbc37b4b6a | ||
|
|
e12bfe263d | ||
|
|
373fbae1fa | ||
|
|
790ccace2c | ||
|
|
a99015ac2d | ||
|
|
52c772d778 | ||
|
|
5af13c0f8c | ||
|
|
e0edb28ce6 | ||
|
|
c35a35cefd | ||
|
|
9bd8f71f26 | ||
|
|
e29e3832fb | ||
|
|
a287e68c92 | ||
|
|
0422a66eaa | ||
|
|
31db2ded11 | ||
|
|
9ab9650763 | ||
|
|
353bd5336b | ||
|
|
7301156e46 | ||
|
|
e68c908077 | ||
|
|
2edcbdc487 | ||
|
|
25c2f5cf0d | ||
|
|
316cb6271d | ||
|
|
70e9af9200 | ||
|
|
38f89125b1 | ||
|
|
80d76e712a | ||
|
|
a296712000 | ||
|
|
12d7c369db | ||
|
|
c8223cbab2 | ||
|
|
2c522a9931 | ||
|
|
fc0e133ea9 | ||
|
|
15364ac9a3 | ||
|
|
e82b5b9d74 | ||
|
|
c8f5c741fd | ||
|
|
8d464aa1b5 | ||
|
|
ce28ab7fc7 | ||
|
|
fae1bc2661 | ||
|
|
4663fab4e4 | ||
|
|
db0892f3e9 | ||
|
|
d330bafaa7 | ||
|
|
8b91d733af | ||
|
|
97bf652d90 | ||
|
|
b0bbb74558 | ||
|
|
1d73468dc5 | ||
|
|
dfd2a60855 | ||
|
|
f563c5a634 | ||
|
|
35272b40d3 | ||
|
|
9320be5d5b | ||
|
|
d109fba9d8 | ||
|
|
42d92ba913 | ||
|
|
1e2dc8f88b | ||
|
|
f716b7fa3b | ||
|
|
f6d52b53db | ||
|
|
61cca76acc | ||
|
|
9ad850af46 | ||
|
|
eee6a85eaa | ||
|
|
bb87ab0a6e | ||
|
|
da7c5cd65a | ||
|
|
ceefe0bab2 | ||
|
|
78439e03cc | ||
|
|
b66416e074 | ||
|
|
6c7c49e051 | ||
|
|
b1b69ad972 | ||
|
|
52be9dc818 | ||
|
|
c7e95483bf | ||
|
|
65f6e418a1 | ||
|
|
1fef946a19 | ||
|
|
4c3d51f186 | ||
|
|
9340cb962b | ||
|
|
6578b4ea52 | ||
|
|
0bd60874ca | ||
|
|
b02ec93b30 | ||
|
|
89ee57f519 | ||
|
|
1c8398942a | ||
|
|
3e7e4caf3f | ||
|
|
a3ea8cdb1f | ||
|
|
32dca290ef | ||
|
|
03f623920a | ||
|
|
98476dfacf | ||
|
|
35ff87b08d | ||
|
|
03eed3fd64 | ||
|
|
272d9ed5bf | ||
|
|
371f8ecc5b | ||
|
|
171687f3ab | ||
|
|
421ad21c98 | ||
|
|
50358e96b6 | ||
|
|
86e10db19e | ||
|
|
deb1c9c4f4 | ||
|
|
6679b1f5a9 | ||
|
|
c7de70ed20 | ||
|
|
2cdb70eb91 | ||
|
|
2ef029ef4b | ||
|
|
dce96d462e | ||
|
|
3fcbef9482 | ||
|
|
c8b966be1a | ||
|
|
72621dce32 | ||
|
|
098d5e3eb1 | ||
|
|
8c49465d49 | ||
|
|
4ad36db3bb | ||
|
|
a933b93234 | ||
|
|
cbb58a8c6f | ||
|
|
8fc22f0281 | ||
|
|
4b7b347aea | ||
|
|
5c6745291b | ||
|
|
83d490dadc | ||
|
|
005cdbd37a | ||
|
|
ade2668ae3 | ||
|
|
46e5965680 | ||
|
|
aab3160cd7 | ||
|
|
13ab215fdf | ||
|
|
a08cda30fb | ||
|
|
652b0a190f | ||
|
|
6f87e2639e | ||
|
|
e1393691a4 | ||
|
|
90f8582e4f | ||
|
|
0c9fea4d9f | ||
|
|
cdca2e6b51 | ||
|
|
8407d5a692 | ||
|
|
eaf6cdd477 | ||
|
|
f447b6fa95 | ||
|
|
8c6ac2dd29 | ||
|
|
22b6d3d464 | ||
|
|
dda3900943 | ||
|
|
ac0c367e81 | ||
|
|
6f2490cc23 | ||
|
|
4a9d06eb50 | ||
|
|
21e311a319 | ||
|
|
71a14812fe | ||
|
|
35fdcb0a1a | ||
|
|
6d26a9766c | ||
|
|
1cfaef9405 | ||
|
|
063e2092c8 | ||
|
|
cb215d26f3 | ||
|
|
8bbe80e683 | ||
|
|
9a0483446a | ||
|
|
f4561f9ba7 | ||
|
|
beaf89cb22 | ||
|
|
96b58c2860 | ||
|
|
8873da4a30 | ||
|
|
1362850986 | ||
|
|
98a4391677 | ||
|
|
036a956473 | ||
|
|
b381fa198f | ||
|
|
8ca2e9fe8d | ||
|
|
bc1d73a307 | ||
|
|
9679cd5c4e | ||
|
|
00817df9e2 | ||
|
|
ec189bf388 | ||
|
|
58bdce5707 | ||
|
|
8262b6e64b | ||
|
|
72fe0bf47f | ||
|
|
137078602b | ||
|
|
8fa21dd165 | ||
|
|
da70389546 | ||
|
|
cc1525707a | ||
|
|
b3aee43c3b | ||
|
|
932c1aa91e | ||
|
|
76ee05420d | ||
|
|
a470bc2976 | ||
|
|
cf725dd4db | ||
|
|
317ac0810e | ||
|
|
cb6018ef04 | ||
|
|
580fcdde4c | ||
|
|
ad4f44644c | ||
|
|
0c8a9d34a6 | ||
|
|
d067f32678 | ||
|
|
d251677774 | ||
|
|
b1780fbae5 | ||
|
|
e8cb962fcc | ||
|
|
1e84351d60 | ||
|
|
baa0402d5a | ||
|
|
c54d16c57e | ||
|
|
1adb75520f | ||
|
|
db51a9ff98 | ||
|
|
f044398c17 | ||
|
|
704652a0d2 | ||
|
|
6e3001194d | ||
|
|
d7774381cc | ||
|
|
1c8ec0a287 | ||
|
|
118e3a496c | ||
|
|
a139fb0b49 | ||
|
|
afdbb0a75c | ||
|
|
001a4254f8 | ||
|
|
2e72e70893 | ||
|
|
2907c40ecc | ||
|
|
2c67cee720 | ||
|
|
0ddbcb2010 | ||
|
|
40d4c6f554 | ||
|
|
bf88636487 | ||
|
|
a444b3bde8 | ||
|
|
4009f9d886 | ||
|
|
3f926c618a | ||
|
|
71d6670e7d | ||
|
|
08226e9199 | ||
|
|
d8de58d7f3 | ||
|
|
a1e402987b | ||
|
|
78e5cd56f3 | ||
|
|
462146b34e | ||
|
|
12e38da1a0 | ||
|
|
56a0ac5cbf | ||
|
|
d1aa1726f5 | ||
|
|
0f56a405c6 | ||
|
|
4948612cd4 | ||
|
|
6046e88eb1 | ||
|
|
77c45355ff | ||
|
|
3ff1414fc2 | ||
|
|
4e832b2cf4 | ||
|
|
5c1a5eab3a | ||
|
|
5d6f5bfde3 | ||
|
|
2b47d8e4cc | ||
|
|
bbadfb3cbd | ||
|
|
880a9e8eb5 | ||
|
|
5397031cee | ||
|
|
c4ede20a2d | ||
|
|
a135bd6268 | ||
|
|
0a3333474a | ||
|
|
d854e23e9a | ||
|
|
1bc672afd3 | ||
|
|
14d3b79387 | ||
|
|
facc64bb3a | ||
|
|
f9cdb93b87 | ||
|
|
2dca99d0dc | ||
|
|
334d8e6506 | ||
|
|
8710bde5b2 | ||
|
|
3ba5c12211 | ||
|
|
b8d646ac98 | ||
|
|
ab9d128828 | ||
|
|
873f249bf0 | ||
|
|
5b42be9b4a | ||
|
|
b507ed90dd | ||
|
|
a25039ff54 | ||
|
|
6b905f2d18 | ||
|
|
d52fcf17a8 | ||
|
|
592a649b50 | ||
|
|
fa5fcbb264 | ||
|
|
9dc2785762 | ||
|
|
212e69b5a4 | ||
|
|
7fde67ef75 | ||
|
|
8a7e2fedbc | ||
|
|
3b2ca1b542 | ||
|
|
8a000b93b0 | ||
|
|
b6cd9dd3f3 | ||
|
|
a5155e23f2 | ||
|
|
3dd1ce4e1c | ||
|
|
71e7c3e17c | ||
|
|
cf179b9dfe | ||
|
|
9f3ffdd26d | ||
|
|
7c1168fbc6 | ||
|
|
af31b96199 | ||
|
|
9400270e34 | ||
|
|
bcbbc57854 | ||
|
|
b792db72fd | ||
|
|
84c9a34f92 | ||
|
|
c11a7de949 | ||
|
|
f68a6bc362 | ||
|
|
7ea8c2e43c | ||
|
|
2adb64b949 | ||
|
|
9a38ebd15e | ||
|
|
4977fd64b1 | ||
|
|
ae77077853 | ||
|
|
007d8f5dad | ||
|
|
b3024e780d | ||
|
|
ebf4b930b7 | ||
|
|
fd25f4bf81 | ||
|
|
3fed5f9a25 | ||
|
|
7849831e12 | ||
|
|
42e9c5ffcb | ||
|
|
fb16bd9ee1 | ||
|
|
2c986abf5e | ||
|
|
667e6491ac | ||
|
|
1d3e887fca | ||
|
|
63cc934cd4 | ||
|
|
edfe0a944a | ||
|
|
25edd9be21 | ||
|
|
daaadaa1f9 | ||
|
|
9443a433fc | ||
|
|
b2776cadf7 | ||
|
|
1337b7ffd5 | ||
|
|
efe59cb91c | ||
|
|
13fa672d9e | ||
|
|
85ec990aa4 | ||
|
|
6929f1b798 | ||
|
|
63519dd89c | ||
|
|
2b052430bd | ||
|
|
7b8560016e | ||
|
|
886bc16fd4 | ||
|
|
4ea79f3634 | ||
|
|
5d883447a3 | ||
|
|
00fab37e58 | ||
|
|
328c34ab8b | ||
|
|
d29fb8ad05 | ||
|
|
c2abb24c26 | ||
|
|
8c4a1e5a5e | ||
|
|
ff3c85d380 | ||
|
|
2c63511af6 | ||
|
|
9517987b7b | ||
|
|
129eb89c20 | ||
|
|
e8ca201198 | ||
|
|
b87a504d22 | ||
|
|
076f9e293f | ||
|
|
6c4a2a8d44 | ||
|
|
1a83005a44 | ||
|
|
74d5f0f9a6 | ||
|
|
50c0d54dd5 | ||
|
|
377f7db0ad | ||
|
|
3b112ffb46 | ||
|
|
a192eed093 | ||
|
|
18cd73f55a | ||
|
|
4ed667da88 | ||
|
|
5d866fd8a1 | ||
|
|
ddf9a060ba | ||
|
|
8e437f89fa | ||
|
|
9ce4632f47 | ||
|
|
baa78fc4da | ||
|
|
2bf448f285 | ||
|
|
462468f3d8 | ||
|
|
6bae8bc6e6 | ||
|
|
3152f5f0ea | ||
|
|
c7ebfeb4bc | ||
|
|
d1c27f2d2b | ||
|
|
92599ad497 | ||
|
|
a118599233 | ||
|
|
2f44aab2b5 | ||
|
|
0488abf083 | ||
|
|
d2ffd04aed | ||
|
|
ee7782b551 | ||
|
|
2378d8bdca | ||
|
|
3218da8cbd | ||
|
|
eb330ac1c1 | ||
|
|
641b343c7f | ||
|
|
0601a4157d | ||
|
|
62e80b82ac | ||
|
|
a352521c15 | ||
|
|
8697fc0233 | ||
|
|
fe0cefd1dc | ||
|
|
4d364885e9 | ||
|
|
535cb2a91b | ||
|
|
8e845caeeb | ||
|
|
9e2a535044 | ||
|
|
857aad66fc | ||
|
|
b860edd8f5 | ||
|
|
ca86f6e64d | ||
|
|
d002b8afbf | ||
|
|
c613005f69 | ||
|
|
99415f1da1 | ||
|
|
656b9c6c89 | ||
|
|
d34f050642 | ||
|
|
89f4242e6f | ||
|
|
f7d4da9b1d | ||
|
|
1034313ac2 | ||
|
|
a6d9550a9a | ||
|
|
fd1bb5b4b2 | ||
|
|
8c581e4855 | ||
|
|
bf2a67b85b | ||
|
|
d3a2012750 | ||
|
|
0b00edc526 | ||
|
|
fa98266914 | ||
|
|
d7e0dedf74 | ||
|
|
f90a94be2e | ||
|
|
5206b6cbbb | ||
|
|
58aacc788d | ||
|
|
0343db7d95 | ||
|
|
7076b4da0c | ||
|
|
e17e7d712f | ||
|
|
399d2efa59 | ||
|
|
300426ed41 | ||
|
|
20066174e5 | ||
|
|
413db5a1e5 | ||
|
|
9855927597 | ||
|
|
72bff07498 | ||
|
|
409ff28200 | ||
|
|
5d2616093d | ||
|
|
74ba99479c | ||
|
|
0e8ec18c20 | ||
|
|
7ca52da776 | ||
|
|
2dfadfe1b1 | ||
|
|
8b39478913 | ||
|
|
2c0eaa1059 | ||
|
|
4804d51de4 | ||
|
|
097af2a38a | ||
|
|
9cc6d2d325 | ||
|
|
b4f30b5ad6 | ||
|
|
abb881c1a6 | ||
|
|
6448fc7ea1 | ||
|
|
98ba121b5c | ||
|
|
f50216eebf | ||
|
|
21a3584513 | ||
|
|
091559433a | ||
|
|
b15a7ea005 | ||
|
|
451b4b25d1 | ||
|
|
4879ed38c8 | ||
|
|
096b9a5b99 | ||
|
|
5467fbf7c2 | ||
|
|
6e87237070 | ||
|
|
796cc26fb9 | ||
|
|
174253715e | ||
|
|
8373a38b35 | ||
|
|
e608d8204f | ||
|
|
ddfbaa3127 | ||
|
|
b5bf082a95 | ||
|
|
d48614d72b | ||
|
|
b736499fc9 | ||
|
|
031a0296f9 | ||
|
|
84d7fb29e0 | ||
|
|
0af46f6416 | ||
|
|
a64874f27d | ||
|
|
e99fc921df | ||
|
|
0a7bf58905 | ||
|
|
334d0619e6 | ||
|
|
1190ed2931 | ||
|
|
ccf84d5653 | ||
|
|
8a905ce79a | ||
|
|
724d851dcd | ||
|
|
95d7204ae8 | ||
|
|
5aa6b6f959 | ||
|
|
fcb47f7226 | ||
|
|
f47f032b23 | ||
|
|
0b120f1748 | ||
|
|
13e857cf00 | ||
|
|
b867968a10 | ||
|
|
a95a818441 | ||
|
|
03430699f9 | ||
|
|
c7b4993721 | ||
|
|
d543be924f | ||
|
|
2ef9d69e01 | ||
|
|
3786017424 | ||
|
|
a6f738d2d1 | ||
|
|
1facc6b28b | ||
|
|
4414e15a00 | ||
|
|
49a8fd96d6 | ||
|
|
0a55b3b3a2 | ||
|
|
5f9c55d9f3 | ||
|
|
93c1b5f520 | ||
|
|
097614f2be | ||
|
|
eb170bc393 | ||
|
|
d002858169 | ||
|
|
646ac83bef | ||
|
|
9a9324af9a | ||
|
|
c2d0ed2365 | ||
|
|
89ca7226b9 | ||
|
|
5313f479a4 | ||
|
|
568a94c0e1 | ||
|
|
463a54fb58 | ||
|
|
d5f06eaf6f | ||
|
|
4255e63269 | ||
|
|
57975735b3 | ||
|
|
84d190a40c | ||
|
|
fd3135145a | ||
|
|
cff974555e | ||
|
|
14b6d104df | ||
|
|
d21ebc77cc | ||
|
|
95f2b54cc8 | ||
|
|
9f67fb9f5e | ||
|
|
3f99fde52d | ||
|
|
bfe11b3f8e | ||
|
|
52980a6aa7 | ||
|
|
8f72e49080 | ||
|
|
19c4e44e2c | ||
|
|
790baa615f | ||
|
|
bba43ecdf4 | ||
|
|
688d987765 | ||
|
|
8b92485b6a | ||
|
|
2a3c9c9164 | ||
|
|
5e3573cf84 | ||
|
|
4031a7f3df | ||
|
|
15cd445108 | ||
|
|
ed3186c506 | ||
|
|
157ed3af06 | ||
|
|
36a21717eb | ||
|
|
232916a8eb | ||
|
|
317cbd3fc4 | ||
|
|
1bfc67bed7 | ||
|
|
1c795e4a9f | ||
|
|
087dc939b2 | ||
|
|
86a13d0f87 | ||
|
|
21fc9afbdf | ||
|
|
0c2aae6bd2 | ||
|
|
a6aa9b7d3b | ||
|
|
29695055d2 | ||
|
|
00df1cbb04 | ||
|
|
49d5505efa | ||
|
|
1cf95972f3 | ||
|
|
047489b96e | ||
|
|
da498b091b | ||
|
|
2ea0f443f8 | ||
|
|
639318832b | ||
|
|
b9731ef9f3 | ||
|
|
b9475f14f3 | ||
|
|
587c61883b | ||
|
|
f866fe046f | ||
|
|
1876019faf | ||
|
|
185322fcd1 | ||
|
|
1dd6ff6ce5 | ||
|
|
9e79cb06d0 | ||
|
|
94131ff56b | ||
|
|
ec0add34ee | ||
|
|
6387513805 | ||
|
|
9ed9cd2592 | ||
|
|
5d6ad66618 | ||
|
|
6f7ca11ea9 | ||
|
|
51a108b5ab | ||
|
|
cfe18afcc9 | ||
|
|
39acd616a6 | ||
|
|
95a2ecc49b | ||
|
|
5c35af99d0 | ||
|
|
c68218a07e | ||
|
|
0539ec9d1f | ||
|
|
c4dce2752d | ||
|
|
474c8bc478 | ||
|
|
a5c833b80f | ||
|
|
a1e43f8e93 | ||
|
|
1d0747fbfe | ||
|
|
c3618652cd | ||
|
|
ca5596ceb2 | ||
|
|
f2e900171e | ||
|
|
1496888d92 | ||
|
|
058dc169f1 | ||
|
|
0d534346bf | ||
|
|
e73cc438e1 | ||
|
|
6a378a32f7 | ||
|
|
1534501a1d | ||
|
|
941700b9f8 | ||
|
|
4743701286 | ||
|
|
b58862d9f3 | ||
|
|
4b245dd5f1 | ||
|
|
f737782ae8 | ||
|
|
32bf9be5d1 | ||
|
|
f56eb2503e | ||
|
|
b1c0c1b00a | ||
|
|
4c88106d14 | ||
|
|
3d0b4cba65 | ||
|
|
f7fd508400 | ||
|
|
32b10b5335 | ||
|
|
5f981bf4d9 | ||
|
|
5634632944 | ||
|
|
fc62e6a0bc | ||
|
|
837772392c | ||
|
|
386fb2e15f | ||
|
|
ad59b39257 | ||
|
|
57966ce9ec | ||
|
|
1f692a043f | ||
|
|
ca6609571a | ||
|
|
6690bd678a | ||
|
|
1c489eff98 | ||
|
|
f1e067041e | ||
|
|
73d69172db | ||
|
|
8881b5c588 | ||
|
|
83d9868350 | ||
|
|
c9a3069297 | ||
|
|
8864762ff1 | ||
|
|
39a12db1d4 | ||
|
|
55fafd0a40 | ||
|
|
cc28a51c18 | ||
|
|
9938c1d2ad | ||
|
|
7f1e0ea36b | ||
|
|
51dba14fee | ||
|
|
78d70085cb | ||
|
|
e2cb82a7da | ||
|
|
78e1c2ceba | ||
|
|
898f2ba72c | ||
|
|
11f2a005e2 | ||
|
|
3ba7c1b8e2 | ||
|
|
3562bbf2ed | ||
|
|
408a9ad0ff | ||
|
|
0c4a156662 | ||
|
|
acf1ef6d90 | ||
|
|
766467ab78 | ||
|
|
0cec129cf0 | ||
|
|
65b48f6b4a | ||
|
|
752818e577 | ||
|
|
2e38e8998f | ||
|
|
7878df14be | ||
|
|
dc449c4fff | ||
|
|
afcd0d6e5a | ||
|
|
6b48881de7 | ||
|
|
10beacabc0 | ||
|
|
f180f0f5be | ||
|
|
f906a2978f | ||
|
|
e4949a7de7 | ||
|
|
4e41e9b34f | ||
|
|
e804a01e85 | ||
|
|
d0559e104d | ||
|
|
fa8b6e125c | ||
|
|
47295cd5f7 | ||
|
|
2d48c5dba7 | ||
|
|
13b847d1dc | ||
|
|
7e19c633a6 | ||
|
|
8df41a5683 | ||
|
|
59b652d0f2 | ||
|
|
76429548b6 | ||
|
|
23301bbd17 | ||
|
|
77b7d3733a | ||
|
|
63388fdee9 | ||
|
|
c06d5f0131 | ||
|
|
a151685a57 | ||
|
|
cbaa605e08 | ||
|
|
fb1dbfd084 | ||
|
|
fefd005c2c | ||
|
|
2c53eb10a8 | ||
|
|
d381f43e50 | ||
|
|
dc08d88c5c | ||
|
|
af562950a3 | ||
|
|
ee9568945a | ||
|
|
ea03d55d6a | ||
|
|
3f55c3022e | ||
|
|
a54e491d49 | ||
|
|
39766f4c0a | ||
|
|
4c03f899b9 | ||
|
|
1b5c592abb | ||
|
|
4679334d86 | ||
|
|
8d29796810 | ||
|
|
9cd6549cdc | ||
|
|
e4b5a8e0f9 | ||
|
|
a5cad09782 | ||
|
|
483cc0677f | ||
|
|
b2a1eb5b21 | ||
|
|
fa979cf0ab | ||
|
|
2a1542c465 | ||
|
|
e543aac6dd | ||
|
|
3ee6de3ed3 | ||
|
|
16848e9160 | ||
|
|
071feeadce | ||
|
|
9587439f8d | ||
|
|
a61a6c7144 | ||
|
|
6ae1dfdcb0 | ||
|
|
fc40438f35 | ||
|
|
730bbd246c | ||
|
|
656f639db5 | ||
|
|
663522bed8 | ||
|
|
324872303b | ||
|
|
651ed9d470 | ||
|
|
6aedf4874f | ||
|
|
d33c159a26 | ||
|
|
572ea32c0c | ||
|
|
3415c15365 | ||
|
|
2ed66bfffc | ||
|
|
c6591f609f | ||
|
|
ba7760f9ad | ||
|
|
3f05b107ed | ||
|
|
d4c6fd7426 | ||
|
|
6d8d4fdddb | ||
|
|
adec783d49 | ||
|
|
2cca69be00 | ||
|
|
894ee7f5f9 | ||
|
|
23085eaf8a | ||
|
|
4deb9597b2 | ||
|
|
392d769483 | ||
|
|
f088e16fe2 | ||
|
|
30cf394a7b | ||
|
|
beabf6810c | ||
|
|
dbd6104c8b | ||
|
|
2a5ce95472 | ||
|
|
77ae682120 | ||
|
|
4a0b3bd2cf | ||
|
|
a9aad6727c | ||
|
|
7c6668b58e | ||
|
|
385c26ad78 | ||
|
|
d57078a7ed | ||
|
|
7a5672bbcc | ||
|
|
e6f0a8f3f0 | ||
|
|
9975b63216 | ||
|
|
512edd0c9b | ||
|
|
f4850b870f |
@@ -0,0 +1,41 @@
|
||||
# see https://docs.codecov.io/docs/codecov-yaml
|
||||
# Validation check:
|
||||
# $ curl --data-binary @.codecov.yml https://codecov.io/validate
|
||||
|
||||
# https://docs.codecov.io/docs/codecovyml-reference
|
||||
codecov:
|
||||
bot: "codecov-io"
|
||||
strict_yaml_branch: "yaml-config"
|
||||
require_ci_to_pass: yes
|
||||
notify:
|
||||
# after_n_builds: 2
|
||||
wait_for_ci: yes
|
||||
|
||||
coverage:
|
||||
precision: 0 # 2 = xx.xx%, 0 = xx%
|
||||
round: nearest # how coverage is rounded: down/up/nearest
|
||||
range: 40...100 # custom range of coverage colors from red -> yellow -> green
|
||||
status:
|
||||
project:
|
||||
default:
|
||||
informational: true
|
||||
target: 95% # specify the target coverage for each commit status
|
||||
threshold: 10% # allow this little decrease on project
|
||||
# branches: master
|
||||
if_ci_failed: error
|
||||
patch:
|
||||
default:
|
||||
informational: true
|
||||
target: 95% # enforce same coverage target for new/changed code as the project
|
||||
threshold: 10% # allow only a small decrease on patch coverage
|
||||
changes: false
|
||||
|
||||
# https://docs.codecov.com/docs/github-checks#disabling-github-checks-patch-annotations
|
||||
github_checks:
|
||||
annotations: false
|
||||
|
||||
comment:
|
||||
layout: header, diff
|
||||
require_changes: false
|
||||
behavior: default # update if exists else create new
|
||||
# branches: *
|
||||
+1
-1
@@ -1,4 +1,4 @@
|
||||
# These owners will be the default owners for everything in
|
||||
# the repo. They will be requested for review when someone
|
||||
# opens a pull request.
|
||||
* @SkalskiP @onuralpszr
|
||||
* @SkalskiP @soumik12345
|
||||
|
||||
@@ -21,20 +21,20 @@ community include:
|
||||
- Being respectful of differing opinions, viewpoints, and experiences
|
||||
- Giving and gracefully accepting constructive feedback
|
||||
- Accepting responsibility and apologizing to those affected by our mistakes,
|
||||
and learning from the experience
|
||||
and learning from the experience
|
||||
- Focusing on what is best not just for us as individuals, but for the overall
|
||||
community
|
||||
community
|
||||
|
||||
Examples of unacceptable behavior include:
|
||||
|
||||
- The use of sexualized language or imagery, and sexual attention or advances of
|
||||
any kind
|
||||
any kind
|
||||
- Trolling, insulting or derogatory comments, and personal or political attacks
|
||||
- Public or private harassment
|
||||
- Publishing others' private information, such as a physical or email address,
|
||||
without their explicit permission
|
||||
without their explicit permission
|
||||
- Other conduct which could reasonably be considered inappropriate in a
|
||||
professional setting
|
||||
professional setting
|
||||
|
||||
## Enforcement Responsibilities
|
||||
|
||||
@@ -83,18 +83,20 @@ git push -u origin <your_branch_name>
|
||||
|
||||
Use conventional commit messages to clearly describe your changes. The format is:
|
||||
|
||||
<type>\[optional scope\]: <description>
|
||||
```
|
||||
<type>[optional scope]: <description>
|
||||
```
|
||||
|
||||
Common types include:
|
||||
|
||||
- feat: A new feature
|
||||
- fix: A bug fix
|
||||
- docs: Documentation only changes
|
||||
- style: Changes that do not affect the meaning of the code (white-space, formatting, etc)
|
||||
- refactor: A code change that neither fixes a bug nor adds a feature
|
||||
- perf: A code change that improves performance
|
||||
- test: Adding missing tests or correcting existing tests
|
||||
- chore: Changes to the build process or auxiliary tools and libraries
|
||||
- `feat`: A new feature
|
||||
- `fix`: A bug fix
|
||||
- `docs`: Documentation only changes
|
||||
- `style`: Changes that do not affect the meaning of the code (white-space, formatting, etc)
|
||||
- `refactor`: A code change that neither fixes a bug nor adds a feature
|
||||
- `perf`: A code change that improves performance
|
||||
- `test`: Adding missing tests or correcting existing tests
|
||||
- `chore`: Changes to the build process or auxiliary tools and libraries
|
||||
|
||||
Then, go back to your fork of the `supervision` repository, click "Pull Requests", and click "New Pull Request".
|
||||
|
||||
@@ -116,7 +118,7 @@ When creating new functions, please ensure you have the following:
|
||||
2. Unit tests for the function.
|
||||
3. Examples in the documentation for the function.
|
||||
4. Created an entry in our docs to autogenerate the documentation for the function.
|
||||
5. Please share a Google Colab with minimal code to test new feature or reproduce PR whenever it is possible. Please ensure that Google Colab can be accessed without any issue.
|
||||
5. Please share a Google Colab with minimal code to test a new feature or reproduce the issue whenever possible. Please ensure that Google Colab can be accessed without any restrictions.
|
||||
|
||||
When you submit your Pull Request, you will be asked to sign a Contributor License Agreement (CLA) by the `cla-assistant` GitHub bot. We can only respond to PRs from contributors who have signed the project CLA.
|
||||
|
||||
@@ -128,7 +130,7 @@ PRs must pass all tests and linting requirements before they can be merged.
|
||||
|
||||
Before starting your work on the project, set up your development environment:
|
||||
|
||||
1. Clone your fork of the project (recommended to use shallow clone of develop branch):
|
||||
1. **Clone your fork of the project:**
|
||||
|
||||
**Option A: Recommended for most contributors (shallow clone of develop branch):**
|
||||
|
||||
@@ -139,47 +141,53 @@ Before starting your work on the project, set up your development environment:
|
||||
|
||||
Replace `YOUR_USERNAME` with your GitHub username.
|
||||
|
||||
> Note: Using `--depth 1` creates a shallow clone with minimal history and `-b develop` ensures you start with the development branch. This significantly reduces download size while providing everything needed to contribute.
|
||||
> **Note**: Using `--depth 1` creates a shallow clone with minimal history and `-b develop` ensures you start with the development branch. This significantly reduces download size while providing everything needed to contribute.
|
||||
|
||||
**Option B: Full repository clone (if you need complete history):**
|
||||
|
||||
```bash
|
||||
git clone https://github.com/YOUR_USERNAME/supervision.git
|
||||
cd supervision
|
||||
git checkout develop
|
||||
```
|
||||
|
||||
2. Create and activate a virtual environment:
|
||||
2. **Set up the upstream remote:**
|
||||
|
||||
```bash
|
||||
git remote add upstream https://github.com/roboflow/supervision.git
|
||||
git fetch upstream
|
||||
```
|
||||
|
||||
3. **Create and activate a virtual environment:**
|
||||
|
||||
**On Linux/macOS:**
|
||||
|
||||
```bash
|
||||
python3 -m venv .venv
|
||||
source .venv/bin/activate
|
||||
```
|
||||
|
||||
3. Install Poetry:
|
||||
**On Windows:**
|
||||
|
||||
Using pip:
|
||||
|
||||
```bash
|
||||
pip install -U pip setuptools
|
||||
pip install poetry
|
||||
```cmd
|
||||
python -m venv .venv
|
||||
.venv\Scripts\activate
|
||||
```
|
||||
|
||||
Or using pipx (recommended for global installation):
|
||||
4. **Install `uv`:**
|
||||
|
||||
Follow the instructions on the [uv installation page](https://docs.astral.sh/uv/getting-started/installation/).
|
||||
|
||||
5. **Install project dependencies:**
|
||||
|
||||
```bash
|
||||
pipx install poetry
|
||||
uv pip install -r pyproject.toml --group dev --group docs --extra metrics
|
||||
```
|
||||
|
||||
4. Install project dependencies:
|
||||
6. **Verify the setup:**
|
||||
|
||||
```bash
|
||||
poetry install
|
||||
```
|
||||
|
||||
5. Run pytest to verify the setup:
|
||||
|
||||
```bash
|
||||
poetry run pytest
|
||||
uv run pytest
|
||||
```
|
||||
|
||||
## 🎨 Code Style and Quality
|
||||
@@ -192,13 +200,29 @@ Furthermore, we have integrated a pre-commit GitHub Action into our workflow. Th
|
||||
|
||||
To run the pre-commit tool, follow these steps:
|
||||
|
||||
1. Install pre-commit by running the following command: `poetry install --with dev`. It will not only install pre-commit but also install all the deps and dev-deps of project
|
||||
1. **Install pre-commit** (already included if you followed the installation steps above):
|
||||
|
||||
2. Once pre-commit is installed, navigate to the project's root directory.
|
||||
```bash
|
||||
uv sync --group dev
|
||||
```
|
||||
|
||||
3. Run the command `pre-commit run --all-files`. This will execute the pre-commit hooks configured for this project against the modified files. If any issues are found, the pre-commit tool will provide feedback on how to resolve them. Make the necessary changes and re-run the pre-commit command until all issues are resolved.
|
||||
2. **Navigate to the project's root directory** (if not already there).
|
||||
|
||||
4. You can also install pre-commit as a git hook by executing `pre-commit install`. Every time you do a `git commit` pre-commit run automatically for you.
|
||||
3. **Run pre-commit checks**:
|
||||
|
||||
```bash
|
||||
uv run pre-commit run --all-files
|
||||
```
|
||||
|
||||
This will execute the pre-commit hooks configured for this project. If any issues are found, the pre-commit tool will provide feedback on how to resolve them. Make the necessary changes and re-run the command until all issues are resolved.
|
||||
|
||||
4. **Install pre-commit as a git hook** (optional but recommended):
|
||||
|
||||
```bash
|
||||
uv run pre-commit install
|
||||
```
|
||||
|
||||
This will automatically run pre-commit checks every time you make a `git commit`.
|
||||
|
||||
### Docstrings
|
||||
|
||||
@@ -208,13 +232,27 @@ All new functions and classes in `supervision` should include docstrings. This i
|
||||
|
||||
### Type checking
|
||||
|
||||
So far, **there is no type checking with mypy**. See [issue](https://github.com/roboflow-ai/template-python/issues/4).
|
||||
Currently, there is no systematic type checking with mypy implemented in the project. This is a known limitation that may be addressed in future updates.
|
||||
|
||||
## 📝 Documentation
|
||||
|
||||
The `supervision` documentation is stored in a folder called `docs`. The project documentation is built using `mkdocs`.
|
||||
|
||||
To run the documentation, install the project requirements with `poetry install --with dev`. Then, run `mkdocs serve` to start the documentation server.
|
||||
To run the documentation locally:
|
||||
|
||||
1. **Install documentation dependencies** (if not already installed):
|
||||
|
||||
```bash
|
||||
uv sync --group docs
|
||||
```
|
||||
|
||||
2. **Start the documentation server**:
|
||||
|
||||
```bash
|
||||
uv run mkdocs serve
|
||||
```
|
||||
|
||||
3. **Access the documentation** at `http://127.0.0.1:8000` in your browser.
|
||||
|
||||
You can learn more about mkdocs on the [mkdocs website](https://www.mkdocs.org/).
|
||||
|
||||
@@ -227,15 +265,121 @@ submit a PR with your example. Here are some guidelines for submitting a new exa
|
||||
- Create a new notebook in the [`docs/notebooks`](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.
|
||||
- Pin the version of `supervision` you are using in the notebook.
|
||||
- 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.
|
||||
[`pytest`](https://docs.pytest.org/en/7.1.x/) is used to run our tests.
|
||||
|
||||
To run tests:
|
||||
|
||||
```bash
|
||||
uv run pytest
|
||||
```
|
||||
|
||||
To run tests with coverage:
|
||||
|
||||
```bash
|
||||
uv run pytest --cov=supervision
|
||||
```
|
||||
|
||||
## 🔍 PR Review Guidelines
|
||||
|
||||
These guidelines help reviewers provide consistent, actionable feedback efficiently. Your goals: validate completeness, identify risks, provide actionable feedback, and highlight quality gaps.
|
||||
|
||||
### Overall Recommendation
|
||||
|
||||
Start with a clear recommendation using these levels:
|
||||
|
||||
- 🟢 **Approve** — Ready to merge
|
||||
- 🟡 **Minor Suggestions** — Improvements recommended but not blocking
|
||||
- 🟠 **Request Changes** — Must address issues before merge
|
||||
- 🔴 **Block** — Critical issues require major rework
|
||||
|
||||
Example: `🟠 Request Changes — Missing unit tests for PolygonMerger and no mkdocs entry.`
|
||||
|
||||
### PR Completeness
|
||||
|
||||
Verify requirements are met (✅ Complete / ⚠️ Incomplete / ❌ Missing / 🔵 N/A):
|
||||
|
||||
- [ ] Clear description of what changed and why
|
||||
- [ ] Tests added/updated for new functionality or bug fixes
|
||||
- [ ] Docstrings follow [Google-style](https://google.github.io/styleguide/pyguide.html#383-functions-and-methods)
|
||||
- [ ] Docs entry added to mkdocs (new functions/classes only)
|
||||
- [ ] Google Colab provided (if demonstrating feature/fix)
|
||||
- [ ] Screenshots/videos included (visual changes only)
|
||||
|
||||
Call out missing items explicitly in your review.
|
||||
|
||||
### Quality Scores
|
||||
|
||||
Use **n/5 scoring** with inline code comments for specifics:
|
||||
|
||||
**Code Quality (n/5):**
|
||||
|
||||
- 5/5 🟢 Excellent — 4/5 🟢 Good — 3/5 🟡 Acceptable — 2/5 🟠 Needs Work — 1/5 🔴 Poor
|
||||
- Check: correctness (edge cases, None checks, bounds), Python best practices (idiomatic patterns, error handling, type hints), project conventions (docstrings, linting, import order, PEP 8 naming)
|
||||
|
||||
**Testing (n/5):**
|
||||
|
||||
- 5/5 🟢 Comprehensive — 4/5 🟢 Good — 3/5 🟡 Adequate — 2/5 🟠 Insufficient — 1/5 🔴 Missing
|
||||
- Verify: unit tests for new code, edge cases covered, specific assertions, realistic scenarios, clear test names
|
||||
|
||||
**Documentation (n/5):**
|
||||
|
||||
- 5/5 🟢 Excellent — 4/5 🟢 Good — 3/5 🟡 Adequate — 2/5 🟠 Insufficient — 1/5 🔴 Missing
|
||||
- Confirm: docstrings for public functions/classes, parameters/returns/exceptions documented, usage examples, mkdocs integration, changelog entry for user-facing changes
|
||||
|
||||
### Risk Assessment
|
||||
|
||||
Flag risks with severity (5/5 🔴 Critical — 4/5 🟠 High — 3/5 🟡 Medium — 2/5 🟢 Low — 1/5 🟢 Negligible):
|
||||
|
||||
**Common risk categories:**
|
||||
|
||||
1. **Breaking changes** — API changes, removed features, behavior modifications (must include migration guide)
|
||||
2. **Performance** — Inefficient algorithms, memory-intensive operations, bottlenecks
|
||||
3. **Compatibility** — New Python/dependency requirements, platform-specific code
|
||||
4. **Security** — Unvalidated input, code execution risks, data exposure
|
||||
|
||||
### Review Summary Template
|
||||
|
||||
```markdown
|
||||
## Review Summary
|
||||
|
||||
**Recommendation:** [emoji] [Status] — [justification]
|
||||
|
||||
**PR Completeness:**
|
||||
- ✅ Complete: [items]
|
||||
- ❌ Missing: [gaps]
|
||||
|
||||
**Quality Scores:**
|
||||
- Code: n/5 [emoji] — [reason]
|
||||
- Testing: n/5 [emoji] — [reason]
|
||||
- Documentation: n/5 [emoji] — [reason]
|
||||
|
||||
**Risk Level:** n/5 [emoji] — [description]
|
||||
|
||||
**Critical Issues (Must Fix):**
|
||||
1. [Issue] — See comment on `file.py`
|
||||
|
||||
**Suggestions (Optional):**
|
||||
1. [Improvement] — See suggestion on `file.py`
|
||||
|
||||
**Next Steps:**
|
||||
1. [Action item]
|
||||
```
|
||||
|
||||
### Review Best Practices
|
||||
|
||||
**DO:** Use inline GitHub comments with suggestions, explain *why* (not just *what*), distinguish blocking vs. nice-to-have, acknowledge good work, run linter if needed (`uv run pre-commit run --all-files`)
|
||||
|
||||
**DON'T:** Mention line numbers in summary (use inline comments), give vague feedback, nitpick style (defer to tools), assume knowledge of conventions, block on minor issues
|
||||
|
||||
**Tone:** Be respectful, specific, pragmatic, and consistent. Focus on actionable feedback that moves PRs toward merge.
|
||||
|
||||
## 📄 License
|
||||
|
||||
By contributing, you agree that your contributions will be licensed under an [MIT license](https://github.com/roboflow/supervision/blob/develop/LICENSE.md).
|
||||
By contributing, you agree that your contributions will be licensed under an [MIT license](../LICENSE.md).
|
||||
@@ -1,65 +1,68 @@
|
||||
name: 🐞 Bug Report
|
||||
# title: " "
|
||||
description: Problems with Supervision
|
||||
title: "[Bug]: "
|
||||
description: Report a bug or unexpected behavior in Supervision
|
||||
labels: [bug]
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
Thank you for submitting a Supervision 🐞 Bug Report!
|
||||
|
||||
- type: checkboxes
|
||||
attributes:
|
||||
label: Search before asking
|
||||
description: >
|
||||
Please search the [issues](https://github.com/roboflow/supervision/issues) to see if a similar bug report already exists.
|
||||
description: Please search [issues](https://github.com/roboflow/supervision/issues) and [discussions](https://github.com/roboflow/supervision/discussions) first.
|
||||
options:
|
||||
- label: >
|
||||
I have searched the Supervision [issues](https://github.com/roboflow/supervision/issues) and found no similar bug report.
|
||||
- label: I have searched the issues and discussions and found no similar bug report.
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Bug
|
||||
description: Provide console output with error messages and/or screenshots of the bug.
|
||||
description: Describe the bug, what you expected, and what actually happened.
|
||||
placeholder: |
|
||||
💡 ProTip! Include as much information as possible (screenshots, logs, tracebacks etc.) to receive the most helpful response.
|
||||
**What's the bug?**
|
||||
Brief description...
|
||||
|
||||
**Expected behavior:**
|
||||
What should happen...
|
||||
|
||||
**Actual behavior:**
|
||||
What actually happens...
|
||||
|
||||
**Error/Traceback (if any):**
|
||||
```python
|
||||
# Paste error messages here
|
||||
```
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Environment
|
||||
description: Please specify the software and hardware you used to produce the bug.
|
||||
description: Your setup details
|
||||
placeholder: |
|
||||
- Supervision: 0.1.0
|
||||
- OS: Ubuntu 20.04
|
||||
- Python: 3.8.10
|
||||
- Supervision: 0.23.0
|
||||
- Python: 3.10.12
|
||||
- OS: Ubuntu 22.04
|
||||
value: |
|
||||
- Supervision:
|
||||
- Python:
|
||||
- OS:
|
||||
validations:
|
||||
required: false
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Minimal Reproducible Example
|
||||
description: >
|
||||
When asking a question, people will be better able to provide help if you provide code that they can easily understand and use to **reproduce** the problem.
|
||||
This is referred to by community members as creating a [minimal reproducible example](https://stackoverflow.com/help/minimal-reproducible-example).
|
||||
description: Code to reproduce the bug ([guide](https://stackoverflow.com/help/minimal-reproducible-example))
|
||||
placeholder: |
|
||||
```
|
||||
# Code to reproduce your issue here
|
||||
```python
|
||||
import supervision as sv
|
||||
|
||||
# Your code here
|
||||
```
|
||||
validations:
|
||||
required: false
|
||||
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Additional
|
||||
description: Anything else you would like to share?
|
||||
|
||||
- type: checkboxes
|
||||
attributes:
|
||||
label: Are you willing to submit a PR?
|
||||
description: >
|
||||
(Optional) We encourage you to submit a [Pull Request](https://github.com/roboflow/supervision/pulls) (PR) to help improve Supervision for everyone, especially if you have a good understanding of how to implement a fix or feature.
|
||||
description: (Optional) We encourage community contributions!
|
||||
options:
|
||||
- label: Yes I'd like to help by submitting a PR!
|
||||
|
||||
@@ -0,0 +1,17 @@
|
||||
blank_issues_enabled: false
|
||||
contact_links:
|
||||
- name: ❓ Ask a Question
|
||||
url: https://github.com/roboflow/supervision/discussions/new?category=q-a
|
||||
about: Ask questions about using Supervision in GitHub Discussions
|
||||
- name: 📚 Documentation
|
||||
url: https://supervision.roboflow.com/
|
||||
about: Check the official Supervision documentation for guides and API references
|
||||
- name: 💬 GitHub Discussions
|
||||
url: https://github.com/roboflow/supervision/discussions
|
||||
about: Join community discussions, share ideas, and get help
|
||||
- name: 🌟 Show and Tell
|
||||
url: https://github.com/roboflow/supervision/discussions/categories/show-and-tell
|
||||
about: Share your projects and creations built with Supervision
|
||||
- name: 🗣️ Roboflow Discord
|
||||
url: https://discord.com/invite/GbfgXGJ8Bk
|
||||
about: Join our Discord to collaborate with other community members
|
||||
@@ -1,6 +1,6 @@
|
||||
name: 🤩 Feature Request
|
||||
description: Suggest a Supervision idea
|
||||
# title: " "
|
||||
title: "[Feature]: "
|
||||
description: Suggest a new feature or improvement
|
||||
labels: [enhancement]
|
||||
body:
|
||||
- type: markdown
|
||||
@@ -11,39 +11,40 @@ body:
|
||||
- type: checkboxes
|
||||
attributes:
|
||||
label: Search before asking
|
||||
description: >
|
||||
Please search the [issues](https://github.com/roboflow/supervision/issues) to see if a similar feature request already exists.
|
||||
description: Please search [issues](https://github.com/roboflow/supervision/issues) and [discussions](https://github.com/roboflow/supervision/discussions) first.
|
||||
options:
|
||||
- label: >
|
||||
I have searched the Supervision [issues](https://github.com/roboflow/supervision/issues) and found no similar feature requests.
|
||||
- label: I have searched the issues and discussions and found no similar feature request.
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Description
|
||||
description: A short description of your feature.
|
||||
label: Feature Description
|
||||
description: What feature would you like and why?
|
||||
placeholder: |
|
||||
What new feature would you like to see in Supervision?
|
||||
**What:** Describe the feature...
|
||||
|
||||
**Why:** What problem does it solve? Who would benefit?
|
||||
|
||||
**How (optional):** Any ideas on implementation?
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Use case
|
||||
description: |
|
||||
Describe the use case of your feature request. It will help us understand and prioritize the feature request.
|
||||
label: Example Usage
|
||||
description: (Optional) Show how you'd like to use this feature
|
||||
placeholder: |
|
||||
How would this feature be used, and who would use it?
|
||||
```python
|
||||
import supervision as sv
|
||||
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Additional
|
||||
description: Anything else you would like to share?
|
||||
# Your example usage here
|
||||
```
|
||||
validations:
|
||||
required: false
|
||||
|
||||
- type: checkboxes
|
||||
attributes:
|
||||
label: Are you willing to submit a PR?
|
||||
description: >
|
||||
(Optional) We encourage you to submit a [Pull Request](https://github.com/roboflow/supervision/pulls) (PR) to help improve Supervision for everyone, especially if you have a good understanding of how to implement a fix or feature.
|
||||
description: (Optional) We encourage community contributions!
|
||||
options:
|
||||
- label: Yes I'd like to help by submitting a PR!
|
||||
|
||||
@@ -1,33 +0,0 @@
|
||||
name: ❓ Question
|
||||
description: Ask a Supervision question
|
||||
# title: " "
|
||||
labels: [question]
|
||||
body:
|
||||
- type: markdown
|
||||
attributes:
|
||||
value: |
|
||||
Thank you for asking a Supervision ❓ Question!
|
||||
|
||||
- type: checkboxes
|
||||
attributes:
|
||||
label: Search before asking
|
||||
description: >
|
||||
Please search the [issues](https://github.com/roboflow/supervision/issues) to see if a similar feature request already exists.
|
||||
options:
|
||||
- label: >
|
||||
I have searched the Supervision [issues](https://github.com/roboflow/supervision/issues) and found no similar feature requests.
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Question
|
||||
description: What is your question?
|
||||
placeholder: |
|
||||
💡 ProTip! Include as much information as possible (screenshots, logs, tracebacks etc.) to receive the most helpful response.
|
||||
validations:
|
||||
required: true
|
||||
|
||||
- type: textarea
|
||||
attributes:
|
||||
label: Additional
|
||||
description: Anything else you would like to share?
|
||||
@@ -0,0 +1,67 @@
|
||||
<details>
|
||||
<summary>Before submitting</summary>
|
||||
|
||||
- [ ] Self-reviewed the code
|
||||
- [ ] Updated documentation, follow [Google-style](https://google.github.io/styleguide/pyguide.html#383-functions-and-methods)
|
||||
- [ ] Added docs entry for autogeneration (if new functions/classes)
|
||||
- [ ] Added/updated tests
|
||||
- [ ] All tests pass locally
|
||||
|
||||
</details>
|
||||
|
||||
## Description
|
||||
|
||||
<!-- Provide a clear and concise description of your changes -->
|
||||
|
||||
## Type of Change
|
||||
|
||||
<!-- Mark the relevant option with an "x" and delete the others -->
|
||||
|
||||
- 🐛 Bug fix (non-breaking change which fixes an issue)
|
||||
- ✨ New feature (non-breaking change which adds functionality)
|
||||
- 💥 Breaking change (fix or feature that would cause existing functionality to not work as expected)
|
||||
- 📝 Documentation update
|
||||
- 🧪 Test update
|
||||
- 🔨 Refactoring (no functional changes)
|
||||
- ⚡ Performance improvement
|
||||
- 🔧 Chore (dependencies, configs, etc.)
|
||||
|
||||
## Motivation and Context
|
||||
|
||||
<!-- Why is this change required? What problem does it solve? -->
|
||||
|
||||
<!-- If it fixes an open issue, please link to the issue here -->
|
||||
|
||||
Closes #(issue)
|
||||
|
||||
## Changes Made
|
||||
|
||||
<!-- List the main changes made in this PR -->
|
||||
|
||||
-
|
||||
-
|
||||
-
|
||||
|
||||
## Testing
|
||||
|
||||
<!-- Describe the tests you ran and how to reproduce them -->
|
||||
|
||||
- [ ] I have tested this code locally
|
||||
- [ ] I have added unit tests that prove my fix is effective or that my feature works
|
||||
- [ ] All new and existing tests pass
|
||||
|
||||
## Google Colab (optional)
|
||||
|
||||
<!-- If applicable, provide a link to a Google Colab notebook demonstrating the feature/fix -->
|
||||
|
||||
<!-- Ensure the notebook is publicly accessible -->
|
||||
|
||||
Colab link:
|
||||
|
||||
## Screenshots/Videos (optional)
|
||||
|
||||
<!-- If applicable, add screenshots or videos to demonstrate the changes -->
|
||||
|
||||
## Additional Notes
|
||||
|
||||
<!-- Any additional information that reviewers should know -->
|
||||
@@ -0,0 +1,146 @@
|
||||
# GitHub Copilot Instructions for Supervision
|
||||
|
||||
This file provides context-aware guidance for GitHub Copilot when working in the Supervision repository.
|
||||
|
||||
---
|
||||
|
||||
## 📚 Repository Overview
|
||||
|
||||
**Supervision** is a Python library providing reusable computer vision utilities for working with object detection models (YOLO, SAM, etc.). It offers tools for detections processing, tracking, annotation, and dataset management.
|
||||
|
||||
- **Languages**: Python 3.9+
|
||||
- **Key Dependencies**: NumPy, OpenCV, SciPy
|
||||
- **License**: MIT
|
||||
|
||||
---
|
||||
|
||||
## 🏗️ Project Structure
|
||||
|
||||
```
|
||||
supervision/
|
||||
├── src/
|
||||
│ └── supervision/ # Main library code
|
||||
│ ├── detection/ # Detection utilities
|
||||
│ ├── draw/ # Annotation and visualization
|
||||
│ ├── tracker/ # Object tracking
|
||||
│ ├── dataset/ # Dataset management
|
||||
│ └── utils/ # Shared utilities
|
||||
├── tests/ # Test suite (mirrors src/supervision/)
|
||||
├── docs/ # MkDocs documentation
|
||||
└── examples/ # Usage examples
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 🔧 Development Commands
|
||||
|
||||
**Setup:**
|
||||
|
||||
```bash
|
||||
# Install dependencies
|
||||
uv sync --group dev --group docs --extra metrics
|
||||
|
||||
# Install pre-commit hooks
|
||||
uv run pre-commit install
|
||||
```
|
||||
|
||||
**Quality Checks:**
|
||||
|
||||
```bash
|
||||
# Run all pre-commit hooks (formatting, linting, type checking)
|
||||
uv run pre-commit run --all-files
|
||||
|
||||
# Run tests with coverage
|
||||
uv run pytest --cov=supervision
|
||||
```
|
||||
|
||||
**Documentation:**
|
||||
|
||||
```bash
|
||||
# Serve docs locally at http://127.0.0.1:8000
|
||||
uv run mkdocs serve
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 💻 Code Conventions
|
||||
|
||||
### General Guidelines
|
||||
|
||||
- Follow **[AGENTS.md](../AGENTS.md)** for task-based development workflows
|
||||
- Reference **[CONTRIBUTING.md](CONTRIBUTING.md)** for detailed contribution guidelines
|
||||
- All code must pass `pre-commit` hooks before committing
|
||||
|
||||
### Code Style
|
||||
|
||||
- **Formatting**: Enforced by `ruff-format`, `prettier` (pre-commit)
|
||||
- **Linting**: Enforced by `ruff-check` (pre-commit)
|
||||
- **Type Hints**: Required on all new code
|
||||
- **Docstrings**: Required using [Google Python style](https://google.github.io/styleguide/pyguide.html#383-functions-and-methods)
|
||||
- Must include usage examples with primitive values
|
||||
- Serve as runnable documentation
|
||||
|
||||
### Performance
|
||||
|
||||
- Avoid unnecessary NumPy array copies
|
||||
- Prefer vectorized operations over Python loops
|
||||
- Use OpenCV operations efficiently
|
||||
|
||||
### API Design
|
||||
|
||||
- Follow existing naming patterns for consistency
|
||||
- Maintain backward compatibility unless explicitly breaking
|
||||
- Prefer functional utilities over complex classes
|
||||
|
||||
---
|
||||
|
||||
## 🧪 Testing Requirements
|
||||
|
||||
All new features must include:
|
||||
|
||||
- Unit tests covering happy path and edge cases
|
||||
- Tests for `None`, empty inputs, large arrays, boundary conditions
|
||||
- Clear test names describing what they validate
|
||||
- Proper assertions (not just "no exception raised")
|
||||
|
||||
---
|
||||
|
||||
## 📝 Documentation Requirements
|
||||
|
||||
For new public functions/classes:
|
||||
|
||||
- Google-style docstrings with parameters, returns, exceptions
|
||||
- Usage examples in docstrings
|
||||
- Entry in appropriate `docs/*.md` file
|
||||
- Reference in `mkdocs.yml` navigation
|
||||
|
||||
---
|
||||
|
||||
## 🔍 Pull Request Reviews
|
||||
|
||||
**When reviewing PRs, follow the comprehensive [PR Review Guidelines](CONTRIBUTING.md#pr-review-guidelines).**
|
||||
|
||||
Quick checklist:
|
||||
|
||||
- Tests included and passing
|
||||
- Docstrings follow Google style with examples
|
||||
- Pre-commit hooks pass
|
||||
- Breaking changes documented
|
||||
- Score code quality, testing, docs (n/5 scale)
|
||||
- Use inline comments + GitHub suggestion format
|
||||
|
||||
---
|
||||
|
||||
## 🌿 Branching & Commits
|
||||
|
||||
- Branch from `develop` using prefixes: `feat/`, `fix/`, `docs/`, `refactor/`, `perf/`, `test/`, `chore/`
|
||||
- Use **conventional commits**: `feat:`, `fix:`, `docs:`, `refactor:`, `perf:`, `test:`, `chore:`
|
||||
- All PRs target `develop` branch
|
||||
|
||||
---
|
||||
|
||||
## 🎯 Context-Aware Behavior
|
||||
|
||||
**For general development tasks**: Follow [AGENTS.md](../AGENTS.md)
|
||||
**For pull request reviews**: Follow [PR Review Guidelines](CONTRIBUTING.md#pr-review-guidelines)
|
||||
**For detailed processes**: Consult [CONTRIBUTING.md](CONTRIBUTING.md)
|
||||
@@ -8,6 +8,10 @@ updates:
|
||||
commit-message:
|
||||
prefix: ⬆️
|
||||
target-branch: "develop"
|
||||
groups:
|
||||
github-actions:
|
||||
patterns:
|
||||
- "*"
|
||||
# Python
|
||||
- package-ecosystem: "pip"
|
||||
directory: "/"
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
verbose = "info"
|
||||
no_progress = true
|
||||
include_verbatim = true
|
||||
retry_wait_time = 10
|
||||
max_retries = 3
|
||||
max_concurrency = 8
|
||||
cache = false
|
||||
accept = [
|
||||
200, # OK
|
||||
408, # Request Timeout
|
||||
# 429 means the server received the request and is actively rate-limiting — the URL is
|
||||
# reachable. Real dead links return 404, 410, 5xx, or fail to connect; none of those
|
||||
# produce a 429, so accepting it here does not hide broken links.
|
||||
429, # Too Many Requests (rate-limited but reachable; does not mask dead links)
|
||||
]
|
||||
|
||||
exclude = [
|
||||
"https://github.com/YOUR_USERNAME/supervision.git", # hint for forking contributors
|
||||
"http://127.0.0.1:8000", # hint for local docs server
|
||||
"https://sam2.metademolab.com/", # returns 403 Forbidden
|
||||
"https://snyk.io/advisor/python/supervision/badge.svg", # badge URL
|
||||
"https://universe.roboflow.com/",
|
||||
"https://universe.roboflow.com/model-examples/segmented-animals-basic",
|
||||
# fixme: this page returns 401 Unauthorized when accessed and 404 Not Found when accessed with browser,
|
||||
# which is weird and should be investigated
|
||||
"https://huggingface.co/spaces/Roboflow/Annotators",
|
||||
]
|
||||
Executable
+70
@@ -0,0 +1,70 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Script to augment relative links in markdown files to GitHub URLs.
|
||||
"""
|
||||
|
||||
import argparse
|
||||
import os
|
||||
import re
|
||||
from re import Match
|
||||
|
||||
|
||||
def get_repo_root() -> str:
|
||||
"""Get the repository root path."""
|
||||
script_dir = os.path.dirname(os.path.abspath(__file__))
|
||||
return os.path.dirname(os.path.dirname(script_dir))
|
||||
|
||||
|
||||
def augment_links_in_file(file_path: str, branch: str = "main") -> None:
|
||||
"""
|
||||
Augment relative links in a markdown file to GitHub URLs.
|
||||
|
||||
Args:
|
||||
file_path: Path to the markdown file.
|
||||
branch: Branch name, default "main".
|
||||
"""
|
||||
repo_root = get_repo_root()
|
||||
|
||||
if not file_path.endswith(".md"):
|
||||
return
|
||||
|
||||
with open(file_path) as f:
|
||||
content = f.read()
|
||||
|
||||
def replace_link(match: Match[str]) -> str:
|
||||
full_match = match.group(0)
|
||||
text = match.group(2)
|
||||
url = match.group(3)
|
||||
if not url.startswith("http"):
|
||||
# Resolve relative to an absolute path
|
||||
abs_path = os.path.normpath(os.path.join(os.path.dirname(file_path), url))
|
||||
if os.path.exists(abs_path):
|
||||
# Use 'tree' for directories and 'blob' for files
|
||||
ref = "tree" if os.path.isdir(abs_path) else "blob"
|
||||
rel_to_root = os.path.relpath(abs_path, repo_root)
|
||||
new_url = f"https://github.com/roboflow/supervision/{ref}/{branch}/{rel_to_root}"
|
||||
if full_match.startswith("!"):
|
||||
return f""
|
||||
else:
|
||||
return f"[{text}]({new_url})"
|
||||
return full_match
|
||||
|
||||
new_content = re.sub(r"(!?)\[([^\]]+)\]\(([^)]+)\)", replace_link, content)
|
||||
with open(file_path, "w") as f:
|
||||
f.write(new_content)
|
||||
|
||||
|
||||
def main() -> None:
|
||||
parser = argparse.ArgumentParser(
|
||||
description="Augment relative links to GitHub URLs."
|
||||
)
|
||||
parser.add_argument("--branch", default="main", help="Branch name")
|
||||
parser.add_argument("files", nargs="+", help="Files to process")
|
||||
args = parser.parse_args()
|
||||
|
||||
for file in args.files:
|
||||
augment_links_in_file(file, args.branch)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
@@ -0,0 +1,56 @@
|
||||
name: Build Package
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
on:
|
||||
workflow_call:
|
||||
inputs:
|
||||
python-version:
|
||||
required: false
|
||||
type: string
|
||||
default: "3.10"
|
||||
link-check:
|
||||
required: false
|
||||
type: boolean
|
||||
default: true
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: 📥 Checkout the repository
|
||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||
|
||||
- name: 🐍 Install uv and set Python version ${{ inputs.python-version }}
|
||||
uses: astral-sh/setup-uv@08807647e7069bb48b6ef5acd8ec9567f424441b # v8.1.0
|
||||
with:
|
||||
python-version: ${{ inputs.python-version }}
|
||||
activate-environment: true
|
||||
|
||||
- name: 🎨 Augment paths in README
|
||||
run: |
|
||||
python .github/scripts/augment_links.py README.md --branch ${{ github.head_ref || github.ref_name }}
|
||||
cat README.md
|
||||
|
||||
- name: 🔗 Link Checker
|
||||
if: inputs.link-check
|
||||
uses: lycheeverse/lychee-action@v2
|
||||
with:
|
||||
lycheeVersion: v0.22.0
|
||||
args: |
|
||||
--config .github/lychee.toml
|
||||
README.md
|
||||
fail: true
|
||||
|
||||
- name: 🏗️ Build source and wheel distributions
|
||||
run: |
|
||||
uv sync --frozen --group build
|
||||
uv build
|
||||
twine check --strict dist/*
|
||||
|
||||
- name: 📤 Upload distribution artifacts
|
||||
uses: actions/upload-artifact@v7
|
||||
with:
|
||||
name: dist
|
||||
path: dist/
|
||||
@@ -0,0 +1,37 @@
|
||||
name: Docs/Test Workflow
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [main, develop]
|
||||
pull_request:
|
||||
branches: [main, develop]
|
||||
|
||||
concurrency:
|
||||
group: docs-test-${{ github.ref }}
|
||||
cancel-in-progress: ${{ github.event_name == 'pull_request' }}
|
||||
|
||||
# Restrict permissions by default
|
||||
permissions:
|
||||
contents: read # Required for checkout
|
||||
checks: write # Required for test reporting
|
||||
|
||||
jobs:
|
||||
docs-build:
|
||||
name: Test docs build
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 10
|
||||
steps:
|
||||
- name: 📥 Checkout the repository
|
||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||
|
||||
- name: 🐍 Install uv and set Python
|
||||
uses: astral-sh/setup-uv@08807647e7069bb48b6ef5acd8ec9567f424441b # v8.1.0
|
||||
with:
|
||||
python-version: "3.10"
|
||||
activate-environment: true
|
||||
|
||||
- name: 🏗️ Install dependencies
|
||||
run: uv sync --frozen --group docs
|
||||
|
||||
- name: 🧪 Test Docs Build
|
||||
run: mkdocs build --verbose
|
||||
@@ -0,0 +1,37 @@
|
||||
name: Check links & references
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [main, develop]
|
||||
pull_request:
|
||||
schedule:
|
||||
# Run once a week on Sundays
|
||||
- cron: "0 9 * * 0"
|
||||
|
||||
concurrency:
|
||||
group: ci-check-links-${{ github.ref }}
|
||||
cancel-in-progress: true
|
||||
jobs:
|
||||
links-check:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v6
|
||||
|
||||
- name: 🔗 Link Checker
|
||||
uses: lycheeverse/lychee-action@v2
|
||||
with:
|
||||
lycheeVersion: v0.22.0
|
||||
args: |
|
||||
--config .github/lychee.toml
|
||||
'./**/*.md'
|
||||
# TODO: enable also following file types
|
||||
# './**/*.toml'
|
||||
# './**/*.yml'
|
||||
# './**/*.yaml'
|
||||
# './**/*.py'
|
||||
fail: true
|
||||
token: ${{ secrets.GITHUB_TOKEN }}
|
||||
@@ -0,0 +1,90 @@
|
||||
name: Pytest/Test Workflow
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [main, develop]
|
||||
pull_request:
|
||||
branches: [main, develop]
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
concurrency:
|
||||
group: pytest-test-${{ github.ref }}
|
||||
cancel-in-progress: ${{ github.event_name == 'pull_request' }}
|
||||
|
||||
jobs:
|
||||
build-pkg:
|
||||
name: Build this Package
|
||||
uses: ./.github/workflows/build-package.yml
|
||||
with:
|
||||
# only run link check on PRs from the same repo
|
||||
link-check: ${{ github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == github.repository }}
|
||||
|
||||
run-tests:
|
||||
name: Import Test and Pytest Run
|
||||
# needs: build # todo: consider using this build package for testing
|
||||
timeout-minutes: 10
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
os: ["ubuntu-latest", "windows-latest", "macos-latest"]
|
||||
python-version: ["3.9", "3.10", "3.11", "3.12", "3.13"]
|
||||
runs-on: ${{ matrix.os }}
|
||||
steps:
|
||||
- name: 📥 Checkout the repository
|
||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||
|
||||
- name: 🐍 Install uv and set Python version ${{ matrix.python-version }}
|
||||
uses: astral-sh/setup-uv@08807647e7069bb48b6ef5acd8ec9567f424441b # v8.1.0
|
||||
with:
|
||||
python-version: ${{ matrix.python-version }}
|
||||
activate-environment: true
|
||||
|
||||
- name: 🚀 Install Packages
|
||||
run: uv sync --frozen --group dev --group docs --extra metrics
|
||||
|
||||
- name: 📦 Run the Import test
|
||||
run: python -c "import supervision; from supervision import assets; from supervision import metrics; print(supervision.__version__)"
|
||||
|
||||
- name: 🧪 Run the Test
|
||||
run: pytest src/ tests/ --cov=supervision --cov-report=xml
|
||||
|
||||
- name: Generate Coverage Report
|
||||
run: |
|
||||
coverage xml
|
||||
coverage report
|
||||
|
||||
- name: Upload coverage to Codecov
|
||||
uses: codecov/codecov-action@v6
|
||||
with:
|
||||
token: ${{ secrets.CODECOV_TOKEN }}
|
||||
files: "coverage.xml"
|
||||
flags: cpu,${{ runner.os }},python${{ matrix.python-version }}
|
||||
env_vars: OS,PYTHON
|
||||
name: codecov-umbrella
|
||||
fail_ci_if_error: false
|
||||
|
||||
- name: Minimize uv cache
|
||||
run: uv cache prune --ci
|
||||
|
||||
testing-guardian:
|
||||
runs-on: ubuntu-latest
|
||||
needs: run-tests
|
||||
if: always()
|
||||
steps:
|
||||
- name: 📋 Display test result
|
||||
run: echo "${{ needs.run-tests.result }}"
|
||||
- name: ❌ Fail guardian on test failure
|
||||
if: needs.run-tests.result == 'failure'
|
||||
run: exit 1
|
||||
# Ensure that cancelled or skipped test runs still cause this guardian job to fail,
|
||||
# using an explicit exit code instead of relying on timeout behavior.
|
||||
- name: ⚠️ cancelled or skipped...
|
||||
if: contains(fromJSON('["cancelled", "skipped"]'), needs.run-tests.result)
|
||||
run: |
|
||||
echo "run-tests job result is '${{ needs.run-tests.result }}'; failing explicitly."
|
||||
exit 1
|
||||
- name: ✅ tests succeeded
|
||||
if: needs.run-tests.result == 'success'
|
||||
run: echo "All tests completed successfully in job 'run-tests'."
|
||||
@@ -16,7 +16,7 @@ jobs:
|
||||
timeout-minutes: 10
|
||||
steps:
|
||||
- name: Clear cache
|
||||
uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # v7.0.1
|
||||
uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
|
||||
with:
|
||||
script: |
|
||||
console.log("Starting cache cleanup...")
|
||||
|
||||
@@ -1,22 +0,0 @@
|
||||
name: Combine Dependabot PRs
|
||||
|
||||
on:
|
||||
schedule:
|
||||
- cron: "0 1 * * 3" # Wednesday at 01:00
|
||||
workflow_dispatch: # allows you to manually trigger the workflow
|
||||
|
||||
permissions:
|
||||
contents: write
|
||||
pull-requests: write
|
||||
checks: read
|
||||
|
||||
jobs:
|
||||
combine-prs:
|
||||
name: Combine
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: combine-prs
|
||||
id: combine-prs
|
||||
uses: github/combine-prs@2909f404763c3177a456e052bdb7f2e85d3a7cb3 # v5.2.0
|
||||
with:
|
||||
labels: combined-pr
|
||||
@@ -1,42 +0,0 @@
|
||||
name: 🔧 Poetry Check and Installation Test Workflow
|
||||
on:
|
||||
push:
|
||||
paths:
|
||||
- "poetry.lock"
|
||||
- "pyproject.toml"
|
||||
pull_request:
|
||||
paths:
|
||||
- "poetry.lock"
|
||||
- "pyproject.toml"
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
poetry-tests:
|
||||
name: Poetry install and check
|
||||
timeout-minutes: 10
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
os: [ubuntu-latest, windows-latest, macos-latest]
|
||||
python-version: ["3.8", "3.9", "3.10", "3.11", "3.12", "3.13"]
|
||||
runs-on: ${{ matrix.os }}
|
||||
steps:
|
||||
- name: 📥 Checkout the repository
|
||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
||||
|
||||
- name: 🐍 Set up Python ${{ matrix.python-version }}
|
||||
uses: actions/setup-python@0b93645e9fea7318ecaed2b359559ac225c90a2b # v5.3.0
|
||||
with:
|
||||
python-version: ${{ matrix.python-version }}
|
||||
|
||||
- name: 📜 Setup Poetry
|
||||
uses: abatilo/actions-poetry@e78f54a89cb052fff327414dd9ff010b5d2b4dbd # v3.0.1
|
||||
|
||||
- name: 🔍 Check the correctness of the project config
|
||||
run: poetry check
|
||||
|
||||
- name: 🚀 Do Install the package Test
|
||||
run: poetry install --with dev --extras metrics
|
||||
|
||||
- name: 🧪 Run the Import test
|
||||
run: poetry run python -c "import supervision; from supervision import assets; from supervision import metrics; print(supervision.__version__)"
|
||||
@@ -0,0 +1,26 @@
|
||||
name: PR Conflict Labeler
|
||||
|
||||
on:
|
||||
# So that PRs touching the same files as the push are updated
|
||||
push:
|
||||
branches:
|
||||
- main
|
||||
- develop
|
||||
# So that the `dirtyLabel` is removed if conflicts are resolved
|
||||
# We recommend `pull_request_target` so that github secrets are available.
|
||||
# In `pull_request` we wouldn't be able to change labels of fork PRs
|
||||
pull_request_target:
|
||||
types: [synchronize]
|
||||
|
||||
permissions:
|
||||
pull-requests: write
|
||||
issues: write
|
||||
jobs:
|
||||
main:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: check if prs are dirty
|
||||
uses: eps1lon/actions-label-merge-conflict@v3
|
||||
with:
|
||||
dirtyLabel: "has conflicts"
|
||||
repoToken: "${{ secrets.GITHUB_TOKEN }}"
|
||||
@@ -1,9 +1,15 @@
|
||||
name: Build and Publish Docs
|
||||
name: Docs/Build and Publish
|
||||
|
||||
# Deploy matrix:
|
||||
# push develop -> mike deploy develop
|
||||
# push release/latest -> mike deploy latest
|
||||
# release published -> mike deploy <tag> only; does not move /latest/
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- develop
|
||||
- release/latest
|
||||
workflow_dispatch:
|
||||
release:
|
||||
types: [published]
|
||||
@@ -20,43 +26,129 @@ permissions:
|
||||
pull-requests: write # Required for PR comments
|
||||
|
||||
jobs:
|
||||
deploy:
|
||||
docs-build-deploy:
|
||||
name: Publish Docs
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 10
|
||||
strategy:
|
||||
matrix:
|
||||
python-version: ["3.10"]
|
||||
steps:
|
||||
- name: 📥 Checkout the repository
|
||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: 🐍 Set up Python ${{ matrix.python-version }}
|
||||
uses: actions/setup-python@0b93645e9fea7318ecaed2b359559ac225c90a2b # v5.3.0
|
||||
- name: 🐍 Install uv and set Python
|
||||
uses: astral-sh/setup-uv@08807647e7069bb48b6ef5acd8ec9567f424441b # v8.1.0
|
||||
with:
|
||||
python-version: ${{ matrix.python-version }}
|
||||
python-version: "3.10"
|
||||
activate-environment: true
|
||||
|
||||
- name: 📜 Setup Poetry
|
||||
uses: abatilo/actions-poetry@e78f54a89cb052fff327414dd9ff010b5d2b4dbd # v3.0.1
|
||||
|
||||
- name: 📦 Install dependencies
|
||||
run: |
|
||||
poetry install --with=docs
|
||||
- name: 🏗️ Install dependencies
|
||||
run: uv sync --frozen --group docs
|
||||
|
||||
- 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"
|
||||
git config --global user.name "${{ github.actor }}"
|
||||
git config --global user.email "${{ github.actor }}@users.noreply.github.com"
|
||||
|
||||
- name: 🚀 Deploy Development Docs
|
||||
if: (github.event_name == 'push' && github.ref == 'refs/heads/develop') || github.event_name == 'workflow_dispatch'
|
||||
env:
|
||||
MKDOCS_GIT_COMMITTERS_APIKEY: ${{ secrets.GITHUB_TOKEN }}
|
||||
run: |
|
||||
MKDOCS_GIT_COMMITTERS_APIKEY=${{ secrets.GITHUB_TOKEN }} poetry run mike deploy --push develop
|
||||
mike deploy --push develop
|
||||
|
||||
- name: 🚀 Deploy Latest Docs
|
||||
if: github.event_name == 'push' && github.ref == 'refs/heads/release/latest'
|
||||
env:
|
||||
MKDOCS_GIT_COMMITTERS_APIKEY: ${{ secrets.GITHUB_TOKEN }}
|
||||
run: |
|
||||
mike deploy --push latest
|
||||
|
||||
- name: 🚀 Deploy Release Docs
|
||||
if: github.event_name == 'release' && github.event.action == 'published'
|
||||
env:
|
||||
MKDOCS_GIT_COMMITTERS_APIKEY: ${{ secrets.GITHUB_TOKEN }}
|
||||
run: |
|
||||
latest_tag=$(git describe --tags `git rev-list --tags --max-count=1`)
|
||||
MKDOCS_GIT_COMMITTERS_APIKEY=${{ secrets.GITHUB_TOKEN }} poetry run mike deploy --push --update-aliases $latest_tag latest
|
||||
release_tag="${GITHUB_REF_NAME#v}"
|
||||
mike deploy --push "$release_tag"
|
||||
|
||||
# IndexNow key: 0d5d9799b1cc4a39825146388c6781eb
|
||||
# This key must stay in sync across three files:
|
||||
# docs/0d5d9799b1cc4a39825146388c6781eb.txt (key file served at site root)
|
||||
# docs/theme/main.html (indexnow-key meta tag)
|
||||
# this workflow (inject step + notify step below)
|
||||
# Bing/Yandex fetch https://supervision.roboflow.com/<key>.txt to verify ownership.
|
||||
# Do NOT rename or delete the .txt file or change the key string without updating all three.
|
||||
- name: 🌐 Inject GEO root files into gh-pages
|
||||
if: >
|
||||
(github.event_name == 'push' && github.ref == 'refs/heads/develop') ||
|
||||
github.event_name == 'workflow_dispatch' ||
|
||||
(github.event_name == 'push' && github.ref == 'refs/heads/release/latest') ||
|
||||
(github.event_name == 'release' && github.event.action == 'published')
|
||||
run: |
|
||||
cp docs/robots.txt /tmp/robots.txt
|
||||
cp docs/llms.txt /tmp/llms.txt
|
||||
cp docs/llms.full.txt /tmp/llms.full.txt
|
||||
cp docs/llms-100k.txt /tmp/llms-100k.txt
|
||||
cp docs/_headers /tmp/headers.txt
|
||||
cp docs/0d5d9799b1cc4a39825146388c6781eb.txt /tmp/indexnow.txt
|
||||
if [[ "$GITHUB_REF" == "refs/heads/release/latest" ]]; then
|
||||
version_dir="latest"
|
||||
else
|
||||
version_dir=""
|
||||
fi
|
||||
git fetch origin gh-pages
|
||||
git checkout gh-pages
|
||||
cp /tmp/robots.txt robots.txt
|
||||
cp /tmp/llms.txt llms.txt
|
||||
cp /tmp/llms.full.txt llms.full.txt
|
||||
cp /tmp/llms-100k.txt llms-100k.txt
|
||||
cp /tmp/headers.txt _headers
|
||||
cp /tmp/indexnow.txt 0d5d9799b1cc4a39825146388c6781eb.txt
|
||||
if [[ -n "$version_dir" && -f "$version_dir/sitemap.xml" ]]; then
|
||||
cp "$version_dir/sitemap.xml" sitemap.xml
|
||||
gzip -9 -c sitemap.xml > sitemap.xml.gz
|
||||
fi
|
||||
files_to_add=(
|
||||
robots.txt
|
||||
llms.txt
|
||||
llms.full.txt
|
||||
llms-100k.txt
|
||||
_headers
|
||||
0d5d9799b1cc4a39825146388c6781eb.txt
|
||||
)
|
||||
if [[ -f "sitemap.xml" ]]; then
|
||||
files_to_add+=(sitemap.xml)
|
||||
fi
|
||||
if [[ -f "sitemap.xml.gz" ]]; then
|
||||
files_to_add+=(sitemap.xml.gz)
|
||||
fi
|
||||
git add "${files_to_add[@]}"
|
||||
git diff --cached --quiet || git commit -m "chore: update GEO root files"
|
||||
git push origin gh-pages
|
||||
|
||||
- name: 📡 Notify IndexNow
|
||||
if: >
|
||||
(github.event_name == 'push' && github.ref == 'refs/heads/develop') ||
|
||||
github.event_name == 'workflow_dispatch' ||
|
||||
(github.event_name == 'push' && github.ref == 'refs/heads/release/latest')
|
||||
run: |
|
||||
curl -s -o /dev/null -w "%{http_code}" -X POST "https://api.indexnow.org/IndexNow" \
|
||||
-H "Content-Type: application/json; charset=utf-8" \
|
||||
-d '{
|
||||
"host": "supervision.roboflow.com",
|
||||
"key": "0d5d9799b1cc4a39825146388c6781eb",
|
||||
"keyLocation": "https://supervision.roboflow.com/0d5d9799b1cc4a39825146388c6781eb.txt",
|
||||
"urlList": [
|
||||
"https://supervision.roboflow.com/",
|
||||
"https://supervision.roboflow.com/latest/",
|
||||
"https://supervision.roboflow.com/latest/how_to/detect_and_annotate/",
|
||||
"https://supervision.roboflow.com/latest/how_to/track_objects/",
|
||||
"https://supervision.roboflow.com/latest/how_to/detect_small_objects/",
|
||||
"https://supervision.roboflow.com/latest/how_to/filter_detections/",
|
||||
"https://supervision.roboflow.com/latest/how_to/save_detections/",
|
||||
"https://supervision.roboflow.com/latest/how_to/count_in_zone/",
|
||||
"https://supervision.roboflow.com/latest/how_to/benchmark_a_model/",
|
||||
"https://supervision.roboflow.com/latest/how_to/process_datasets/"
|
||||
]
|
||||
}' || true
|
||||
|
||||
@@ -0,0 +1,48 @@
|
||||
name: Publish Supervision Pre-Releases to PyPI
|
||||
|
||||
on:
|
||||
push:
|
||||
tags:
|
||||
- "[0-9]+.[0-9]+[0-9]+.[0-9]+a[0-9]"
|
||||
- "[0-9]+.[0-9]+[0-9]+.[0-9]+b[0-9]"
|
||||
- "[0-9]+.[0-9]+[0-9]+.[0-9]+rc[0-9]"
|
||||
workflow_dispatch:
|
||||
pull_request:
|
||||
branches: [main, develop]
|
||||
paths:
|
||||
- ".github/workflows/build-package.yml"
|
||||
- ".github/workflows/publish-pre-release.yml"
|
||||
|
||||
permissions: {} # Explicitly remove all permissions by default
|
||||
|
||||
jobs:
|
||||
build:
|
||||
permissions:
|
||||
contents: read
|
||||
uses: ./.github/workflows/build-package.yml
|
||||
|
||||
publish-pre-release:
|
||||
name: Publish Pre-release Package
|
||||
needs: build
|
||||
runs-on: ubuntu-latest
|
||||
environment:
|
||||
name: test
|
||||
url: https://pypi.org/project/supervision/
|
||||
timeout-minutes: 10
|
||||
permissions:
|
||||
id-token: write # Required for PyPI publishing
|
||||
contents: read # Required for checkout
|
||||
steps:
|
||||
- name: 📥 Download distribution artifacts
|
||||
uses: actions/download-artifact@v8
|
||||
with:
|
||||
name: dist
|
||||
path: dist/
|
||||
- name: List distribution artifacts
|
||||
run: ls -lh dist/
|
||||
|
||||
- name: 🚀 Publish to PyPi
|
||||
if: github.event_name != 'pull_request'
|
||||
uses: pypa/gh-action-pypi-publish@cef221092ed1bacb1cc03d23a2d87d1d172e277b # v1.14.0
|
||||
with:
|
||||
attestations: true
|
||||
@@ -0,0 +1,53 @@
|
||||
name: Publish Supervision Releases to PyPI
|
||||
|
||||
on:
|
||||
release:
|
||||
types: [published]
|
||||
workflow_dispatch:
|
||||
pull_request:
|
||||
branches: [main, develop]
|
||||
paths:
|
||||
- ".github/workflows/build-package.yml"
|
||||
- ".github/workflows/publish-release.yml"
|
||||
|
||||
permissions: {} # Explicitly remove all permissions by default
|
||||
|
||||
jobs:
|
||||
build:
|
||||
permissions:
|
||||
contents: read
|
||||
uses: ./.github/workflows/build-package.yml
|
||||
|
||||
publish-release:
|
||||
name: Publish Release Package
|
||||
needs: build
|
||||
runs-on: ubuntu-latest
|
||||
environment:
|
||||
name: release
|
||||
url: https://pypi.org/project/supervision/
|
||||
timeout-minutes: 10
|
||||
permissions:
|
||||
id-token: write # Required for PyPI publishing
|
||||
contents: write # Required for checkout and upload assets
|
||||
steps:
|
||||
- name: 📥 Download distribution artifacts
|
||||
uses: actions/download-artifact@v8
|
||||
with:
|
||||
name: dist
|
||||
path: dist/
|
||||
- name: List distribution artifacts
|
||||
run: ls -lh dist/
|
||||
|
||||
- name: 📦 Upload assets to Release
|
||||
if: github.event_name == 'release'
|
||||
uses: AButler/upload-release-assets@v3.0
|
||||
with:
|
||||
files: "dist/*"
|
||||
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: 🚀 Publish to PyPi
|
||||
# We only want to publish to PyPi if the event is a release and it's not a pre-release.
|
||||
if: (github.event_name == 'release' && github.event.release.prerelease != true) || github.event_name == 'workflow_dispatch'
|
||||
uses: pypa/gh-action-pypi-publish@cef221092ed1bacb1cc03d23a2d87d1d172e277b # v1.14.0
|
||||
with:
|
||||
attestations: true
|
||||
@@ -1,52 +0,0 @@
|
||||
name: Publish Supervision Pre-Releases to PyPI and TestPyPI
|
||||
|
||||
on:
|
||||
push:
|
||||
tags:
|
||||
- "[0-9]+.[0-9]+[0-9]+.[0-9]+a[0-9]"
|
||||
- "[0-9]+.[0-9]+[0-9]+.[0-9]+b[0-9]"
|
||||
- "[0-9]+.[0-9]+[0-9]+.[0-9]+rc[0-9]"
|
||||
workflow_dispatch:
|
||||
|
||||
permissions: {} # Explicitly remove all permissions by default
|
||||
|
||||
jobs:
|
||||
build-and-publish-pre-release:
|
||||
name: Publish Pre-releasePackage
|
||||
runs-on: ubuntu-latest
|
||||
environment: release
|
||||
timeout-minutes: 10
|
||||
permissions:
|
||||
id-token: write # Required for PyPI publishing
|
||||
contents: read # Required for checkout
|
||||
strategy:
|
||||
matrix:
|
||||
python-version: ["3.10"]
|
||||
steps:
|
||||
- name: 📥 Checkout the repository
|
||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
||||
|
||||
- name: 🐍 Set up Python ${{ matrix.python-version }}
|
||||
uses: actions/setup-python@0b93645e9fea7318ecaed2b359559ac225c90a2b # v5.3.0
|
||||
with:
|
||||
python-version: ${{ matrix.python-version }}
|
||||
|
||||
- name: 📜 Setup Poetry
|
||||
uses: abatilo/actions-poetry@e78f54a89cb052fff327414dd9ff010b5d2b4dbd # v3.0.1
|
||||
|
||||
- name: 🏗️ Build source and wheel distributions
|
||||
run: |
|
||||
poetry install --with=build
|
||||
poetry build
|
||||
twine check --strict dist/*
|
||||
|
||||
- name: 🚀 Publish to PyPi
|
||||
uses: pypa/gh-action-pypi-publish@67339c736fd9354cd4f8cb0b744f2b82a74b5c70 # v1.12.3
|
||||
with:
|
||||
attestations: true
|
||||
|
||||
- name: 🚀 Publish to Test-PyPi
|
||||
uses: pypa/gh-action-pypi-publish@67339c736fd9354cd4f8cb0b744f2b82a74b5c70 # v1.12.3
|
||||
with:
|
||||
repository-url: https://test.pypi.org/legacy/
|
||||
attestations: true
|
||||
@@ -0,0 +1,44 @@
|
||||
name: Publish Supervision Releases to TestPyPI
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
pull_request:
|
||||
branches: [main, develop]
|
||||
paths:
|
||||
- ".github/workflows/build-package.yml"
|
||||
- ".github/workflows/publish-testpypi.yml"
|
||||
|
||||
permissions: {} # Explicitly remove all permissions by default
|
||||
|
||||
jobs:
|
||||
build:
|
||||
permissions:
|
||||
contents: read
|
||||
uses: ./.github/workflows/build-package.yml
|
||||
|
||||
publish-testpypi:
|
||||
name: Publish Release Package
|
||||
needs: build
|
||||
runs-on: ubuntu-latest
|
||||
environment:
|
||||
name: release
|
||||
url: https://pypi.org/project/supervision/
|
||||
timeout-minutes: 10
|
||||
permissions:
|
||||
id-token: write # Required for PyPI publishing
|
||||
contents: read # Required for checkout
|
||||
steps:
|
||||
- name: 📥 Download distribution artifacts
|
||||
uses: actions/download-artifact@v8
|
||||
with:
|
||||
name: dist
|
||||
path: dist/
|
||||
- name: List distribution artifacts
|
||||
run: ls -lh dist/
|
||||
|
||||
- name: 🚀 Publish to Test-PyPi
|
||||
if: github.event_name != 'pull_request'
|
||||
uses: pypa/gh-action-pypi-publish@cef221092ed1bacb1cc03d23a2d87d1d172e277b # v1.14.0
|
||||
with:
|
||||
repository-url: https://test.pypi.org/legacy/
|
||||
attestations: true
|
||||
@@ -1,50 +0,0 @@
|
||||
name: Publish Supervision Releases to PyPI and TestPyPI
|
||||
|
||||
on:
|
||||
push:
|
||||
tags:
|
||||
- "[0-9]+.[0-9]+[0-9]+.[0-9]"
|
||||
workflow_dispatch:
|
||||
|
||||
permissions: {} # Explicitly remove all permissions by default
|
||||
|
||||
jobs:
|
||||
build-and-publish-pre-release:
|
||||
name: Publish Release Package
|
||||
runs-on: ubuntu-latest
|
||||
environment: release
|
||||
timeout-minutes: 10
|
||||
permissions:
|
||||
id-token: write # Required for PyPI publishing
|
||||
contents: read # Required for checkout
|
||||
strategy:
|
||||
matrix:
|
||||
python-version: ["3.10"]
|
||||
steps:
|
||||
- name: 📥 Checkout the repository
|
||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
||||
|
||||
- name: 🐍 Set up Python ${{ matrix.python-version }}
|
||||
uses: actions/setup-python@0b93645e9fea7318ecaed2b359559ac225c90a2b # v5.3.0
|
||||
with:
|
||||
python-version: ${{ matrix.python-version }}
|
||||
|
||||
- name: 📜 Setup Poetry
|
||||
uses: abatilo/actions-poetry@e78f54a89cb052fff327414dd9ff010b5d2b4dbd # v3.0.1
|
||||
|
||||
- name: 🏗️ Build source and wheel distributions
|
||||
run: |
|
||||
poetry install --with=build
|
||||
poetry build
|
||||
twine check --strict dist/*
|
||||
|
||||
- name: 🚀 Publish to PyPi
|
||||
uses: pypa/gh-action-pypi-publish@67339c736fd9354cd4f8cb0b744f2b82a74b5c70 # v1.12.3
|
||||
with:
|
||||
attestations: true
|
||||
|
||||
- name: 🚀 Publish to Test-PyPi
|
||||
uses: pypa/gh-action-pypi-publish@67339c736fd9354cd4f8cb0b744f2b82a74b5c70 # v1.12.3
|
||||
with:
|
||||
repository-url: https://test.pypi.org/legacy/
|
||||
attestations: true
|
||||
@@ -1,40 +0,0 @@
|
||||
name: 🧪 Docs Test WorkFlow 📚
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
branches: [main, develop]
|
||||
|
||||
# Restrict permissions by default
|
||||
permissions:
|
||||
contents: read # Required for checkout
|
||||
checks: write # Required for test reporting
|
||||
|
||||
jobs:
|
||||
docs-build-test:
|
||||
name: Test docs build
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 10
|
||||
strategy:
|
||||
matrix:
|
||||
python-version: ["3.10"]
|
||||
steps:
|
||||
- name: 📥 Checkout the repository
|
||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: 🐍 Set up Python ${{ matrix.python-version }}
|
||||
uses: actions/setup-python@0b93645e9fea7318ecaed2b359559ac225c90a2b # v5.3.0
|
||||
with:
|
||||
python-version: ${{ matrix.python-version }}
|
||||
|
||||
- name: 📜 Setup Poetry
|
||||
uses: abatilo/actions-poetry@e78f54a89cb052fff327414dd9ff010b5d2b4dbd # v3.0.1
|
||||
|
||||
- name: 🏗️ Install dependencies
|
||||
run: |
|
||||
poetry install --with=docs
|
||||
|
||||
- name: 🧪 Test Docs Build
|
||||
run: |
|
||||
poetry run mkdocs build --verbose
|
||||
@@ -1,47 +0,0 @@
|
||||
name: Test WorkFlow
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
branches: [main, develop]
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
checks: write # Required for test reporting
|
||||
pull-requests: write # Required for PR comments
|
||||
|
||||
jobs:
|
||||
pytest:
|
||||
name: PyTest
|
||||
timeout-minutes: 10
|
||||
strategy:
|
||||
matrix:
|
||||
os: [ubuntu-latest, windows-latest, macos-latest]
|
||||
python-version: ["3.8", "3.9", "3.10", "3.11", "3.12", "3.13"]
|
||||
fail-fast: false # Continue with other versions if one fails
|
||||
runs-on: ${{ matrix.os }}
|
||||
steps:
|
||||
- name: 📥 Checkout the repository
|
||||
uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
||||
|
||||
- name: 🐍 Set up Python ${{ matrix.python-version }}
|
||||
uses: actions/setup-python@0b93645e9fea7318ecaed2b359559ac225c90a2b # v5.3.0
|
||||
with:
|
||||
python-version: ${{ matrix.python-version }}
|
||||
|
||||
- name: 📜 Setup Poetry
|
||||
uses: abatilo/actions-poetry@e78f54a89cb052fff327414dd9ff010b5d2b4dbd # v3.0.1
|
||||
|
||||
- name: 📦 Install dependencies
|
||||
run: |
|
||||
poetry install --with=test
|
||||
|
||||
- name: Run pytest
|
||||
uses: pavelzw/pytest-action@510c5e90c360a185039bea56ce8b3e7e51a16507 # v2.2.0
|
||||
with:
|
||||
verbose: true
|
||||
emoji: true
|
||||
job-summary: true
|
||||
custom-arguments: "-q"
|
||||
click-to-expand: true
|
||||
report-title: "Test Report"
|
||||
custom-pytest: "poetry run pytest"
|
||||
+16
@@ -153,3 +153,19 @@ Desktop.ini
|
||||
*~
|
||||
.directory
|
||||
.Trash-*
|
||||
|
||||
# local data
|
||||
data/
|
||||
|
||||
# Claude working scratchpad (plans, lessons, ephemeral artefacts)
|
||||
.claude/logs
|
||||
.claude/state/
|
||||
.plans/
|
||||
.reports/
|
||||
.temp/
|
||||
.tmp/
|
||||
_outputs/
|
||||
_resolutions/
|
||||
_reviews/
|
||||
tasks/
|
||||
*.local.md
|
||||
|
||||
+52
-26
@@ -1,3 +1,5 @@
|
||||
default_language_version:
|
||||
python: python3
|
||||
|
||||
ci:
|
||||
autofix_prs: true
|
||||
@@ -7,49 +9,73 @@ ci:
|
||||
|
||||
repos:
|
||||
- repo: https://github.com/pre-commit/pre-commit-hooks
|
||||
rev: v5.0.0
|
||||
rev: v6.0.0
|
||||
hooks:
|
||||
- id: trailing-whitespace
|
||||
exclude: test/.*\.py
|
||||
- id: check-yaml
|
||||
exclude: mkdocs.yml
|
||||
args: ["--unsafe"]
|
||||
- id: check-executables-have-shebangs
|
||||
- id: check-json
|
||||
- id: check-toml
|
||||
- id: check-case-conflict
|
||||
- id: check-added-large-files
|
||||
args: ["--maxkb=500", "--enforce-all"]
|
||||
exclude: uv.lock|.*\.ipynb$
|
||||
- id: detect-private-key
|
||||
- id: pretty-format-json
|
||||
exclude: demo.ipynb
|
||||
args: ['--autofix', '--no-sort-keys', '--indent=4']
|
||||
args: ["--autofix", "--no-sort-keys", "--indent=4"]
|
||||
- id: end-of-file-fixer
|
||||
- id: mixed-line-ending
|
||||
|
||||
- repo: https://github.com/PyCQA/bandit
|
||||
rev: '1.8.0'
|
||||
hooks:
|
||||
- id: bandit
|
||||
args: ["-c", "pyproject.toml"]
|
||||
additional_dependencies: ["bandit[toml]"]
|
||||
- repo: https://github.com/JoC0de/pre-commit-prettier
|
||||
rev: v3.8.3 # using tag; previously pinned SHA when tags were not persistent
|
||||
hooks:
|
||||
- id: prettier
|
||||
files: \.(ya?ml|toml)$
|
||||
# https://prettier.io/docs/en/options.html#print-width
|
||||
args: ["--print-width=120"]
|
||||
|
||||
- repo: https://github.com/astral-sh/ruff-pre-commit
|
||||
rev: v0.8.2
|
||||
hooks:
|
||||
- id: ruff
|
||||
args: [--fix, --exit-non-zero-on-fix]
|
||||
- id: ruff-format
|
||||
types_or: [ python, pyi, jupyter ]
|
||||
- repo: https://github.com/tox-dev/pyproject-fmt
|
||||
rev: v2.21.1
|
||||
hooks:
|
||||
- id: pyproject-fmt
|
||||
|
||||
# - repo: https://github.com/executablebooks/mdformat
|
||||
# rev: 0.7.17
|
||||
# hooks:
|
||||
# - id: mdformat
|
||||
# additional_dependencies:
|
||||
# - "mdformat-mkdocs[recommended]>=2.1.0"
|
||||
# args: ["--number"]
|
||||
- repo: https://github.com/abravalheri/validate-pyproject
|
||||
rev: v0.25
|
||||
hooks:
|
||||
- id: validate-pyproject
|
||||
|
||||
- repo: https://github.com/astral-sh/ruff-pre-commit
|
||||
rev: v0.15.12
|
||||
hooks:
|
||||
- id: ruff-check
|
||||
args: ["--fix"]
|
||||
- id: ruff-format
|
||||
types_or: [python, pyi, jupyter]
|
||||
|
||||
- repo: https://github.com/executablebooks/mdformat
|
||||
rev: 1.0.0
|
||||
hooks:
|
||||
- id: mdformat
|
||||
additional_dependencies:
|
||||
- "mdformat-mkdocs[recommended]>=2.1.0"
|
||||
- "mdformat-ruff"
|
||||
args: ["--number"]
|
||||
exclude: ^(docs/changelog\.md|docs/deprecated\.md)$
|
||||
|
||||
- repo: https://github.com/pre-commit/mirrors-mypy
|
||||
rev: v1.20.2
|
||||
hooks:
|
||||
- id: mypy
|
||||
additional_dependencies:
|
||||
- "numpy>=2.0"
|
||||
- "types-PyYAML"
|
||||
- "types-requests"
|
||||
|
||||
- repo: https://github.com/codespell-project/codespell
|
||||
rev: v2.3.0
|
||||
rev: v2.4.2
|
||||
hooks:
|
||||
- id: codespell
|
||||
additional_dependencies:
|
||||
- tomli
|
||||
- "tomli>=2.0.1"
|
||||
|
||||
@@ -0,0 +1,98 @@
|
||||
# Agent Guidelines for `supervision`
|
||||
|
||||
These instructions define how AI agents (GitHub Copilot, Claude, etc.) should behave when
|
||||
assigned an issue, task, or multi-step problem in this repository.
|
||||
|
||||
Behave like a senior contributor: precise, efficient, aligned with the project's
|
||||
philosophy, and focused on maintainability and clarity.
|
||||
|
||||
---
|
||||
|
||||
## 1. Before You Code
|
||||
|
||||
- Read the task/issue thoroughly before acting.
|
||||
- Identify missing information; ask **one targeted clarification question** if needed.
|
||||
- Outline a step-by-step plan before making changes.
|
||||
- Check whether the feature or fix already exists under a different name.
|
||||
- Confirm alignment with the repository's architecture (`src/supervision/`).
|
||||
|
||||
---
|
||||
|
||||
## 2. Repository Conventions
|
||||
|
||||
All work must follow the conventions of the `supervision` library
|
||||
(see [CONTRIBUTING.md](.github/CONTRIBUTING.md) for full details).
|
||||
|
||||
### Branching & Commits
|
||||
|
||||
- Branch from `develop` using prefixes: `feat/`, `fix/`, `docs/`, `refactor/`, `test/`, `chore/`.
|
||||
- Use **conventional commits**: `feat:`, `fix:`, `docs:`, `refactor:`, `perf:`, `test:`, `chore:`.
|
||||
- PRs must target the `develop` branch.
|
||||
|
||||
### Code Style
|
||||
|
||||
- **Formatting and linting** are enforced by **pre-commit**.
|
||||
The hook chain typically includes: ruff-check, ruff-format, codespell, mdformat,
|
||||
prettier, pyproject-fmt, and standard pre-commit-hooks (trailing whitespace, YAML, TOML, etc.).
|
||||
- **Type hints**: required on all new code. Type checking with mypy is encouraged but not
|
||||
currently enforced systematically by pre-commit; see [.github/CONTRIBUTING.md](.github/CONTRIBUTING.md)
|
||||
for the latest type-checking expectations.
|
||||
- **Docstrings**: Google Python docstring style. Required for all new functions and classes.
|
||||
Docstrings should include usage examples demonstrating the function with primitive values
|
||||
so they serve as runnable documentation.
|
||||
|
||||
### API Consistency
|
||||
|
||||
- Follow existing naming patterns.
|
||||
- Maintain backward compatibility unless explicitly allowed.
|
||||
- Prefer functional utilities over complex classes unless justified.
|
||||
|
||||
### Performance
|
||||
|
||||
- Avoid unnecessary copies of NumPy arrays.
|
||||
- Prefer vectorized operations over Python loops in hot paths.
|
||||
- Use OpenCV operations efficiently.
|
||||
|
||||
---
|
||||
|
||||
## 3. Implementing Features
|
||||
|
||||
- Provide a minimal, clean implementation.
|
||||
- Include type hints and Google-style docstrings with usage examples.
|
||||
- All new functionality must be covered with tests, including edge cases.
|
||||
- Add or update documentation (docstrings + mkdocs entries if applicable).
|
||||
- Ensure compatibility with core dependencies: NumPy, OpenCV, SciPy.
|
||||
|
||||
---
|
||||
|
||||
## 4. Fixing Bugs
|
||||
|
||||
1. Reproduce and understand the root cause.
|
||||
2. Write a test that reproduces the bug (it should fail before the fix).
|
||||
3. Apply a minimal, targeted fix.
|
||||
4. Verify the test passes and no other components break.
|
||||
|
||||
---
|
||||
|
||||
## 5. Refactoring
|
||||
|
||||
- Preserve behavior and API stability.
|
||||
- Improve readability or performance.
|
||||
- Reduce duplication.
|
||||
- Avoid large, sweeping refactors unless explicitly requested.
|
||||
|
||||
---
|
||||
|
||||
## 6. Before You Commit
|
||||
|
||||
Always run these before committing:
|
||||
|
||||
```bash
|
||||
uv run pytest --cov=supervision
|
||||
uv run pre-commit run --all-files
|
||||
```
|
||||
|
||||
- All pre-commit hooks must pass (formatting, linting, type checking, spell check, etc.).
|
||||
- All tests must pass before opening a PR. Note: some existing tests in the repo may
|
||||
already be failing — your changes must not introduce new failures.
|
||||
- Fix any issues reported and re-run until clean.
|
||||
@@ -0,0 +1,5 @@
|
||||
# Claude Code Project Instructions
|
||||
|
||||
<!-- Imports AGENTS.md, which contains agent roles, behavioral rules, and coding constraints for this project. -->
|
||||
|
||||
@AGENTS.md
|
||||
@@ -16,15 +16,16 @@
|
||||
|
||||
[](https://badge.fury.io/py/supervision)
|
||||
[](https://pypistats.org/packages/supervision)
|
||||
[](https://snyk.io/advisor/python/supervision)
|
||||
[](https://github.com/roboflow/supervision/blob/main/LICENSE.md)
|
||||
[](LICENSE.md)
|
||||
[](https://badge.fury.io/py/supervision)
|
||||
[](https://codecov.io/gh/roboflow/supervision)
|
||||
|
||||
[](https://snyk.io/advisor/python/supervision)
|
||||
[](https://colab.research.google.com/github/roboflow/supervision/blob/main/demo.ipynb)
|
||||
[](https://huggingface.co/spaces/Roboflow/Annotators)
|
||||
[](https://discord.gg/GbfgXGJ8Bk)
|
||||
[](https://squidfunk.github.io/mkdocs-material/)
|
||||
|
||||
<div align="center">
|
||||
<div align="center">
|
||||
<a href="https://trendshift.io/repositories/124" target="_blank"><img src="https://trendshift.io/api/badge/repositories/124" alt="roboflow%2Fsupervision | Trendshift" style="width: 250px; height: 55px;" width="250" height="55"/></a>
|
||||
</div>
|
||||
|
||||
@@ -37,7 +38,7 @@
|
||||
## 💻 install
|
||||
|
||||
Pip install the supervision package in a
|
||||
[**Python>=3.8**](https://www.python.org/) environment.
|
||||
[**Python>=3.9**](https://www.python.org/) environment.
|
||||
|
||||
```bash
|
||||
pip install supervision
|
||||
@@ -49,17 +50,18 @@ Read more about conda, mamba, and installing from source 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/latest/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, MMDetection, or Inference. Other integrations, like `rfdetr`, already return `sv.Detections` directly.
|
||||
|
||||
Install the optional dependencies for this example with `pip install pillow rfdetr`.
|
||||
|
||||
```python
|
||||
import cv2
|
||||
import supervision as sv
|
||||
from ultralytics import YOLO
|
||||
from PIL import Image
|
||||
from rfdetr import RFDETRSmall
|
||||
|
||||
image = cv2.imread(...)
|
||||
model = YOLO("yolov8s.pt")
|
||||
result = model(image)[0]
|
||||
detections = sv.Detections.from_ultralytics(result)
|
||||
image = Image.open(...)
|
||||
model = RFDETRSmall()
|
||||
detections = model.predict(image, threshold=0.5)
|
||||
|
||||
len(detections)
|
||||
# 5
|
||||
@@ -70,21 +72,21 @@ len(detections)
|
||||
|
||||
- inference
|
||||
|
||||
Running with [Inference](https://github.com/roboflow/inference) requires a [Roboflow API KEY](https://docs.roboflow.com/api-reference/authentication#retrieve-an-api-key).
|
||||
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 import get_model
|
||||
```python
|
||||
import supervision as sv
|
||||
from PIL import Image
|
||||
from inference import get_model
|
||||
|
||||
image = cv2.imread(...)
|
||||
model = get_model(model_id="yolov8s-640", api_key=<ROBOFLOW API KEY>)
|
||||
result = model.infer(image)[0]
|
||||
detections = sv.Detections.from_inference(result)
|
||||
image = Image.open(...)
|
||||
model = get_model(model_id="rfdetr-small", api_key="ROBOFLOW_API_KEY")
|
||||
result = model.infer(image)[0]
|
||||
detections = sv.Detections.from_inference(result)
|
||||
|
||||
len(detections)
|
||||
# 5
|
||||
```
|
||||
len(detections)
|
||||
# 5
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
@@ -100,9 +102,7 @@ image = cv2.imread(...)
|
||||
detections = sv.Detections(...)
|
||||
|
||||
box_annotator = sv.BoxAnnotator()
|
||||
annotated_frame = box_annotator.annotate(
|
||||
scene=image.copy(),
|
||||
detections=detections)
|
||||
annotated_frame = box_annotator.annotate(scene=image.copy(), detections=detections)
|
||||
```
|
||||
|
||||
https://github.com/roboflow/supervision/assets/26109316/691e219c-0565-4403-9218-ab5644f39bce
|
||||
@@ -115,8 +115,8 @@ Supervision provides a set of [utils](https://supervision.roboflow.com/latest/da
|
||||
import supervision as sv
|
||||
from roboflow import Roboflow
|
||||
|
||||
project = Roboflow().workspace(<WORKSPACE_ID>).project(<PROJECT_ID>)
|
||||
dataset = project.version(<PROJECT_VERSION>).download("coco")
|
||||
project = Roboflow().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",
|
||||
@@ -124,10 +124,11 @@ ds = sv.DetectionDataset.from_coco(
|
||||
)
|
||||
|
||||
path, image, annotation = ds[0]
|
||||
# loads image on demand
|
||||
# loads image on demand
|
||||
|
||||
for path, image, annotation in ds:
|
||||
# loads image on demand
|
||||
pass
|
||||
```
|
||||
|
||||
<details close>
|
||||
@@ -135,99 +136,99 @@ for path, image, annotation in ds:
|
||||
|
||||
- load
|
||||
|
||||
```python
|
||||
dataset = sv.DetectionDataset.from_yolo(
|
||||
images_directory_path=...,
|
||||
annotations_directory_path=...,
|
||||
data_yaml_path=...
|
||||
)
|
||||
```python
|
||||
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)
|
||||
```python
|
||||
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']
|
||||
```python
|
||||
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=...
|
||||
)
|
||||
```python
|
||||
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=...
|
||||
)
|
||||
```
|
||||
```python
|
||||
sv.DetectionDataset.from_yolo(
|
||||
images_directory_path=...,
|
||||
annotations_directory_path=...,
|
||||
data_yaml_path=...,
|
||||
).as_pascal_voc(
|
||||
images_directory_path=...,
|
||||
annotations_directory_path=...,
|
||||
)
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
## 🎬 tutorials
|
||||
|
||||
Want to learn how to use Supervision? Explore our [how-to guides](https://supervision.roboflow.com/develop/how_to/detect_and_annotate/), [end-to-end examples](https://github.com/roboflow/supervision/tree/develop/examples), [cheatsheet](https://roboflow.github.io/cheatsheet-supervision/), and [cookbooks](https://supervision.roboflow.com/develop/cookbooks/)!
|
||||
Want to learn how to use Supervision? Explore our [how-to guides](https://supervision.roboflow.com/develop/how_to/detect_and_annotate/), [end-to-end examples](./examples), [cheatsheet](https://roboflow.github.io/cheatsheet-supervision/), and [cookbooks](https://supervision.roboflow.com/develop/cookbooks/)!
|
||||
|
||||
<br/>
|
||||
|
||||
<p align="left">
|
||||
<a href="https://youtu.be/hAWpsIuem10" title="Dwell Time Analysis with Computer Vision | Real-Time Stream Processing"><img src="https://github.com/SkalskiP/SkalskiP/assets/26109316/a742823d-c158-407d-b30f-063a5d11b4e1" alt="Dwell Time Analysis with Computer Vision | Real-Time Stream Processing" width="300px" align="left" /></a>
|
||||
<a href="https://youtu.be/hAWpsIuem10" title="Dwell Time Analysis with Computer Vision | Real-Time Stream Processing"><img src="https://github.com/user-attachments/assets/014cffc7-72b3-4c0a-bb89-6de265b2c06b" alt="Dwell Time Analysis with Computer Vision | Real-Time Stream Processing" width="300px" align="left" /></a>
|
||||
<a href="https://youtu.be/hAWpsIuem10" title="Dwell Time Analysis with Computer Vision | Real-Time Stream Processing"><strong>Dwell Time Analysis with Computer Vision | Real-Time Stream Processing</strong></a>
|
||||
<div><strong>Created: 5 Apr 2024</strong></div>
|
||||
<br/>Learn how to use computer vision to analyze wait times and optimize processes. This tutorial covers object detection, tracking, and calculating time spent in designated zones. Use these techniques to improve customer experience in retail, traffic management, or other scenarios.</p>
|
||||
@@ -235,7 +236,7 @@ Want to learn how to use Supervision? Explore our [how-to guides](https://superv
|
||||
<br/>
|
||||
|
||||
<p align="left">
|
||||
<a href="https://youtu.be/uWP6UjDeZvY" title="Speed Estimation & Vehicle Tracking | Computer Vision | Open Source"><img src="https://github.com/SkalskiP/SkalskiP/assets/26109316/61a444c8-b135-48ce-b979-2a5ab47c5a91" alt="Speed Estimation & Vehicle Tracking | Computer Vision | Open Source" width="300px" align="left" /></a>
|
||||
<a href="https://youtu.be/uWP6UjDeZvY" title="Speed Estimation & Vehicle Tracking | Computer Vision | Open Source"><img src="https://github.com/user-attachments/assets/b16b8e21-dc6c-4a73-a678-2f7d5d374793" alt="Speed Estimation & Vehicle Tracking | Computer Vision | Open Source" width="300px" align="left" /></a>
|
||||
<a href="https://youtu.be/uWP6UjDeZvY" title="Speed Estimation & Vehicle Tracking | Computer Vision | Open Source"><strong>Speed Estimation & Vehicle Tracking | Computer Vision | Open Source</strong></a>
|
||||
<div><strong>Created: 11 Jan 2024</strong></div>
|
||||
<br/>Learn how to track and estimate the speed of vehicles using YOLO, ByteTrack, and Roboflow Inference. This comprehensive tutorial covers object detection, multi-object tracking, filtering detections, perspective transformation, speed estimation, visualization improvements, and more.</p>
|
||||
@@ -256,7 +257,7 @@ Visit our [documentation](https://roboflow.github.io/supervision) page to learn
|
||||
|
||||
## 🏆 contribution
|
||||
|
||||
We love your input! Please see our [contributing guide](https://github.com/roboflow/supervision/blob/main/CONTRIBUTING.md) to get started. Thank you 🙏 to all our contributors!
|
||||
We love your input! Please see our [contributing guide](.github/CONTRIBUTING.md) to get started. Thank you 🙏 to all our contributors!
|
||||
|
||||
<p align="center">
|
||||
<a href="https://github.com/roboflow/supervision/graphs/contributors">
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
0d5d9799b1cc4a39825146388c6781eb
|
||||
@@ -0,0 +1,6 @@
|
||||
/*
|
||||
Strict-Transport-Security: max-age=31536000; includeSubDomains; preload
|
||||
X-Content-Type-Options: nosniff
|
||||
Referrer-Policy: strict-origin-when-cross-origin
|
||||
Permissions-Policy: camera=(), microphone=(), geolocation=()
|
||||
Content-Security-Policy: default-src 'self'; base-uri 'self'; object-src 'none'; frame-ancestors 'none'; img-src 'self' https: data:; media-src 'self' https: data:; font-src 'self' https: data:; style-src 'self'; script-src 'self'; connect-src 'self' https:;
|
||||
@@ -0,0 +1,27 @@
|
||||
---
|
||||
comments: true
|
||||
description: About Supervision, Roboflow's open-source Python library for building reusable computer vision workflows.
|
||||
---
|
||||
|
||||
# About Supervision
|
||||
|
||||
Supervision is an open-source Python library by Roboflow for building computer vision applications. It gives developers a model-agnostic toolkit for loading predictions, annotating images and video, tracking objects, counting detections in zones, processing datasets, and evaluating model performance.
|
||||
|
||||
The project centers on a unified `Detections` API with converters for supported outputs from Ultralytics, Roboflow Inference, Hugging Face Transformers, SAM, Detectron2, MMDetection, YOLO-NAS, PaddleDet, NCNN, Azure AI Vision, and VLM parsers such as Florence-2, PaliGemma, Qwen VL, Gemini, DeepSeek VL 2, and Moondream. That common representation lets teams change models without rewriting annotation, filtering, tracking, dataset, or metrics code.
|
||||
|
||||
Supervision is maintained by Roboflow and an open-source contributor community. The library is MIT licensed, developed in public on GitHub, and published on PyPI.
|
||||
|
||||
## Project Links
|
||||
|
||||
- Source code: [github.com/roboflow/supervision](https://github.com/roboflow/supervision)
|
||||
- Package: [pypi.org/project/supervision](https://pypi.org/project/supervision/)
|
||||
- Community: [Roboflow Discord](https://discord.gg/GbfgXGJ8Bk)
|
||||
- Roboflow: [roboflow.com](https://roboflow.com/)
|
||||
|
||||
## Maintainers and Contributors
|
||||
|
||||
Supervision has been shaped by Roboflow engineers and community contributors, including Piotr Skalski, Borda, onuralpszr, Soumik Mandal, and many others. The complete contributor history is available in the GitHub repository.
|
||||
|
||||
## Citation
|
||||
|
||||
If Supervision helps your research or production system, cite the project using the citation block in [llms.txt](https://supervision.roboflow.com/llms.txt) or link to the GitHub repository.
|
||||
+8
-1
@@ -1,10 +1,11 @@
|
||||
---
|
||||
comments: true
|
||||
description: API reference for supervision's assets module — download sample video and image files for demos, testing, and tutorials.
|
||||
---
|
||||
|
||||
# Assets
|
||||
|
||||
Supervision offers an assets download utility that allows you to download video files
|
||||
Supervision offers an assets download utility that allows you to download image and video files
|
||||
that you can use in your demos.
|
||||
|
||||
<div class="md-typeset">
|
||||
@@ -18,3 +19,9 @@ that you can use in your demos.
|
||||
</div>
|
||||
|
||||
:::supervision.assets.list.VideoAssets
|
||||
|
||||
<div class="md-typeset">
|
||||
<h2><a href="#supervision.assets.list.ImageAssets">ImageAssets</a></h2>
|
||||
</div>
|
||||
|
||||
:::supervision.assets.list.ImageAssets
|
||||
|
||||
+430
-102
@@ -1,4 +1,332 @@
|
||||
# CHANGELOG
|
||||
---
|
||||
description: "Full version history of the supervision Python library — release notes, breaking changes, new features, and deprecations for every version."
|
||||
date_modified: 2026-04-23
|
||||
---
|
||||
|
||||
# Changelog
|
||||
|
||||
### 0.28.0 <small>Apr 30, 2026</small>
|
||||
|
||||
- Added [#2159](https://github.com/roboflow/supervision/pull/2159): [`sv.CompactMask`](https://supervision.roboflow.com/develop/detection/compact_mask/#supervision.detection.compact_mask.CompactMask) for memory-efficient mask storage. Masks are stored as crop-region bounding boxes plus RLE-encoded data instead of full-resolution bitmaps, reducing memory by up to 240× for sparse masks. Integrates transparently with `sv.Detections.mask` — filtering, merging, and `area` all work without materialising the full array.
|
||||
|
||||
- Added [#2227](https://github.com/roboflow/supervision/pull/2227): [`sv.CompactMask.resize(new_image_shape)`](https://supervision.roboflow.com/develop/detection/compact_mask/#supervision.detection.compact_mask.CompactMask.resize) rescales all stored crops to match a new image resolution, enabling use across frames or after image resizing pipelines.
|
||||
|
||||
- Added [#2178](https://github.com/roboflow/supervision/pull/2178): [`sv.Detections.from_inference`](https://supervision.roboflow.com/latest/detection/core/#supervision.detection.core.Detections.from_inference) now supports compressed COCO RLE masks. Inference responses with `rle` or `rle_mask` fields containing a compressed counts string (as produced by `pycocotools`) are decoded directly into binary masks, avoiding a lossy polygon round-trip.
|
||||
|
||||
- Added [#2004](https://github.com/roboflow/supervision/pull/2004): [`sv.Color.from_hex`](https://supervision.roboflow.com/latest/utils/draw/#supervision.draw.color.Color.from_hex) now accepts 8-digit hexadecimal RGBA codes (e.g. `#ff00ff80`). [`Color.as_hex()`](https://supervision.roboflow.com/latest/utils/draw/#supervision.draw.color.Color.as_hex) serialises back, including alpha when not fully opaque. New utility functions `sv.hex_to_rgba`, `sv.rgba_to_hex`, and `sv.is_valid_hex` are exported at the top level.
|
||||
|
||||
- Added [#709](https://github.com/roboflow/supervision/pull/709): [`sv.BlurAnnotator`](https://supervision.roboflow.com/latest/detection/annotators/#supervision.annotators.core.BlurAnnotator) and [`sv.PixelateAnnotator`](https://supervision.roboflow.com/latest/detection/annotators/#supervision.annotators.core.PixelateAnnotator) now support dynamic sizing. When `kernel_size=None` or `pixel_size=None` (the new default), the size is computed per detection as a fraction of the shorter bounding-box dimension, producing consistent visual results across objects of different sizes.
|
||||
|
||||
- Added [#2186](https://github.com/roboflow/supervision/pull/2186): [`sv.InferenceSlicer`](https://supervision.roboflow.com/latest/detection/tools/inference_slicer/#supervision.detection.tools.inference_slicer.InferenceSlicer) now emits a warning when detections returned by the callback fall outside the tile boundaries, helping catch coordinate-system bugs in custom callbacks.
|
||||
|
||||
- Added [#2103](https://github.com/roboflow/supervision/pull/2103), [#2152](https://github.com/roboflow/supervision/pull/2152): New [`sv.Detections.from_sam3()`](https://supervision.roboflow.com/latest/detection/core/#supervision.detection.core.Detections.from_sam3) classmethod parses SAM3 PCS (text-prompted) and PVS (visual-prompted video segmentation) response formats into a standard `sv.Detections`, both from the local `inference` package and from Roboflow-hosted server responses.
|
||||
|
||||
- Added [#2154](https://github.com/roboflow/supervision/pull/2154): The library now uses Python's `logging` module instead of `print` for diagnostic output. Messages are emitted under the `supervision` logger so applications can capture, filter, or silence them through standard `logging` configuration.
|
||||
|
||||
- Added [#932](https://github.com/roboflow/supervision/pull/932): [`sv.ImageAssets`](https://supervision.roboflow.com/latest/assets/) for downloading sample images alongside existing video assets, useful for examples and tutorials.
|
||||
|
||||
- Changed [#2169](https://github.com/roboflow/supervision/pull/2169): [`sv.MeanAveragePrecisionResult`](https://supervision.roboflow.com/latest/metrics/mean_average_precision/) and related metric arrays (`mAP_scores`, `ap_per_class`, `iou_thresholds`, precision/recall) are now `float32` instead of `float64`. Reduces memory and speeds up computation; numerical results may differ in the last few digits.
|
||||
|
||||
- Changed [#2178](https://github.com/roboflow/supervision/pull/2178): [`sv.rle_to_mask`](https://supervision.roboflow.com/latest/detection/utils/converters/#supervision.detection.utils.converters.rle_to_mask) and [`sv.mask_to_rle`](https://supervision.roboflow.com/latest/detection/utils/converters/#supervision.detection.utils.converters.mask_to_rle) moved to `supervision.detection.utils.converters`. The old import path `supervision.dataset.utils` continues to work but is deprecated.
|
||||
|
||||
- Fixed [#2178](https://github.com/roboflow/supervision/pull/2178): [`sv.rle_to_mask`](https://supervision.roboflow.com/latest/detection/utils/converters/#supervision.detection.utils.converters.rle_to_mask) now returns `NDArray[bool]` as declared in its signature. Previously the implementation returned `uint8` despite the `bool` annotation; code that relied on the undocumented `uint8` output (e.g. `mask * 255` producing `uint8`) should wrap the result with `.astype(np.uint8)`.
|
||||
|
||||
- Fixed [#2210](https://github.com/roboflow/supervision/pull/2210): [`sv.VideoInfo.fps`](https://supervision.roboflow.com/latest/utils/video/#supervision.utils.video.VideoInfo) now returns a `float` instead of a truncated `int`. Previously, frame rates like 23.976, 29.97, and 59.94 were silently truncated, causing frame-timing drift that accumulates over long videos. The type of `VideoInfo.fps` has changed from `int` to `float`; callers that pass `fps` to APIs requiring an integer (such as `deque(maxlen=...)` or `TraceAnnotator(trace_length=...)`) should wrap the value with `int()`.
|
||||
|
||||
- Fixed [#2209](https://github.com/roboflow/supervision/pull/2209): [`sv.Detections.is_empty()`](https://supervision.roboflow.com/latest/detection/core/#supervision.detection.core.Detections.is_empty) now returns `True` for detections filtered down to zero rows, even when `tracker_id` is an empty array. Previously this case incorrectly returned `False`.
|
||||
|
||||
- Fixed [#2199](https://github.com/roboflow/supervision/pull/2199): [`sv.CSVSink`](https://supervision.roboflow.com/latest/detection/tools/save_detections/#supervision.detection.tools.csv_sink.CSVSink) now correctly slices numpy array values in `custom_data` per row. Previously the full array was written for every detection.
|
||||
|
||||
- Fixed [#2216](https://github.com/roboflow/supervision/pull/2216): [`sv.CSVSink`](https://supervision.roboflow.com/latest/detection/tools/save_detections/#supervision.detection.tools.csv_sink.CSVSink) and [`sv.JSONSink`](https://supervision.roboflow.com/latest/detection/tools/save_detections/#supervision.detection.tools.json_sink.JSONSink) now slice plain Python `list` and `tuple` values in `custom_data` per detection row. Lists and tuples matching the detection count are indexed per row, consistent with `np.ndarray` behavior.
|
||||
|
||||
- Fixed [#2217](https://github.com/roboflow/supervision/pull/2217): [`sv.TraceAnnotator`](https://supervision.roboflow.com/latest/detection/annotators/#supervision.annotators.core.TraceAnnotator) no longer crashes in `smooth` mode when a tracker remains stationary. Duplicate consecutive points caused `splprep` to fail; the annotator now deduplicates anchor points and falls back to a raw polyline when fewer than 4 unique points are available.
|
||||
|
||||
- Fixed [#2218](https://github.com/roboflow/supervision/pull/2218): [`load_coco_annotations`](https://supervision.roboflow.com/latest/datasets/core/) now rejects COCO annotations whose `file_name` escapes the images directory via `../` traversal or absolute paths, preventing path-traversal attacks from malicious annotation files.
|
||||
|
||||
- Fixed [#2187](https://github.com/roboflow/supervision/pull/2187): Extreme memory usage when loading OBB (oriented bounding box) datasets, caused by allocating full-image masks for each rotated box, has been resolved.
|
||||
|
||||
- Fixed [#2188](https://github.com/roboflow/supervision/pull/2188): [`sv.KeyPoints`](https://supervision.roboflow.com/latest/keypoint/core/#supervision.key_points.core.KeyPoints) boolean mask indexing now works correctly when all instances have the same keypoint count (uniform-count selection).
|
||||
|
||||
- Fixed [#2185](https://github.com/roboflow/supervision/pull/2185): [`sv.DetectionDataset.as_coco()`](https://supervision.roboflow.com/latest/datasets/core/#supervision.dataset.core.DetectionDataset.as_coco) now preserves `area` and `iscrowd` fields instead of silently dropping them in the round-trip.
|
||||
|
||||
- Fixed [#1746](https://github.com/roboflow/supervision/pull/1746): Precision loss when converting annotations with `force_mask=True` in dataset format converters.
|
||||
|
||||
- Fixed [#1991](https://github.com/roboflow/supervision/pull/1991): [`sv.PolygonZone`](https://supervision.roboflow.com/latest/detection/tools/polygon_zone/) no longer double-counts the same object when multiple zones overlap. Detection bounding boxes were incorrectly clipped to each zone's ROI before anchor computation, causing the same detection to appear at a different anchor point in each zone; anchor is now computed from the original bounding box so containment is independent per zone.
|
||||
|
||||
- Fixed [#1868](https://github.com/roboflow/supervision/pull/1868): [`sv.LineZone`](https://supervision.roboflow.com/latest/detection/tools/line_zone/) no longer mis-attributes crossings when a tracker reuses the same `tracker_id` across different classes. Class-aware bookkeeping prevents a new object from inheriting another class's prior crossing state.
|
||||
|
||||
- Fixed [#2022](https://github.com/roboflow/supervision/pull/2022): [`sv.process_video`](https://supervision.roboflow.com/latest/utils/video/#supervision.utils.video.process_video) now raises immediately when the user callback throws, instead of silently swallowing the exception and hanging until the writer is flushed.
|
||||
|
||||
- Fixed [#2156](https://github.com/roboflow/supervision/pull/2156): [`sv.DetectionDataset`](https://supervision.roboflow.com/latest/datasets/core/#supervision.dataset.core.DetectionDataset) now populates `data["class_name"]` on every loaded annotation, matching what model connectors produce. Downstream code can rely on `class_name` being present whether detections come from a dataset or a model.
|
||||
|
||||
- Fixed [#1364](https://github.com/roboflow/supervision/pull/1364): [`sv.ByteTrack`](https://supervision.roboflow.com/latest/trackers/#supervision.tracker.byte_tracker.core.ByteTrack) now preserves externally assigned `tracker_id` values instead of overwriting them with internal ids on the first update.
|
||||
|
||||
- Fixed [#1853](https://github.com/roboflow/supervision/pull/1853): [`sv.ConfusionMatrix`](https://supervision.roboflow.com/latest/detection/metrics/#supervision.metrics.detection.ConfusionMatrix) `evaluate_detection_batch` now matches predictions to ground truth correctly when multiple detections fall on the same target. Previously, double-counting inflated false-positive and false-negative counts.
|
||||
|
||||
- Fixed [#2136](https://github.com/roboflow/supervision/pull/2136): [`sv.MeanAverageRecall`](https://supervision.roboflow.com/latest/metrics/mean_average_recall/) now computes mAR@K using the top-K detections per image, matching the COCO definition. Previous values were inflated relative to `pycocotools`.
|
||||
|
||||
- Fixed [#1086](https://github.com/roboflow/supervision/pull/1086), [#265](https://github.com/roboflow/supervision/pull/265): COCO export and `force_masks` behaviour are now consistent across dataset formats. Empty polygons no longer raise during `as_coco`, and `force_masks=True` produces masks regardless of source format.
|
||||
|
||||
- Deprecated [#2215](https://github.com/roboflow/supervision/pull/2215): [`sv.ByteTrack`](https://supervision.roboflow.com/latest/trackers/#supervision.tracker.byte_tracker.core.ByteTrack) is deprecated in favour of `ByteTrackTracker` from the external [`trackers`](https://pypi.org/project/trackers/) package (`pip install trackers`). The update method is renamed from `update_with_detections()` to `update()`. Removal planned for `supervision-0.30.0`.
|
||||
|
||||
- Deprecated [#2214](https://github.com/roboflow/supervision/pull/2214): `supervision.keypoint` module is deprecated; use `supervision.key_points` instead. `create_tiles` in `supervision.utils.image`, `ensure_cv2_image_for_processing` in `supervision.utils.conversion`, and keypoint validation utilities in `supervision.validators` are deprecated. The `LMM` enum (use `VLM`) and `from_lmm` method (use `from_vlm`) were deprecated in 0.26.0; this release migrates their deprecation mechanism to `pydeprecate`.
|
||||
|
||||
- Deprecated: `normalized_xyxy` argument in [`sv.denormalize_boxes`](https://supervision.roboflow.com/latest/detection/utils/boxes/#supervision.detection.utils.boxes.denormalize_boxes) renamed to `xyxy`. Passing `normalized_xyxy=` now emits a `FutureWarning`; support will be removed in `supervision-0.30.0`.
|
||||
|
||||
### 0.27.0 <small>Nov 16, 2025</small>
|
||||
|
||||
- Added [#2008](https://github.com/roboflow/supervision/pull/2008): [`sv.filter_segments_by_distance`](https://supervision.roboflow.com/0.27.0/detection/utils/masks/#supervision.detection.utils.masks.filter_segments_by_distance) to keep the largest connected component and nearby components within an absolute or relative distance threshold. Useful for cleaning segmentation predictions from models such as SAM, SAM2, YOLO segmentation, and RF-DETR segmentation.
|
||||
|
||||
- Added [#2006](https://github.com/roboflow/supervision/pull/2006): [`sv.xyxy_to_mask`](https://supervision.roboflow.com/0.27.0/detection/utils/converters/#supervision.detection.utils.converters.xyxy_to_mask) to convert bounding boxes into 2D boolean masks, where each mask corresponds to a single box.
|
||||
|
||||
- Added [#1943](https://github.com/roboflow/supervision/pull/1943): [`sv.tint_image`](https://supervision.roboflow.com/0.27.0/utils/image/#supervision.utils.image.tint_image) to apply a solid color overlay to an image at a given opacity. Works with both NumPy and PIL inputs.
|
||||
|
||||
- Added [#1943](https://github.com/roboflow/supervision/pull/1943): [`sv.grayscale_image`](https://supervision.roboflow.com/0.27.0/utils/image/#supervision.utils.image.tint_image) to convert an image to 3 channel grayscale for compatibility with color based drawing utilities.
|
||||
|
||||
- Added [#2014](https://github.com/roboflow/supervision/pull/2014): [`sv.get_image_resolution_wh`](https://supervision.roboflow.com/0.27.0/utils/image/#supervision.utils.image.get_image_resolution_wh) as a unified way to read image width and height from NumPy and PIL inputs.
|
||||
|
||||
- Added [#1912](https://github.com/roboflow/supervision/pull/1912): [`sv.edit_distance`](https://supervision.roboflow.com/0.27.0/detection/utils/vlms/#supervision.detection.utils.vlms.edit_distance) for Levenshtein distance between two strings. Supports insert, delete, and substitute operations.
|
||||
|
||||
- Added [#1912](https://github.com/roboflow/supervision/pull/1912): [`sv.fuzzy_match_index`](https://supervision.roboflow.com/0.27.0/detection/utils/vlms/#supervision.detection.utils.vlms.fuzzy_match_index) to find the first close match in a list using edit distance.
|
||||
|
||||
- Changed [#2015](https://github.com/roboflow/supervision/pull/2015): [`sv.Detections.from_vlm`](https://supervision.roboflow.com/0.27.0/detection/core/#supervision.detection.core.Detections.from_vlm) and legacy `from_lmm` now support Qwen3 VL via `vlm=sv.VLM.QWEN_3_VL`.
|
||||
|
||||
- Changed [#1884](https://github.com/roboflow/supervision/pull/1884): [`sv.Detections.from_vlm`](https://supervision.roboflow.com/0.27.0/detection/core/#supervision.detection.core.Detections.from_vlm) and legacy `from_lmm` now support DeepSeek VL 2 via `vlm=sv.VLM.DEEPSEEK_VL_2`.
|
||||
|
||||
- Changed [#2015](https://github.com/roboflow/supervision/pull/2015): [`sv.Detections.from_vlm`](https://supervision.roboflow.com/0.27.0/detection/core/#supervision.detection.core.Detections.from_vlm) now parses Qwen 2.5 VL outputs more robustly and handles incomplete or truncated JSON responses.
|
||||
|
||||
- Changed [#2014](https://github.com/roboflow/supervision/pull/2014): [`sv.InferenceSlicer`](https://supervision.roboflow.com/0.27.0/detection/tools/inference_slicer/#supervision.detection.tools.inference_slicer.InferenceSlicer) now uses a new offset generation logic that removes redundant tiles and aligns borders cleanly. This reduces the number of processed tiles and shortens inference time without hurting detection quality.
|
||||
|
||||
- Changed [#2016](https://github.com/roboflow/supervision/pull/2016): [`sv.Detections`](https://supervision.roboflow.com/0.27.0/detection/core/#supervision.detection.core.Detections) now includes a `box_aspect_ratio` property for vectorized aspect ratio computation, useful for filtering detections based on box shape.
|
||||
|
||||
- Changed [#2001](https://github.com/roboflow/supervision/pull/2001): Significantly improved the performance of [`sv.box_iou_batch`](https://supervision.roboflow.com/0.27.0/detection/utils/iou_and_nms/#supervision.detection.utils.iou_and_nms.box_iou_batch). On internal benchmarks, processing runs approximately 2x to 5x faster.
|
||||
|
||||
- Changed [#1997](https://github.com/roboflow/supervision/pull/1997): [`sv.process_video`](https://supervision.roboflow.com/0.27.0/utils/video/#supervision.utils.video.process_video) now uses a threaded reader, processor, and writer pipeline. This removes I/O stalls and improves throughput while keeping the callback single threaded and safe for stateful models.
|
||||
|
||||
- Changed: [`sv.denormalize_boxes`](https://supervision.roboflow.com/0.27.0/detection/utils/boxes/#supervision.detection.utils.boxes.denormalize_boxes) now supports batch conversion of bounding boxes. The function accepts arrays of shape `(N, 4)` and returns a batch of absolute pixel coordinates.
|
||||
|
||||
- Changed [#1917](https://github.com/roboflow/supervision/pull/1917): [`sv.LabelAnnotator`](https://supervision.roboflow.com/0.27.0/detection/annotators/#supervision.annotators.core.LabelAnnotator) and [`sv.RichLabelAnnotator`](https://supervision.roboflow.com/0.27.0/detection/annotators/#supervision.annotators.core.RichLabelAnnotator) now accept `text_offset=(x, y)` to shift the label relative to `text_position`. Works with smart label position and line wrapping.
|
||||
|
||||
!!! failure "Removed"
|
||||
Removed the deprecated `overlap_ratio_wh` argument from `sv.InferenceSlicer`. Use the pixel based `overlap_wh` argument to control slice overlap.
|
||||
|
||||
!!! info "Tip"
|
||||
Convert your old ratio based overlap to pixel based overlap by multiplying each ratio by the slice dimensions.
|
||||
|
||||
```python
|
||||
# before
|
||||
|
||||
slice_wh = (640, 640)
|
||||
overlap_ratio_wh = (0.25, 0.25)
|
||||
|
||||
slicer = sv.InferenceSlicer(
|
||||
callback=callback,
|
||||
slice_wh=slice_wh,
|
||||
overlap_ratio_wh=overlap_ratio_wh,
|
||||
overlap_filter=sv.OverlapFilter.NON_MAX_SUPPRESSION,
|
||||
)
|
||||
|
||||
# after
|
||||
|
||||
overlap_wh = (
|
||||
int(overlap_ratio_wh[0] * slice_wh[0]),
|
||||
int(overlap_ratio_wh[1] * slice_wh[1]),
|
||||
)
|
||||
|
||||
slicer = sv.InferenceSlicer(
|
||||
callback=callback,
|
||||
slice_wh=slice_wh,
|
||||
overlap_wh=overlap_wh,
|
||||
overlap_filter=sv.OverlapFilter.NON_MAX_SUPPRESSION,
|
||||
)
|
||||
```
|
||||
|
||||
### 0.26.1 <small>Jul 22, 2025</small>
|
||||
|
||||
- Fixed [1894](https://github.com/roboflow/supervision/pull/1894): Error in [`sv.MeanAveragePrecision`](https://supervision.roboflow.com/0.26.1/metrics/mean_average_precision/#supervision.metrics.mean_average_precision.MeanAveragePrecision) where the area used for size-specific evaluation (small / medium / large) was always zero unless explicitly provided in `sv.Detections.data`.
|
||||
|
||||
- Fixed [1895](https://github.com/roboflow/supervision/pull/1895): `ID=0` bug in [`sv.MeanAveragePrecision`](https://supervision.roboflow.com/0.26.1/metrics/mean_average_precision/#supervision.metrics.mean_average_precision.MeanAveragePrecision) where objects were getting `0.0` mAP despite perfect IoU matches due to a bug in annotation ID assignment.
|
||||
|
||||
- Fixed [1898](https://github.com/roboflow/supervision/pull/1898): Issue where [`sv.MeanAveragePrecision`](https://supervision.roboflow.com/0.26.1/metrics/mean_average_precision/#supervision.metrics.mean_average_precision.MeanAveragePrecision) could return negative values when certain object size categories have no data.
|
||||
|
||||
- Fixed [1901](https://github.com/roboflow/supervision/pull/1901): `match_metric` support for [`sv.Detections.with_nms`](https://supervision.roboflow.com/0.26.1/metrics/mean_average_precision/#supervision.detection.core.Detections.with_nms).
|
||||
|
||||
- Fixed [1906](https://github.com/roboflow/supervision/pull/1906): `border_thickness` parameter usage for [`sv.PercentageBarAnnotator`](https://supervision.roboflow.com/0.26.1/metrics/mean_average_precision/#supervision.annotators.core.PercentageBarAnnotator).
|
||||
|
||||
### 0.26.0 <small>Jul 16, 2025</small>
|
||||
|
||||
!!! failure "Removed"
|
||||
`supervision-0.26.0` drops `python3.8` support and upgrade all codes to `python3.9` syntax style.
|
||||
|
||||
!!! info "Tip"
|
||||
Supervision’s documentation theme now has a fresh look that is consistent with the documentations of all Roboflow open-source projects. ([#1858](https://github.com/roboflow/supervision/pull/1858))
|
||||
|
||||
- Added [#1774](https://github.com/roboflow/supervision/pull/1774): Support for the IOS (Intersection over Smallest) overlap metric that measures how much of the smaller object is covered by the larger one in [`sv.Detections.with_nms`](https://supervision.roboflow.com/0.26.0/detection/core/#supervision.detection.core.Detections.with_nms), [`sv.Detections.with_nmm`](https://supervision.roboflow.com/0.26.0/detection/core/#supervision.detection.core.Detections.with_nmm), [`sv.box_iou_batch`](https://supervision.roboflow.com/0.26.0/detection/utils/iou_and_nms/#supervision.detection.utils.iou_and_nms.box_iou_batch), and [`sv.mask_iou_batch`](https://supervision.roboflow.com/0.26.0/detection/utils/iou_and_nms/#supervision.detection.utils.iou_and_nms.mask_iou_batch).
|
||||
|
||||
```python
|
||||
import numpy as np
|
||||
import supervision as sv
|
||||
|
||||
boxes_true = np.array([
|
||||
[100, 100, 200, 200],
|
||||
[300, 300, 400, 400]
|
||||
])
|
||||
boxes_detection = np.array([
|
||||
[150, 150, 250, 250],
|
||||
[320, 320, 420, 420]
|
||||
])
|
||||
|
||||
sv.box_iou_batch(
|
||||
boxes_true=boxes_true,
|
||||
boxes_detection=boxes_detection,
|
||||
overlap_metric=sv.OverlapMetric.IOU
|
||||
)
|
||||
|
||||
# array([[0.14285714, 0. ],
|
||||
# [0. , 0.47058824]])
|
||||
|
||||
sv.box_iou_batch(
|
||||
boxes_true=boxes_true,
|
||||
boxes_detection=boxes_detection,
|
||||
overlap_metric=sv.OverlapMetric.IOS
|
||||
)
|
||||
|
||||
# array([[0.25, 0. ],
|
||||
# [0. , 0.64]])
|
||||
```
|
||||
|
||||
- Added [#1874](https://github.com/roboflow/supervision/pull/1874): [`sv.box_iou`](https://supervision.roboflow.com/0.26.0/detection/utils/iou_and_nms/#supervision.detection.utils.iou_and_nms.box_iou) that efficiently computes the Intersection over Union (IoU) between two individual bounding boxes.
|
||||
|
||||
- Added [#1816](https://github.com/roboflow/supervision/pull/1816): Support for frame limitations and progress bar in [`sv.process_video`](https://supervision.roboflow.com/0.26.0/utils/video/#supervision.utils.video.process_video).
|
||||
|
||||
- Added [#1788](https://github.com/roboflow/supervision/pull/1788): Support for creating [`sv.KeyPoints`](https://supervision.roboflow.com/0.26.0/keypoint/core/#supervision.keypoint.core.KeyPoints) objects from [ViTPose](https://huggingface.co/docs/transformers/en/model_doc/vitpose) and [ViTPose++](https://huggingface.co/docs/transformers/en/model_doc/vitpose#vitpose-models) inference results via [`sv.KeyPoints.from_transformers`](https://supervision.roboflow.com/0.26.0/keypoint/core/#supervision.keypoint.core.KeyPoints.from_transformers).
|
||||
|
||||
- Added [#1823](https://github.com/roboflow/supervision/pull/1823): [`sv.xyxy_to_xcycarh`](https://supervision.roboflow.com/0.26.0/detection/utils/converters/#supervision.detection.utils.converters.xyxy_to_xcycarh) function to convert bounding box coordinates from `(x_min, y_min, x_max, y_max)` into measurement space to format `(center x, center y, aspect ratio, height)`, where the aspect ratio is `width / height`.
|
||||
|
||||
- Added [#1788](https://github.com/roboflow/supervision/pull/1788): [`sv.xyxy_to_xywh`](https://supervision.roboflow.com/0.26.0/detection/utils/converters/#supervision.detection.utils.converters.xyxy_to_xywh) function to convert bounding box coordinates from `(x_min, y_min, x_max, y_max)` format to `(x, y, width, height)` format.
|
||||
|
||||
- Changed [#1820](https://github.com/roboflow/supervision/pull/1820): [`sv.LabelAnnotator`](https://supervision.roboflow.com/0.26.0/detection/annotators/#supervision.annotators.core.LabelAnnotator) now supports the `smart_position` parameter to automatically keep labels within frame boundaries, and the `max_line_length` parameter to control text wrapping for long or multi-line labels.
|
||||
|
||||
- Changed [#1825](https://github.com/roboflow/supervision/pull/1825): [`sv.LabelAnnotator`](https://supervision.roboflow.com/0.26.0/detection/annotators/#supervision.annotators.core.LabelAnnotator) now supports non-string labels.
|
||||
|
||||
- Changed [#1792](https://github.com/roboflow/supervision/pull/1792): [`sv.Detections.from_vlm`](https://supervision.roboflow.com/0.26.0/detection/core/#supervision.detection.core.Detections.from_vlm) now supports parsing bounding boxes and segmentation masks from responses generated by [Google Gemini models](https://ai.google.dev/gemini-api/docs/vision).
|
||||
|
||||
```python
|
||||
import supervision as sv
|
||||
|
||||
gemini_response_text = """```json
|
||||
[
|
||||
{"box_2d": [543, 40, 728, 200], "label": "cat", "id": 1},
|
||||
{"box_2d": [653, 352, 820, 522], "label": "dog", "id": 2}
|
||||
]
|
||||
```"""
|
||||
|
||||
detections = sv.Detections.from_vlm(
|
||||
sv.VLM.GOOGLE_GEMINI_2_5,
|
||||
gemini_response_text,
|
||||
resolution_wh=(1000, 1000),
|
||||
classes=['cat', 'dog'],
|
||||
)
|
||||
|
||||
detections.xyxy
|
||||
# array([[543., 40., 728., 200.], [653., 352., 820., 522.]])
|
||||
|
||||
detections.data
|
||||
# {'class_name': array(['cat', 'dog'], dtype='<U26')}
|
||||
|
||||
detections.class_id
|
||||
# array([0, 1])
|
||||
```
|
||||
|
||||
- Changed [#1878](https://github.com/roboflow/supervision/pull/1878): [`sv.Detections.from_vlm`](https://supervision.roboflow.com/0.26.0/detection/core/#supervision.detection.core.Detections.from_vlm) now supports parsing bounding boxes from responses generated by [Moondream](https://github.com/vikhyat/moondream).
|
||||
|
||||
```python
|
||||
import supervision as sv
|
||||
|
||||
moondream_result = {
|
||||
'objects': [
|
||||
{
|
||||
'x_min': 0.5704046934843063,
|
||||
'y_min': 0.20069346576929092,
|
||||
'x_max': 0.7049859315156937,
|
||||
'y_max': 0.3012596592307091
|
||||
},
|
||||
{
|
||||
'x_min': 0.6210969910025597,
|
||||
'y_min': 0.3300672620534897,
|
||||
'x_max': 0.8417936339974403,
|
||||
'y_max': 0.4961046129465103
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
detections = sv.Detections.from_vlm(
|
||||
sv.VLM.MOONDREAM,
|
||||
moondream_result,
|
||||
resolution_wh=(1000, 1000),
|
||||
)
|
||||
|
||||
detections.xyxy
|
||||
# array([[1752.28, 818.82, 2165.72, 1229.14],
|
||||
# [1908.01, 1346.67, 2585.99, 2024.11]])
|
||||
```
|
||||
|
||||
- Changed [#1709](https://github.com/roboflow/supervision/pull/1709): [`sv.Detections.from_vlm`](https://supervision.roboflow.com/0.26.0/detection/core/#supervision.detection.core.Detections.from_vlm) now supports parsing bounding boxes from responses generated by [Qwen-2.5 VL](https://github.com/QwenLM/Qwen2.5-VL).
|
||||
|
||||
```python
|
||||
import supervision as sv
|
||||
|
||||
qwen_2_5_vl_result = """```json
|
||||
[
|
||||
{"bbox_2d": [139, 768, 315, 954], "label": "cat"},
|
||||
{"bbox_2d": [366, 679, 536, 849], "label": "dog"}
|
||||
]
|
||||
```"""
|
||||
|
||||
detections = sv.Detections.from_vlm(
|
||||
sv.VLM.QWEN_2_5_VL,
|
||||
qwen_2_5_vl_result,
|
||||
input_wh=(1000, 1000),
|
||||
resolution_wh=(1000, 1000),
|
||||
classes=['cat', 'dog'],
|
||||
)
|
||||
|
||||
detections.xyxy
|
||||
# array([[139., 768., 315., 954.], [366., 679., 536., 849.]])
|
||||
|
||||
detections.class_id
|
||||
# array([0, 1])
|
||||
|
||||
detections.data
|
||||
# {'class_name': array(['cat', 'dog'], dtype='<U10')}
|
||||
|
||||
detections.class_id
|
||||
# array([0, 1])
|
||||
```
|
||||
|
||||
- Changed [#1786](https://github.com/roboflow/supervision/pull/1786): Significantly improved the speed of HSV color mapping in [`sv.HeatMapAnnotator`](https://supervision.roboflow.com/0.26.0/detection/annotators/#supervision.annotators.core.HeatMapAnnotator), achieving approximately 28x faster performance on 1920x1080 frames.
|
||||
|
||||
- Fixed [#1834](https://github.com/roboflow/supervision/pull/1834): Supervision’s [`sv.MeanAveragePrecision`](https://supervision.roboflow.com/0.26.0/metrics/mean_average_precision/#supervision.metrics.mean_average_precision.MeanAveragePrecision) is now fully aligned with [pycocotools](https://github.com/ppwwyyxx/cocoapi), the official COCO evaluation tool, ensuring accurate and standardized metrics. This update enabled us to launch a new version of the [Computer Vision Model Leaderboard](https://leaderboard.roboflow.com/).
|
||||
|
||||
```python
|
||||
import supervision as sv
|
||||
from supervision.metrics import MeanAveragePrecision
|
||||
|
||||
predictions = sv.Detections(...)
|
||||
targets = sv.Detections(...)
|
||||
|
||||
map_metric = MeanAveragePrecision()
|
||||
map_metric.update(predictions, targets).compute()
|
||||
|
||||
# Average Precision (AP) @[ IoU=0.50:0.95 | area= all | maxDets=100 ] = 0.464
|
||||
# Average Precision (AP) @[ IoU=0.50 | area= all | maxDets=100 ] = 0.637
|
||||
# Average Precision (AP) @[ IoU=0.75 | area= all | maxDets=100 ] = 0.203
|
||||
# Average Precision (AP) @[ IoU=0.50:0.95 | area= small | maxDets=100 ] = 0.284
|
||||
# Average Precision (AP) @[ IoU=0.50:0.95 | area=medium | maxDets=100 ] = 0.497
|
||||
# Average Precision (AP) @[ IoU=0.50:0.95 | area= large | maxDets=100 ] = 0.629
|
||||
```
|
||||
|
||||
- Fixed [#1767](https://github.com/roboflow/supervision/pull/1767): Fixed losing `sv.Detections.data` when detections filtering.
|
||||
|
||||
### 0.25.0 <small>Nov 12, 2024</small>
|
||||
|
||||
@@ -38,7 +366,7 @@ sv.process_video(
|
||||
|
||||
- Added `as_detections` method to [`KeyPoints`](https://supervision.roboflow.com/0.25.0/keypoint/core/#supervision.keypoint.core.KeyPoints) that converts `KeyPoints` to `Detections`. ([#1658](https://github.com/roboflow/supervision/pull/1658))
|
||||
|
||||
- Added a new video to `supervision[assets]`. ([#1657](https://github.com/roboflow/supervision/pull/1657))
|
||||
- Added a new video to the `supervision.assets` download catalog. ([#1657](https://github.com/roboflow/supervision/pull/1657))
|
||||
|
||||
```python
|
||||
from supervision.assets import download_assets, VideoAssets
|
||||
@@ -382,9 +710,9 @@ detections = sv.Detections.from_sam(sam_result=sam_result)
|
||||
|
||||
- Changed [#1434](https://github.com/roboflow/supervision/pull/1434): [`InferenceSlicer`](https://supervision.roboflow.com/0.23.0/detection/tools/inference_slicer/) now features an `overlap_wh` parameter, making it easier to compute slice sizes when handling overlapping slices.
|
||||
|
||||
- Fix [#1448](https://github.com/roboflow/supervision/pull/1448): Various annotator type issues have been resolved, supporting expanded error handling.
|
||||
- Fixed [#1448](https://github.com/roboflow/supervision/pull/1448): Various annotator type issues have been resolved, supporting expanded error handling.
|
||||
|
||||
- Fix [#1348](https://github.com/roboflow/supervision/pull/1348): Introduced a new method for [seeking to a specific video frame](https://supervision.roboflow.com/0.23.0/utils/video/#supervision.utils.video.get_video_frames_generator), addressing cases where traditional seek methods were failing. It can be enabled with `iterative_seek=True`.
|
||||
- Fixed [#1348](https://github.com/roboflow/supervision/pull/1348): Introduced a new method for [seeking to a specific video frame](https://supervision.roboflow.com/0.23.0/utils/video/#supervision.utils.video.get_video_frames_generator), addressing cases where traditional seek methods were failing. It can be enabled with `iterative_seek=True`.
|
||||
|
||||
```python
|
||||
import supervision as sv
|
||||
@@ -397,7 +725,7 @@ for frame in sv.get_video_frames_generator(
|
||||
...
|
||||
```
|
||||
|
||||
- Fix [#1424](https://github.com/roboflow/supervision/pull/1424): `plot_image` function now clearly indicates that the size is in inches.
|
||||
- Fixed [#1424](https://github.com/roboflow/supervision/pull/1424): `plot_image` function now clearly indicates that the size is in inches.
|
||||
|
||||
!!! failure "Removed"
|
||||
|
||||
@@ -646,9 +974,9 @@ annotated_image = label_annotator.annotate(
|
||||
|
||||
### 0.20.0 <small>April 24, 2024</small>
|
||||
|
||||
- Added [#1128](https://github.com/roboflow/supervision/pull/1128): [`sv.KeyPoints`](/0.20.0/keypoint/core/#supervision.keypoint.core.KeyPoints) to provide initial support for pose estimation and broader keypoint detection models.
|
||||
- Added [#1128](https://github.com/roboflow/supervision/pull/1128): [`sv.KeyPoints`](https://supervision.roboflow.com/0.20.0/keypoint/core/#supervision.keypoint.core.KeyPoints) to provide initial support for pose estimation and broader keypoint detection models.
|
||||
|
||||
- Added [#1128](https://github.com/roboflow/supervision/pull/1128): [`sv.EdgeAnnotator`](/0.20.0/keypoint/annotators/#supervision.keypoint.annotators.EdgeAnnotator) and [`sv.VertexAnnotator`](/0.20.0/keypoint/annotators/#supervision.keypoint.annotators.VertexAnnotator) to enable rendering of results from keypoint detection models.
|
||||
- Added [#1128](https://github.com/roboflow/supervision/pull/1128): [`sv.EdgeAnnotator`](https://supervision.roboflow.com/0.20.0/keypoint/annotators/#supervision.keypoint.annotators.EdgeAnnotator) and [`sv.VertexAnnotator`](https://supervision.roboflow.com/0.20.0/keypoint/annotators/#supervision.keypoint.annotators.VertexAnnotator) to enable rendering of results from keypoint detection models.
|
||||
|
||||
```python
|
||||
import cv2
|
||||
@@ -665,17 +993,17 @@ edge_annotators = sv.EdgeAnnotator(color=sv.Color.GREEN, thickness=5)
|
||||
annotated_image = edge_annotators.annotate(image.copy(), keypoints)
|
||||
```
|
||||
|
||||
- Changed [#1037](https://github.com/roboflow/supervision/pull/1037): [`sv.LabelAnnotator`](/0.20.0/annotators/#supervision.annotators.core.LabelAnnotator) by adding an additional `corner_radius` argument that allows for rounding the corners of the bounding box.
|
||||
- Changed [#1037](https://github.com/roboflow/supervision/pull/1037): [`sv.LabelAnnotator`](https://supervision.roboflow.com/latest/detection/annotators/#supervision.annotators.core.LabelAnnotator) by adding an additional `corner_radius` argument that allows for rounding the corners of the bounding box.
|
||||
|
||||
- Changed [#1109](https://github.com/roboflow/supervision/pull/1109): [`sv.PolygonZone`](/0.20.0/detection/tools/polygon_zone/#supervision.detection.tools.polygon_zone.PolygonZone) such that the `frame_resolution_wh` argument is no longer required to initialize `sv.PolygonZone`.
|
||||
- Changed [#1109](https://github.com/roboflow/supervision/pull/1109): [`sv.PolygonZone`](https://supervision.roboflow.com/0.20.0/detection/tools/polygon_zone/#supervision.detection.tools.polygon_zone.PolygonZone) such that the `frame_resolution_wh` argument is no longer required to initialize `sv.PolygonZone`.
|
||||
|
||||
!!! failure "Deprecated"
|
||||
|
||||
The `frame_resolution_wh` parameter in `sv.PolygonZone` is deprecated and will be removed in `supervision-0.24.0`.
|
||||
|
||||
- Changed [#1084](https://github.com/roboflow/supervision/pull/1084): [`sv.get_polygon_center`](/0.20.0/utils/geometry/#supervision.geometry.core.utils.get_polygon_center) to calculate a more accurate polygon centroid.
|
||||
- Changed [#1084](https://github.com/roboflow/supervision/pull/1084): [`sv.get_polygon_center`](https://supervision.roboflow.com/0.20.0/utils/geometry/#supervision.geometry.core.utils.get_polygon_center) to calculate a more accurate polygon centroid.
|
||||
|
||||
- Changed [#1069](https://github.com/roboflow/supervision/pull/1069): [`sv.Detections.from_transformers`](/0.20.0/detection/core/#supervision.detection.core.Detections.from_transformers) by adding support for Transformers segmentation models and extract class names values.
|
||||
- Changed [#1069](https://github.com/roboflow/supervision/pull/1069): [`sv.Detections.from_transformers`](https://supervision.roboflow.com/0.20.0/detection/core/#supervision.detection.core.Detections.from_transformers) by adding support for Transformers segmentation models and extract class names values.
|
||||
|
||||
```python
|
||||
import torch
|
||||
@@ -707,11 +1035,11 @@ annotated_image = label_annotator.annotate(
|
||||
scene=annotated_image, detections=detections)
|
||||
```
|
||||
|
||||
- Fixed [#787](https://github.com/roboflow/supervision/pull/787): [`sv.ByteTrack.update_with_detections`](/0.20.0/trackers/#supervision.tracker.byte_tracker.core.ByteTrack.update_with_detections) which was removing segmentation masks while tracking. Now, `ByteTrack` can be used alongside segmentation models.
|
||||
- Fixed [#787](https://github.com/roboflow/supervision/pull/787): [`sv.ByteTrack.update_with_detections`](https://supervision.roboflow.com/0.20.0/trackers/#supervision.tracker.byte_tracker.core.ByteTrack.update_with_detections) which was removing segmentation masks while tracking. Now, `ByteTrack` can be used alongside segmentation models.
|
||||
|
||||
### 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.
|
||||
- Added [#818](https://github.com/roboflow/supervision/pull/818): [`sv.CSVSink`](https://supervision.roboflow.com/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
|
||||
@@ -728,7 +1056,7 @@ with csv_sink:
|
||||
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.
|
||||
- Added [#819](https://github.com/roboflow/supervision/pull/819): [`sv.JSONSink`](https://supervision.roboflow.com/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
|
||||
import supervision as sv
|
||||
@@ -745,11 +1073,11 @@ with json_sink:
|
||||
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_iou_batch`](https://supervision.roboflow.com/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 [#847](https://github.com/roboflow/supervision/pull/847): [`sv.mask_non_max_suppression`](https://supervision.roboflow.com/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.
|
||||
- Added [#888](https://github.com/roboflow/supervision/pull/888): [`sv.CropAnnotator`](https://supervision.roboflow.com/0.19.0/annotators/#supervision.annotators.core.CropAnnotator) allowing users to annotate the scene with scaled-up crops of detections.
|
||||
|
||||
```python
|
||||
import cv2
|
||||
@@ -769,17 +1097,17 @@ annotated_frame = crop_annotator.annotate(
|
||||
)
|
||||
```
|
||||
|
||||
- Changed [#827](https://github.com/roboflow/supervision/pull/827): [`sv.ByteTrack.reset`](/0.19.0/trackers/#supervision.tracker.ByteTrack.reset) allowing users to clear trackers state, enabling the processing of multiple video files in sequence.
|
||||
- Changed [#827](https://github.com/roboflow/supervision/pull/827): [`sv.ByteTrack.reset`](https://supervision.roboflow.com/0.19.0/trackers/#supervision.tracker.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 [#802](https://github.com/roboflow/supervision/pull/802): [`sv.LineZoneAnnotator`](https://supervision.roboflow.com/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/trackers/#supervision.tracker.ByteTrack) input arguments and docstrings updated to improve readability and ease of use.
|
||||
- Changed [#787](https://github.com/roboflow/supervision/pull/787): [`sv.ByteTrack`](https://supervision.roboflow.com/0.19.0/trackers/#supervision.tracker.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.ByteTrack` 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.
|
||||
- Changed [#910](https://github.com/roboflow/supervision/pull/910): [`sv.PolygonZone`](https://supervision.roboflow.com/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"
|
||||
|
||||
@@ -787,11 +1115,11 @@ annotated_frame = crop_annotator.annotate(
|
||||
|
||||
- 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`.
|
||||
- Fixed [#944](https://github.com/roboflow/supervision/pull/944): [`sv.DetectionsSmoother`](https://supervision.roboflow.com/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.
|
||||
- Added [#720](https://github.com/roboflow/supervision/pull/720): [`sv.PercentageBarAnnotator`](https://supervision.roboflow.com/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
|
||||
@@ -806,9 +1134,9 @@ annotated_frame = crop_annotator.annotate(
|
||||
... )
|
||||
```
|
||||
|
||||
- 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 [#702](https://github.com/roboflow/supervision/pull/702): [`sv.RoundBoxAnnotator`](https://supervision.roboflow.com/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).
|
||||
- Added [#770](https://github.com/roboflow/supervision/pull/770): [`sv.OrientedBoxAnnotator`](https://supervision.roboflow.com/0.18.0/annotators/#orientedboxannotator) allowing to annotate images and videos with OBB (Oriented Bounding Boxes).
|
||||
|
||||
```python
|
||||
import cv2
|
||||
@@ -828,9 +1156,9 @@ annotated_frame = oriented_box_annotator.annotate(
|
||||
)
|
||||
```
|
||||
|
||||
- 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 [#696](https://github.com/roboflow/supervision/pull/696): [`sv.DetectionsSmoother`](https://supervision.roboflow.com/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.
|
||||
- Added [#769](https://github.com/roboflow/supervision/pull/769): [`sv.ColorPalette.from_matplotlib`](https://supervision.roboflow.com/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
|
||||
@@ -839,33 +1167,33 @@ annotated_frame = oriented_box_annotator.annotate(
|
||||
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 [#770](https://github.com/roboflow/supervision/pull/770): [`sv.Detections.from_ultralytics`](https://supervision.roboflow.com/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 [#735](https://github.com/roboflow/supervision/pull/735): [`sv.LineZone`](https://supervision.roboflow.com/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`).
|
||||
- Changed [#756](https://github.com/roboflow/supervision/pull/756): [`sv.Color`](https://supervision.roboflow.com/0.18.0/draw/color/#color)'s and [`sv.ColorPalette`](https://supervision.roboflow.com/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 [#769](https://github.com/roboflow/supervision/pull/769): [`sv.ColorPalette.DEFAULT`](https://supervision.roboflow.com/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).
|
||||
- Changed [#677](https://github.com/roboflow/supervision/pull/677): `sv.Detections.from_roboflow` to [`sv.Detections.from_inference`](https://supervision.roboflow.com/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.
|
||||
- Fixed [#735](https://github.com/roboflow/supervision/pull/735): [`sv.LineZone`](https://supervision.roboflow.com/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`](/0.17.0/annotators/#supervision.annotators.core.PixelateAnnotator) allowing to pixelate objects on images and videos.
|
||||
- Added [#633](https://github.com/roboflow/supervision/pull/633): [`sv.PixelateAnnotator`](https://supervision.roboflow.com/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`](/0.17.0/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`](https://supervision.roboflow.com/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`](/0.17.0/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`](https://supervision.roboflow.com/0.17.0/annotators/#supervision.annotators.core.PolygonAnnotator) allowing to annotate images and videos with segmentation mask outline.
|
||||
|
||||
```python
|
||||
>>> import supervision as sv
|
||||
@@ -880,7 +1208,7 @@ ColorPalette(colors=[Color(r=68, g=1, b=84), Color(r=59, g=82, b=139), ...])
|
||||
... )
|
||||
```
|
||||
|
||||
- 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.
|
||||
- Added [#476](https://github.com/roboflow/supervision/pull/476): [`sv.assets`](https://supervision.roboflow.com/0.18.0/assets/) allowing download of video files that you can use in your demos.
|
||||
|
||||
```python
|
||||
>>> from supervision.assets import download_assets, VideoAssets
|
||||
@@ -888,35 +1216,35 @@ ColorPalette(colors=[Color(r=68, g=1, b=84), Color(r=59, g=82, b=139), ...])
|
||||
"vehicles.mp4"
|
||||
```
|
||||
|
||||
- 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 [#605](https://github.com/roboflow/supervision/pull/605): [`Position.CENTER_OF_MASS`](https://supervision.roboflow.com/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`](/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 [#651](https://github.com/roboflow/supervision/pull/651): [`sv.scale_boxes`](https://supervision.roboflow.com/0.17.0/detection/utils/#supervision.detection.utils.scale_boxes) allowing to scale [`sv.Detections.xyxy`](https://supervision.roboflow.com/0.17.0/detection/core/#supervision.detection.core.Detections) values.
|
||||
|
||||
- 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 [#637](https://github.com/roboflow/supervision/pull/637): [`sv.calculate_dynamic_text_scale`](https://supervision.roboflow.com/0.17.0/draw/utils/#supervision.draw.utils.calculate_dynamic_text_scale) and [`sv.calculate_dynamic_line_thickness`](https://supervision.roboflow.com/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`](/0.17.0/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`](https://supervision.roboflow.com/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`](/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 [#572](https://github.com/roboflow/supervision/pull/572): [`sv.Classifications.from_timm`](https://supervision.roboflow.com/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`](/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 [#478](https://github.com/roboflow/supervision/pull/478): [`sv.Classifications.from_clip`](https://supervision.roboflow.com/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`](/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).
|
||||
- Added [#571](https://github.com/roboflow/supervision/pull/571): [`sv.Detections.from_azure_analyze_image`](https://supervision.roboflow.com/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`](/0.17.0/annotators/#supervision.annotators.core.ColorAnnotator).
|
||||
- Changed [#646](https://github.com/roboflow/supervision/pull/646): `sv.BoxMaskAnnotator` renaming it to [`sv.ColorAnnotator`](https://supervision.roboflow.com/0.17.0/annotators/#supervision.annotators.core.ColorAnnotator).
|
||||
|
||||
- Changed [#606](https://github.com/roboflow/supervision/pull/606): [`sv.MaskAnnotator`](/0.17.0/annotators/#supervision.annotators.core.MaskAnnotator) to make it **5x faster**.
|
||||
- Changed [#606](https://github.com/roboflow/supervision/pull/606): [`sv.MaskAnnotator`](https://supervision.roboflow.com/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`](/0.17.0/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`](https://supervision.roboflow.com/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`](/0.17.0/annotators/#supervision.annotators.core.BlurAnnotator) to trim negative coordinates before bluring detections.
|
||||
- Fixed [#555](https://github.com/roboflow/supervision/pull/555): [`sv.BlurAnnotator`](https://supervision.roboflow.com/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`](/0.17.0/annotators/#supervision.annotators.core.TraceAnnotator) to respect trace position.
|
||||
- Fixed [#511](https://github.com/roboflow/supervision/pull/511): [`sv.TraceAnnotator`](https://supervision.roboflow.com/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`](/0.16.0/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`](https://supervision.roboflow.com/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`](/0.16.0/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`](https://supervision.roboflow.com/0.16.0/annotators/#supervision.annotators.core.HaloAnnotator) allowing to annotate images and videos with halo effect.
|
||||
|
||||
```python
|
||||
>>> import supervision as sv
|
||||
@@ -931,45 +1259,45 @@ ColorPalette(colors=[Color(r=68, g=1, b=84), Color(r=59, g=82, b=139), ...])
|
||||
... )
|
||||
```
|
||||
|
||||
- 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 [#466](https://github.com/roboflow/supervision/pull/466): [`sv.HeatMapAnnotator`](https://supervision.roboflow.com/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`](/0.16.0/annotators/#supervision.annotators.core.DotAnnotator) allowing to annotate images and videos with dots.
|
||||
- Added [#492](https://github.com/roboflow/supervision/pull/492): [`sv.DotAnnotator`](https://supervision.roboflow.com/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`](/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 [#449](https://github.com/roboflow/supervision/pull/449): [`sv.draw_image`](https://supervision.roboflow.com/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`](/0.16.0/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`](https://supervision.roboflow.com/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.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 [#482](https://github.com/roboflow/supervision/pull/482): [`sv.LineZone.trigger`](https://supervision.roboflow.com/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`](/0.16.0/annotators/#supervision.annotators.core.MaskAnnotator) allowing 2x faster annotation.
|
||||
- Changed [#426](https://github.com/roboflow/supervision/pull/426): [`sv.MaskAnnotator`](https://supervision.roboflow.com/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`](/0.16.0/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`](https://supervision.roboflow.com/0.16.0/trackers/#supervision.tracker.byte_tracker.core.ByteTrack) to return `np.array([], dtype=int)` when `svDetections` is empty.
|
||||
|
||||
!!! failure "Deprecated"
|
||||
|
||||
`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).
|
||||
`sv.Detections.from_yolov8` and `sv.Classifications.from_yolov8` as those are now replaced by [`sv.Detections.from_ultralytics`](https://supervision.roboflow.com/0.16.0/detection/core/#supervision.detection.core.Detections.from_ultralytics) and [`sv.Classifications.from_ultralytics`](https://supervision.roboflow.com/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`](/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.BoundingBoxAnnotator`](https://supervision.roboflow.com/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 `](/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.BoxCornerAnnotator `](https://supervision.roboflow.com/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`](/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.MaskAnnotator`](https://supervision.roboflow.com/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`](/0.15.0/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`](https://supervision.roboflow.com/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`](/0.15.0/annotators/#supervision.annotators.core.CircleAnnotator) allowing to annotate images and videos with circles.
|
||||
- Added [#386](https://github.com/roboflow/supervision/pull/386): [`sv.CircleAnnotator`](https://supervision.roboflow.com/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`](/0.15.0/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`](https://supervision.roboflow.com/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`](/0.15.0/annotators/#supervision.annotators.core.BlurAnnotator) allowing to blur objects on images and videos.
|
||||
- Added [#405](https://github.com/roboflow/supervision/pull/405): [`sv.BlurAnnotator`](https://supervision.roboflow.com/0.15.0/annotators/#supervision.annotators.core.BlurAnnotator) allowing to blur objects on images and videos.
|
||||
|
||||
```python
|
||||
>>> import supervision as sv
|
||||
@@ -986,17 +1314,17 @@ ColorPalette(colors=[Color(r=68, g=1, b=84), Color(r=59, g=82, b=139), ...])
|
||||
|
||||
- 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`](/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 [#399](https://github.com/roboflow/supervision/pull/399): [`sv.Detections.from_roboflow`](https://supervision.roboflow.com/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`](/0.15.0/utils/video/#videosink) now allows to customize the output codec.
|
||||
- Changed [#381](https://github.com/roboflow/supervision/pull/381): [`sv.VideoSink`](https://supervision.roboflow.com/0.15.0/utils/video/#videosink) now allows to customize the output codec.
|
||||
|
||||
- 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.
|
||||
- Changed [#361](https://github.com/roboflow/supervision/pull/361): [`sv.InferenceSlicer`](https://supervision.roboflow.com/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`](/0.15.0/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`](https://supervision.roboflow.com/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`](/0.14.0/detection/tools/inference_slicer).
|
||||
- Added [#282](https://github.com/roboflow/supervision/pull/282): support for SAHI inference technique with [`sv.InferenceSlicer`](https://supervision.roboflow.com/0.14.0/detection/tools/inference_slicer).
|
||||
|
||||
```python
|
||||
>>> import cv2
|
||||
@@ -1015,23 +1343,23 @@ ColorPalette(colors=[Color(r=68, g=1, b=84), Color(r=59, g=82, b=139), ...])
|
||||
>>> detections = slicer(image)
|
||||
```
|
||||
|
||||
- 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 [#297](https://github.com/roboflow/supervision/pull/297): [`Detections.from_deepsparse`](https://supervision.roboflow.com/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`](/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.
|
||||
- Added [#281](https://github.com/roboflow/supervision/pull/281): [`sv.Classifications.from_ultralytics`](https://supervision.roboflow.com/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.
|
||||
|
||||
!!! failure "Deprecated"
|
||||
|
||||
[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.
|
||||
[sv.Detections.from_yolov8](https://supervision.roboflow.com/0.14.0/detection/core/#supervision.detection.core.Detections.from_yolov8) and [sv.Classifications.from_yolov8](https://supervision.roboflow.com/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`](/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.
|
||||
- Changed [#296](https://github.com/roboflow/supervision/pull/296): [`sv.ClassificationDataset`](https://supervision.roboflow.com/0.14.0/dataset/core/#supervision.dataset.core.ClassificationDataset) and [`sv.DetectionDataset`](https://supervision.roboflow.com/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`](/0.14.0/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`](https://supervision.roboflow.com/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`](/0.13.0/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`](https://supervision.roboflow.com/0.13.0/metrics/detection/#meanaverageprecision).
|
||||
|
||||
```python
|
||||
>>> import supervision as sv
|
||||
@@ -1053,17 +1381,17 @@ ColorPalette(colors=[Color(r=68, g=1, b=84), Color(r=59, g=82, b=139), ...])
|
||||
0.433
|
||||
```
|
||||
|
||||
- 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 [#256](https://github.com/roboflow/supervision/pull/256): support for ByteTrack for object tracking with [`sv.ByteTrack`](https://supervision.roboflow.com/0.13.0/tracker/core/#bytetrack).
|
||||
|
||||
- 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.
|
||||
- Added [#222](https://github.com/roboflow/supervision/pull/222): [`sv.Detections.from_ultralytics`](https://supervision.roboflow.com/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.
|
||||
|
||||
!!! failure "Deprecated"
|
||||
|
||||
[`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.
|
||||
[`sv.Detections.from_yolov8`](https://supervision.roboflow.com/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`](/0.13.0/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`](https://supervision.roboflow.com/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.`](/0.13.0/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.`](https://supervision.roboflow.com/0.13.0/dataset/core/#supervision.dataset.core.DetectionDataset.from_pascal_voc).
|
||||
|
||||
### 0.12.0 <small>July 24, 2023</small>
|
||||
|
||||
@@ -1071,7 +1399,7 @@ ColorPalette(colors=[Color(r=68, g=1, b=84), Color(r=59, g=82, b=139), ...])
|
||||
|
||||
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`](/0.12.0/metrics/detection/#confusionmatrix).
|
||||
- Added [#177](https://github.com/roboflow/supervision/pull/177): initial support for object detection model benchmarking with [`sv.ConfusionMatrix`](https://supervision.roboflow.com/0.12.0/metrics/detection/#confusionmatrix).
|
||||
|
||||
```python
|
||||
>>> import supervision as sv
|
||||
@@ -1098,23 +1426,23 @@ array([
|
||||
])
|
||||
```
|
||||
|
||||
- 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 [#173](https://github.com/roboflow/supervision/pull/173): [`Detections.from_mmdetection`](https://supervision.roboflow.com/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://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`](/0.12.0/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`](https://supervision.roboflow.com/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`](/0.12.0/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`](https://supervision.roboflow.com/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`](/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.
|
||||
- Fixed [#165](https://github.com/roboflow/supervision/pull/165): [`as_folder_structure`](https://supervision.roboflow.com/0.11.1/dataset/core/#supervision.dataset.core.ClassificationDataset.as_folder_structure) fails to save [`sv.ClassificationDataset`](https://supervision.roboflow.com/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`](/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.
|
||||
- Added [#150](https://github.com/roboflow/supervision/pull/150): ability to load and save [`sv.DetectionDataset`](https://supervision.roboflow.com/0.11.0/dataset/core/#detectiondataset) in COCO format using [`as_coco`](https://supervision.roboflow.com/0.11.0/dataset/core/#supervision.dataset.core.DetectionDataset.as_coco) and [`from_coco`](https://supervision.roboflow.com/0.11.0/dataset/core/#supervision.dataset.core.DetectionDataset.from_coco) methods.
|
||||
|
||||
```python
|
||||
>>> import supervision as sv
|
||||
@@ -1130,7 +1458,7 @@ array([
|
||||
... )
|
||||
```
|
||||
|
||||
- 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.
|
||||
- Added [#158](https://github.com/roboflow/supervision/pull/158): ability to merge multiple [`sv.DetectionDataset`](https://supervision.roboflow.com/0.11.0/dataset/core/#detectiondataset) together using [`merge`](https://supervision.roboflow.com/0.11.0/dataset/core/#supervision.dataset.core.DetectionDataset.merge) method.
|
||||
|
||||
```python
|
||||
>>> import supervision as sv
|
||||
@@ -1154,13 +1482,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`](/0.11.0/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`](https://supervision.roboflow.com/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`.
|
||||
- Fixed [#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`](/0.10.0/dataset/core/#classificationdataset) in a folder structure format.
|
||||
- Added [#125](https://github.com/roboflow/supervision/pull/125): ability to load and save [`sv.ClassificationDataset`](https://supervision.roboflow.com/0.10.0/dataset/core/#classificationdataset) in a folder structure format.
|
||||
|
||||
```python
|
||||
>>> import supervision as sv
|
||||
@@ -1174,9 +1502,9 @@ array([
|
||||
... )
|
||||
```
|
||||
|
||||
- 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 [#125](https://github.com/roboflow/supervision/pull/125): support for [`sv.ClassificationDataset.split`](https://supervision.roboflow.com/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`](/0.10.0/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`](https://supervision.roboflow.com/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.
|
||||
|
||||
@@ -1184,7 +1512,7 @@ array([
|
||||
|
||||
### 0.9.0 <small>June 7, 2023</small>
|
||||
|
||||
- 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.
|
||||
- Added [#118](https://github.com/roboflow/supervision/pull/118): ability to select [`sv.Detections`](https://supervision.roboflow.com/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
|
||||
@@ -1198,11 +1526,11 @@ array([
|
||||
2
|
||||
```
|
||||
|
||||
- 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 [#101](https://github.com/roboflow/supervision/pull/101): ability to extract masks from YOLOv8 result using [`sv.Detections.from_yolov8`](https://supervision.roboflow.com/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`](/0.9.0/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`](https://supervision.roboflow.com/0.9.0/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`](/0.9.0/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`](https://supervision.roboflow.com/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
|
||||
@@ -1212,12 +1540,12 @@ array([
|
||||
... sink.save_image(image=image)
|
||||
```
|
||||
|
||||
- Fixed [#106](https://github.com/roboflow/supervision/issues/106): inconvenient handling of [`sv.PolygonZone`](/0.8.0/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`](https://supervision.roboflow.com/0.8.0/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`](/0.8.0/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).
|
||||
- Added [#100](https://github.com/roboflow/supervision/pull/100): support for dataset inheritance. The current `Dataset` got renamed to `DetectionDataset`. Now [`DetectionDataset`](https://supervision.roboflow.com/0.8.0/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://supervision.roboflow.com/0.8.0/dataset/core/#supervision.dataset.core.DetectionDataset.as_yolo).
|
||||
|
||||
```python
|
||||
>>> import roboflow
|
||||
@@ -1241,7 +1569,7 @@ array([
|
||||
['dog', 'person']
|
||||
```
|
||||
|
||||
- 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.
|
||||
- Added [#103](https://github.com/roboflow/supervision/pull/103): support for [`DetectionDataset.split`](https://supervision.roboflow.com/0.8.0/dataset/core/#supervision.dataset.core.DetectionDataset.split) allowing to divide `DetectionDataset` into two parts.
|
||||
|
||||
```python
|
||||
>>> import supervision as sv
|
||||
|
||||
@@ -1,5 +1 @@
|
||||
# Code of conduct
|
||||
|
||||
```
|
||||
--8<-- "CODE_OF_CONDUCT.md"
|
||||
```
|
||||
--8<-- ".github/CODE_OF_CONDUCT.md"
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
---
|
||||
comments: true
|
||||
description: Contact and support channels for Supervision documentation, bugs, feature requests, security reports, and community help.
|
||||
---
|
||||
|
||||
# Contact
|
||||
|
||||
Use the channel that matches the kind of request you have.
|
||||
|
||||
## Bugs and Feature Requests
|
||||
|
||||
Open a GitHub issue for reproducible bugs, API requests, documentation fixes, and feature proposals:
|
||||
|
||||
[github.com/roboflow/supervision/issues](https://github.com/roboflow/supervision/issues)
|
||||
|
||||
## Community Support
|
||||
|
||||
Join the Roboflow Discord for community questions, examples, and implementation discussion:
|
||||
|
||||
[discord.gg/GbfgXGJ8Bk](https://discord.gg/GbfgXGJ8Bk)
|
||||
|
||||
## Package and Source
|
||||
|
||||
- PyPI package: [pypi.org/project/supervision](https://pypi.org/project/supervision/)
|
||||
- GitHub repository: [github.com/roboflow/supervision](https://github.com/roboflow/supervision)
|
||||
|
||||
## Security Reports
|
||||
|
||||
For security-sensitive reports, avoid posting public exploit details in an issue. Use GitHub's private vulnerability reporting flow for the repository when available, or contact Roboflow through the security and support channels listed on [roboflow.com](https://roboflow.com/).
|
||||
@@ -1 +1 @@
|
||||
--8<-- "CONTRIBUTING.md"
|
||||
--8<-- ".github/CONTRIBUTING.md"
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
---
|
||||
template: cookbooks.html
|
||||
comments: true
|
||||
description: Collection of practical computer vision cookbooks — object tracking, zero-shot detection, SAHI small object detection, occupancy analytics, and more.
|
||||
hide:
|
||||
- navigation
|
||||
- toc
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
---
|
||||
comments: true
|
||||
description: API reference for supervision's DetectionDataset and ClassificationDataset — load, merge, split, and convert datasets in YOLO, COCO, and VOC formats.
|
||||
---
|
||||
|
||||
# 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`.
|
||||
|
||||
|
||||
@@ -1,17 +0,0 @@
|
||||
---
|
||||
comments: true
|
||||
---
|
||||
|
||||
# Datasets Utils
|
||||
|
||||
<div class="md-typeset">
|
||||
<h2><a href="#supervision.dataset.utils.rle_to_mask">rle_to_mask</a></h2>
|
||||
</div>
|
||||
|
||||
:::supervision.dataset.utils.rle_to_mask
|
||||
|
||||
<div class="md-typeset">
|
||||
<h2><a href="#supervision.dataset.utils.mask_to_rle">mask_to_rle</a></h2>
|
||||
</div>
|
||||
|
||||
:::supervision.dataset.utils.mask_to_rle
|
||||
+16
-20
@@ -7,21 +7,17 @@ status: deprecated
|
||||
|
||||
These features are phased out due to better alternatives or potential issues in future versions. Deprecated functionalities are supported for **five subsequent releases**, providing time for users to transition to updated methods.
|
||||
|
||||
- Constructing [`DetectionDataset`](https://supervision.roboflow.com/latest/datasets/core/#supervision.dataset.core.DetectionDataset) and [`ClassificationDataset`](https://supervision.roboflow.com/latest/datasets/core/#supervision.dataset.core.ClassificationDataset) with parameter `images` as `Dict[str, np.ndarray]` will be removed in `supervision-0.26.0`. Please pass a list of paths `List[str]` instead.
|
||||
|
||||
- The `DetectionDataset.images` property will be removed in `supervision-0.26.0`. Please loop over images with `for path, image, annotation in dataset:`, as that does not require loading all images into memory.
|
||||
|
||||
- `BoundingBoxAnnotator` has been renamed to `BoxAnnotator` after the old implementation of [`BoxAnnotator`](https://supervision.roboflow.com/latest/detection/annotators/#supervision.annotators.core.BoxAnnotator) has been removed. `BoundingBoxAnnotator` will be removed in `supervision-0.26.0`.
|
||||
|
||||
- `overlap_filter_strategy` in [`InferenceSlicer.__init__`](https://supervision.roboflow.com/latest/detection/tools/inference_slicer/) is deprecated and will be removed in `supervision-0.27.0`. Use `overlap_strategy` instead.
|
||||
|
||||
- `overlap_ratio_wh` in [`InferenceSlicer.__init__`](https://supervision.roboflow.com/latest/detection/tools/inference_slicer/) is deprecated and will be removed in `supervision-0.27.0`. Use `overlap_wh` instead.
|
||||
- `overlap_ratio_wh` in [`InferenceSlicer.__init__`](https://supervision.roboflow.com/latest/detection/tools/inference_slicer/) is deprecated and will be removed in `supervision-0.27.0`. Please set it to `None` and use `overlap_wh` instead.
|
||||
- `sv.LMM` enum is deprecated and will be removed in `supervision-0.31.0`. Use `sv.VLM` instead.
|
||||
- [`sv.Detections.from_lmm`](https://supervision.roboflow.com/0.26.0/detection/core/#supervision.detection.core.Detections.from_lmm) property is deprecated and will be removed in `supervision-0.31.0`. Use [`sv.Detections.from_vlm`](https://supervision.roboflow.com/0.26.0/detection/core/#supervision.detection.core.Detections.from_vlm) instead.
|
||||
|
||||
# Removed
|
||||
|
||||
### 0.25.0
|
||||
### 0.26.0
|
||||
|
||||
- The `sv.DetectionDataset.images` property has been removed in `supervision-0.26.0`. Please loop over images with `for path, image, annotation in dataset:`, as that does not require loading all images into memory. Also, constructing `sv.DetectionDataset` with parameter `images` as `Dict[str, np.ndarray]` is deprecated and has been removed in `supervision-0.26.0`. Please pass a list of paths `List[str]` instead.
|
||||
- The name `sv.BoundingBoxAnnotator` is deprecated and has been removed in `supervision-0.26.0`. It has been renamed to [`sv.BoxAnnotator`](https://supervision.roboflow.com/0.22.0/detection/annotators/#supervision.annotators.core.BoxAnnotator).
|
||||
|
||||
No removals in this version!
|
||||
|
||||
### 0.24.0
|
||||
|
||||
@@ -35,12 +31,12 @@ No removals in this version!
|
||||
|
||||
### 0.22.0
|
||||
|
||||
- `Detections.from_roboflow` is removed as of `supervision-0.22.0`. Use [`Detections.from_inference`](detection/core.md/#supervision.detection.core.Detections.from_inference) instead.
|
||||
- The method `Color.white()` was removed as of `supervision-0.22.0`. Use the constant `Color.WHITE` instead.
|
||||
- The method `Color.black()` was removed as of `supervision-0.22.0`. Use the constant `Color.BLACK` instead.
|
||||
- The method `Color.red()` was removed as of `supervision-0.22.0`. Use the constant `Color.RED` instead.
|
||||
- The method `Color.green()` was removed as of `supervision-0.22.0`. Use the constant `Color.GREEN` instead.
|
||||
- The method `Color.blue()` was removed as of `supervision-0.22.0`. Use the constant `Color.BLUE` instead.
|
||||
- The method `ColorPalette.default()` was removed as of `supervision-0.22.0`. Use the constant [`ColorPalette.DEFAULT`](/utils/draw/#supervision.draw.color.ColorPalette.DEFAULT) instead.
|
||||
- `BoxAnnotator` was removed as of `supervision-0.22.0`, however `BoundingBoxAnnotator` was immediately renamed to `BoxAnnotator`. Use [`BoxAnnotator`](detection/annotators.md/#supervision.annotators.core.BoxAnnotator) and [`LabelAnnotator`](detection/annotators.md/#supervision.annotators.core.LabelAnnotator) instead of the old `BoxAnnotator`.
|
||||
- The method `FPSMonitor.__call__` was removed as of `supervision-0.22.0`. Use the attribute [`FPSMonitor.fps`](utils/video.md/#supervision.utils.video.FPSMonitor.fps) instead.
|
||||
- `sv.Detections.from_roboflow` is removed as of `supervision-0.22.0`. Use [`Detections.from_inference`](detection/core.md/#supervision.detection.core.Detections.from_inference) instead.
|
||||
- The method `sv.Color.white()` was removed as of `supervision-0.22.0`. Use the constant `sv.Color.WHITE` instead.
|
||||
- The method `sv.Color.black()` was removed as of `supervision-0.22.0`. Use the constant `sv.Color.BLACK` instead.
|
||||
- The method `sv.Color.red()` was removed as of `supervision-0.22.0`. Use the constant `sv.Color.RED` instead.
|
||||
- The method `sv.Color.green()` was removed as of `supervision-0.22.0`. Use the constant `sv.Color.GREEN` instead.
|
||||
- The method `sv.Color.blue()` was removed as of `supervision-0.22.0`. Use the constant `sv.Color.BLUE` instead.
|
||||
- The method `sv.ColorPalette.default()` was removed as of `supervision-0.22.0`. Use the constant [`ColorPalette.DEFAULT`](utils/draw.md/#supervision.draw.color.ColorPalette.DEFAULT) instead.
|
||||
- `sv.BoxAnnotator` was removed as of `supervision-0.22.0`, however `sv.BoundingBoxAnnotator` was immediately renamed to `sv.BoxAnnotator`. Use [`BoxAnnotator`](detection/annotators.md/#supervision.annotators.core.BoxAnnotator) and [`LabelAnnotator`](detection/annotators.md/#supervision.annotators.core.LabelAnnotator) instead of the old `sv.BoxAnnotator`.
|
||||
- The method `sv.FPSMonitor.__call__` was removed as of `supervision-0.22.0`. Use the attribute [`sv.FPSMonitor.fps`](utils/video.md/#supervision.utils.video.FPSMonitor.fps) instead.
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
---
|
||||
comments: true
|
||||
status: new
|
||||
description: API reference for supervision's annotator classes — draw bounding boxes, masks, labels, tracks, and heatmaps on images with one method call.
|
||||
---
|
||||
|
||||
# Annotators
|
||||
@@ -18,7 +18,7 @@ Annotators accept detections and apply box or mask visualizations to the detecti
|
||||
box_annotator = sv.BoxAnnotator()
|
||||
annotated_frame = box_annotator.annotate(
|
||||
scene=image.copy(),
|
||||
detections=detections
|
||||
detections=detections,
|
||||
)
|
||||
```
|
||||
|
||||
@@ -28,28 +28,26 @@ Annotators accept detections and apply box or mask visualizations to the detecti
|
||||
|
||||
</div>
|
||||
|
||||
<!--
|
||||
=== "RoundBox"
|
||||
=== "RoundBox"
|
||||
|
||||
```python
|
||||
import supervision as sv
|
||||
```python
|
||||
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>
|
||||
<div class="result" markdown>
|
||||
|
||||
{ align=center width="800" }
|
||||
{ align=center width="800" }
|
||||
|
||||
</div>
|
||||
-->
|
||||
</div>
|
||||
|
||||
=== "BoxCorner"
|
||||
|
||||
@@ -62,7 +60,7 @@ Annotators accept detections and apply box or mask visualizations to the detecti
|
||||
corner_annotator = sv.BoxCornerAnnotator()
|
||||
annotated_frame = corner_annotator.annotate(
|
||||
scene=image.copy(),
|
||||
detections=detections
|
||||
detections=detections,
|
||||
)
|
||||
```
|
||||
|
||||
@@ -83,7 +81,7 @@ Annotators accept detections and apply box or mask visualizations to the detecti
|
||||
color_annotator = sv.ColorAnnotator()
|
||||
annotated_frame = color_annotator.annotate(
|
||||
scene=image.copy(),
|
||||
detections=detections
|
||||
detections=detections,
|
||||
)
|
||||
```
|
||||
|
||||
@@ -104,7 +102,7 @@ Annotators accept detections and apply box or mask visualizations to the detecti
|
||||
circle_annotator = sv.CircleAnnotator()
|
||||
annotated_frame = circle_annotator.annotate(
|
||||
scene=image.copy(),
|
||||
detections=detections
|
||||
detections=detections,
|
||||
)
|
||||
```
|
||||
|
||||
@@ -125,7 +123,7 @@ Annotators accept detections and apply box or mask visualizations to the detecti
|
||||
dot_annotator = sv.DotAnnotator()
|
||||
annotated_frame = dot_annotator.annotate(
|
||||
scene=image.copy(),
|
||||
detections=detections
|
||||
detections=detections,
|
||||
)
|
||||
```
|
||||
|
||||
@@ -146,7 +144,7 @@ Annotators accept detections and apply box or mask visualizations to the detecti
|
||||
triangle_annotator = sv.TriangleAnnotator()
|
||||
annotated_frame = triangle_annotator.annotate(
|
||||
scene=image.copy(),
|
||||
detections=detections
|
||||
detections=detections,
|
||||
)
|
||||
```
|
||||
|
||||
@@ -167,7 +165,7 @@ Annotators accept detections and apply box or mask visualizations to the detecti
|
||||
ellipse_annotator = sv.EllipseAnnotator()
|
||||
annotated_frame = ellipse_annotator.annotate(
|
||||
scene=image.copy(),
|
||||
detections=detections
|
||||
detections=detections,
|
||||
)
|
||||
```
|
||||
|
||||
@@ -188,7 +186,7 @@ Annotators accept detections and apply box or mask visualizations to the detecti
|
||||
halo_annotator = sv.HaloAnnotator()
|
||||
annotated_frame = halo_annotator.annotate(
|
||||
scene=image.copy(),
|
||||
detections=detections
|
||||
detections=detections,
|
||||
)
|
||||
```
|
||||
|
||||
@@ -209,7 +207,7 @@ Annotators accept detections and apply box or mask visualizations to the detecti
|
||||
percentage_bar_annotator = sv.PercentageBarAnnotator()
|
||||
annotated_frame = percentage_bar_annotator.annotate(
|
||||
scene=image.copy(),
|
||||
detections=detections
|
||||
detections=detections,
|
||||
)
|
||||
```
|
||||
|
||||
@@ -230,14 +228,13 @@ Annotators accept detections and apply box or mask visualizations to the detecti
|
||||
mask_annotator = sv.MaskAnnotator()
|
||||
annotated_frame = mask_annotator.annotate(
|
||||
scene=image.copy(),
|
||||
detections=detections
|
||||
detections=detections,
|
||||
)
|
||||
```
|
||||
|
||||
<div class="result" markdown>
|
||||
|
||||
{ align=center width="800" }
|
||||
{ align=center width="800" }
|
||||
|
||||
</div>
|
||||
|
||||
@@ -252,14 +249,13 @@ Annotators accept detections and apply box or mask visualizations to the detecti
|
||||
polygon_annotator = sv.PolygonAnnotator()
|
||||
annotated_frame = polygon_annotator.annotate(
|
||||
scene=image.copy(),
|
||||
detections=detections
|
||||
detections=detections,
|
||||
)
|
||||
```
|
||||
|
||||
<div class="result" markdown>
|
||||
|
||||
{ align=center width="800" }
|
||||
{ align=center width="800" }
|
||||
|
||||
</div>
|
||||
|
||||
@@ -273,22 +269,21 @@ Annotators accept detections and apply box or mask visualizations to the detecti
|
||||
|
||||
labels = [
|
||||
f"{class_name} {confidence:.2f}"
|
||||
for class_name, confidence
|
||||
in zip(detections['class_name'], detections.confidence)
|
||||
for class_name, confidence in zip(
|
||||
detections["class_name"],
|
||||
detections.confidence,
|
||||
)
|
||||
]
|
||||
|
||||
label_annotator = sv.LabelAnnotator(text_position=sv.Position.CENTER)
|
||||
annotated_frame = label_annotator.annotate(
|
||||
scene=image.copy(),
|
||||
detections=detections,
|
||||
labels=labels
|
||||
scene=image.copy(), detections=detections, labels=labels
|
||||
)
|
||||
```
|
||||
|
||||
<div class="result" markdown>
|
||||
|
||||
{ align=center width="800" }
|
||||
{ align=center width="800" }
|
||||
|
||||
</div>
|
||||
|
||||
@@ -302,25 +297,26 @@ Annotators accept detections and apply box or mask visualizations to the detecti
|
||||
|
||||
labels = [
|
||||
f"{class_name} {confidence:.2f}"
|
||||
for class_name, confidence
|
||||
in zip(detections['class_name'], detections.confidence)
|
||||
for class_name, confidence in zip(
|
||||
detections["class_name"],
|
||||
detections.confidence,
|
||||
)
|
||||
]
|
||||
|
||||
rich_label_annotator = sv.RichLabelAnnotator(
|
||||
font_path="<TTF_FONT_PATH>",
|
||||
text_position=sv.Position.CENTER
|
||||
font_path="TTF_FONT_PATH",
|
||||
text_position=sv.Position.CENTER,
|
||||
)
|
||||
annotated_frame = rich_label_annotator.annotate(
|
||||
scene=image.copy(),
|
||||
detections=detections,
|
||||
labels=labels
|
||||
labels=labels,
|
||||
)
|
||||
```
|
||||
|
||||
<div class="result" markdown>
|
||||
|
||||
{ align=center width="800" }
|
||||
{ align=center width="800" }
|
||||
|
||||
</div>
|
||||
|
||||
@@ -332,46 +328,43 @@ Annotators accept detections and apply box or mask visualizations to the detecti
|
||||
image = ...
|
||||
detections = sv.Detections(...)
|
||||
|
||||
icon_paths = [
|
||||
"<ICON_PATH>"
|
||||
for _ in detections
|
||||
]
|
||||
icon_paths = ["<ICON_PATH>" for _ in detections]
|
||||
|
||||
icon_annotator = sv.IconAnnotator()
|
||||
annotated_frame = icon_annotator.annotate(
|
||||
scene=image.copy(),
|
||||
detections=detections,
|
||||
icon_path=icon_paths
|
||||
icon_path=icon_paths,
|
||||
)
|
||||
```
|
||||
|
||||
<div class="result" markdown>
|
||||
|
||||
{ align=center width="800" }
|
||||
{ align=center width="800" }
|
||||
|
||||
</div>
|
||||
|
||||
<!-- === "Crop"
|
||||
|
||||
```python
|
||||
import supervision as sv
|
||||
```python
|
||||
import supervision as sv
|
||||
|
||||
image = ...
|
||||
detections = sv.Detections(...)
|
||||
image = ...
|
||||
detections = sv.Detections(...)
|
||||
|
||||
crop_annotator = sv.CropAnnotator()
|
||||
annotated_frame = crop_annotator.annotate(
|
||||
scene=image.copy(),
|
||||
detections=detections
|
||||
)
|
||||
```
|
||||
<div class="result" markdown>
|
||||
crop_annotator = sv.CropAnnotator()
|
||||
annotated_frame = crop_annotator.annotate(
|
||||
scene=image.copy(),
|
||||
detections=detections,
|
||||
)
|
||||
```
|
||||
|
||||
{ align=center width="800" }
|
||||
<div class="result" markdown>
|
||||
|
||||
{ align=center width="800" }
|
||||
|
||||
</div>
|
||||
|
||||
</div>
|
||||
-->
|
||||
|
||||
=== "Blur"
|
||||
@@ -383,16 +376,12 @@ Annotators accept detections and apply box or mask visualizations to the detecti
|
||||
detections = sv.Detections(...)
|
||||
|
||||
blur_annotator = sv.BlurAnnotator()
|
||||
annotated_frame = blur_annotator.annotate(
|
||||
scene=image.copy(),
|
||||
detections=detections
|
||||
)
|
||||
annotated_frame = (blur_annotator.annotate(scene=image.copy(), detections=detections),)
|
||||
```
|
||||
|
||||
<div class="result" markdown>
|
||||
|
||||
{ align=center width="800" }
|
||||
{ align=center width="800" }
|
||||
|
||||
</div>
|
||||
|
||||
@@ -407,14 +396,13 @@ Annotators accept detections and apply box or mask visualizations to the detecti
|
||||
pixelate_annotator = sv.PixelateAnnotator()
|
||||
annotated_frame = pixelate_annotator.annotate(
|
||||
scene=image.copy(),
|
||||
detections=detections
|
||||
detections=detections,
|
||||
)
|
||||
```
|
||||
|
||||
<div class="result" markdown>
|
||||
|
||||
{ align=center width="800" }
|
||||
{ align=center width="800" }
|
||||
|
||||
</div>
|
||||
|
||||
@@ -424,29 +412,29 @@ Annotators accept detections and apply box or mask visualizations to the detecti
|
||||
import supervision as sv
|
||||
from ultralytics import YOLO
|
||||
|
||||
model = YOLO('yolov8x.pt')
|
||||
model = YOLO("yolov8x.pt")
|
||||
|
||||
trace_annotator = sv.TraceAnnotator()
|
||||
|
||||
video_info = sv.VideoInfo.from_video_path(video_path='...')
|
||||
frames_generator = sv.get_video_frames_generator(source_path='...')
|
||||
video_info = sv.VideoInfo.from_video_path(video_path="...")
|
||||
frames_generator = sv.get_video_frames_generator(source_path="...")
|
||||
tracker = sv.ByteTrack()
|
||||
|
||||
with sv.VideoSink(target_path='...', video_info=video_info) as sink:
|
||||
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)
|
||||
detections=detections,
|
||||
)
|
||||
sink.write_frame(frame=annotated_frame)
|
||||
```
|
||||
|
||||
<div class="result" markdown>
|
||||
|
||||
{ align=center width="800" }
|
||||
{ align=center width="800" }
|
||||
|
||||
</div>
|
||||
|
||||
@@ -456,27 +444,27 @@ Annotators accept detections and apply box or mask visualizations to the detecti
|
||||
import supervision as sv
|
||||
from ultralytics import YOLO
|
||||
|
||||
model = YOLO('yolov8x.pt')
|
||||
model = YOLO("yolov8x.pt")
|
||||
|
||||
heat_map_annotator = sv.HeatMapAnnotator()
|
||||
|
||||
video_info = sv.VideoInfo.from_video_path(video_path='...')
|
||||
frames_generator = sv.get_video_frames_generator(source_path='...')
|
||||
video_info = sv.VideoInfo.from_video_path(video_path="...")
|
||||
frames_generator = sv.get_video_frames_generator(source_path="...")
|
||||
|
||||
with sv.VideoSink(target_path='...', video_info=video_info) as sink:
|
||||
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)
|
||||
detections=detections,
|
||||
)
|
||||
sink.write_frame(frame=annotated_frame)
|
||||
```
|
||||
|
||||
<div class="result" markdown>
|
||||
|
||||
{ align=center width="800" }
|
||||
{ align=center width="800" }
|
||||
|
||||
</div>
|
||||
|
||||
@@ -491,7 +479,7 @@ Annotators accept detections and apply box or mask visualizations to the detecti
|
||||
background_overlay_annotator = sv.BackgroundOverlayAnnotator()
|
||||
annotated_frame = background_overlay_annotator.annotate(
|
||||
scene=image.copy(),
|
||||
detections=detections
|
||||
detections=detections,
|
||||
)
|
||||
```
|
||||
|
||||
@@ -514,14 +502,13 @@ Annotators accept detections and apply box or mask visualizations to the detecti
|
||||
annotated_frame = comparison_annotator.annotate(
|
||||
scene=image.copy(),
|
||||
detections_1=detections_1,
|
||||
detections_2=detections_2
|
||||
detections_2=detections_2,
|
||||
)
|
||||
```
|
||||
|
||||
<div class="result" markdown>
|
||||
|
||||
{ align=center width="800" }
|
||||
{ align=center width="800" }
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
@@ -0,0 +1,7 @@
|
||||
---
|
||||
comments: true
|
||||
---
|
||||
|
||||
# CompactMask
|
||||
|
||||
:::supervision.detection.compact_mask.CompactMask
|
||||
@@ -1,6 +1,6 @@
|
||||
---
|
||||
comments: true
|
||||
status: new
|
||||
description: API reference for supervision's Detections class — the core data structure for bounding boxes, masks, confidence scores, and tracker IDs.
|
||||
---
|
||||
|
||||
# Detections
|
||||
|
||||
@@ -1,29 +0,0 @@
|
||||
---
|
||||
comments: true
|
||||
---
|
||||
|
||||
# Double Detection Filter
|
||||
|
||||
<div class="md-typeset">
|
||||
<h2><a href="#supervision.detection.overlap_filter.OverlapFilter">OverlapFilter</a></h2>
|
||||
</div>
|
||||
|
||||
:::supervision.detection.overlap_filter.OverlapFilter
|
||||
|
||||
<div class="md-typeset">
|
||||
<h2><a href="#supervision.detection.overlap_filter.box_non_max_suppression">box_non_max_suppression</a></h2>
|
||||
</div>
|
||||
|
||||
:::supervision.detection.overlap_filter.box_non_max_suppression
|
||||
|
||||
<div class="md-typeset">
|
||||
<h2><a href="#supervision.detection.overlap_filter.mask_non_max_suppression">mask_non_max_suppression</a></h2>
|
||||
</div>
|
||||
|
||||
:::supervision.detection.overlap_filter.mask_non_max_suppression
|
||||
|
||||
<div class="md-typeset">
|
||||
<h2><a href="#supervision.detection.overlap_filter.box_non_max_merge">box_non_max_merge</a></h2>
|
||||
</div>
|
||||
|
||||
:::supervision.detection.overlap_filter.box_non_max_merge
|
||||
@@ -1,6 +1,5 @@
|
||||
---
|
||||
comments: true
|
||||
status: new
|
||||
---
|
||||
|
||||
<div class="md-typeset">
|
||||
|
||||
@@ -1,108 +0,0 @@
|
||||
---
|
||||
comments: true
|
||||
status: new
|
||||
---
|
||||
|
||||
# Detection Utils
|
||||
|
||||
<div class="md-typeset">
|
||||
<h2><a href="#supervision.detection.utils.box_iou_batch">box_iou_batch</a></h2>
|
||||
</div>
|
||||
|
||||
:::supervision.detection.utils.box_iou_batch
|
||||
|
||||
<div class="md-typeset">
|
||||
<h2><a href="#supervision.detection.utils.mask_iou_batch">mask_iou_batch</a></h2>
|
||||
</div>
|
||||
|
||||
:::supervision.detection.utils.mask_iou_batch
|
||||
|
||||
<div class="md-typeset">
|
||||
<h2><a href="#supervision.detection.utils.oriented_box_iou_batch">oriented_box_iou_batch</a></h2>
|
||||
</div>
|
||||
|
||||
:::supervision.detection.utils.oriented_box_iou_batch
|
||||
|
||||
<div class="md-typeset">
|
||||
<h2><a href="#supervision.detection.utils.polygon_to_mask">polygon_to_mask</a></h2>
|
||||
</div>
|
||||
|
||||
:::supervision.detection.utils.polygon_to_mask
|
||||
|
||||
<div class="md-typeset">
|
||||
<h2><a href="#supervision.detection.utils.mask_to_xyxy">mask_to_xyxy</a></h2>
|
||||
</div>
|
||||
|
||||
:::supervision.detection.utils.mask_to_xyxy
|
||||
|
||||
<div class="md-typeset">
|
||||
<h2><a href="#supervision.detection.utils.mask_to_polygons">mask_to_polygons</a></h2>
|
||||
</div>
|
||||
|
||||
:::supervision.detection.utils.mask_to_polygons
|
||||
|
||||
<div class="md-typeset">
|
||||
<h2><a href="#supervision.detection.utils.polygon_to_xyxy">polygon_to_xyxy</a></h2>
|
||||
</div>
|
||||
|
||||
:::supervision.detection.utils.polygon_to_xyxy
|
||||
|
||||
<div class="md-typeset">
|
||||
<h2><a href="#supervision.detection.utils.filter_polygons_by_area">filter_polygons_by_area</a></h2>
|
||||
</div>
|
||||
|
||||
:::supervision.detection.utils.filter_polygons_by_area
|
||||
|
||||
<div class="md-typeset">
|
||||
<h2><a href="#supervision.detection.utils.move_boxes">move_boxes</a></h2>
|
||||
</div>
|
||||
|
||||
:::supervision.detection.utils.move_boxes
|
||||
|
||||
<div class="md-typeset">
|
||||
<h2><a href="#supervision.detection.utils.move_masks">move_masks</a></h2>
|
||||
</div>
|
||||
|
||||
:::supervision.detection.utils.move_masks
|
||||
|
||||
<div class="md-typeset">
|
||||
<h2><a href="#supervision.detection.utils.scale_boxes">scale_boxes</a></h2>
|
||||
</div>
|
||||
|
||||
:::supervision.detection.utils.scale_boxes
|
||||
|
||||
<div class="md-typeset">
|
||||
<h2><a href="#supervision.detection.utils.clip_boxes">clip_boxes</a></h2>
|
||||
</div>
|
||||
|
||||
:::supervision.detection.utils.clip_boxes
|
||||
|
||||
<div class="md-typeset">
|
||||
<h2><a href="#supervision.detection.utils.pad_boxes">pad_boxes</a></h2>
|
||||
</div>
|
||||
|
||||
:::supervision.detection.utils.pad_boxes
|
||||
|
||||
<div class="md-typeset">
|
||||
<h2><a href="#supervision.detection.utils.xywh_to_xyxy">xywh_to_xyxy</a></h2>
|
||||
</div>
|
||||
|
||||
:::supervision.detection.utils.xywh_to_xyxy
|
||||
|
||||
<div class="md-typeset">
|
||||
<h2><a href="#supervision.detection.utils.xcycwh_to_xyxy">xcycwh_to_xyxy</a></h2>
|
||||
</div>
|
||||
|
||||
:::supervision.detection.utils.xcycwh_to_xyxy
|
||||
|
||||
<div class="md-typeset">
|
||||
<h2><a href="#supervision.detection.utils.contains_holes">contains_holes</a></h2>
|
||||
</div>
|
||||
|
||||
:::supervision.detection.utils.contains_holes
|
||||
|
||||
<div class="md-typeset">
|
||||
<h2><a href="#supervision.detection.utils.contains_multiple_segments">contains_multiple_segments</a></h2>
|
||||
</div>
|
||||
|
||||
:::supervision.detection.utils.contains_multiple_segments
|
||||
@@ -0,0 +1,35 @@
|
||||
---
|
||||
comments: true
|
||||
---
|
||||
|
||||
# Boxes Utils
|
||||
|
||||
<div class="md-typeset">
|
||||
<h2><a href="#supervision.detection.utils.boxes.move_boxes">move_boxes</a></h2>
|
||||
</div>
|
||||
|
||||
:::supervision.detection.utils.boxes.move_boxes
|
||||
|
||||
<div class="md-typeset">
|
||||
<h2><a href="#supervision.detection.utils.boxes.scale_boxes">scale_boxes</a></h2>
|
||||
</div>
|
||||
|
||||
:::supervision.detection.utils.boxes.scale_boxes
|
||||
|
||||
<div class="md-typeset">
|
||||
<h2><a href="#supervision.detection.utils.boxes.clip_boxes">clip_boxes</a></h2>
|
||||
</div>
|
||||
|
||||
:::supervision.detection.utils.boxes.clip_boxes
|
||||
|
||||
<div class="md-typeset">
|
||||
<h2><a href="#supervision.detection.utils.boxes.pad_boxes">pad_boxes</a></h2>
|
||||
</div>
|
||||
|
||||
:::supervision.detection.utils.boxes.pad_boxes
|
||||
|
||||
<div class="md-typeset">
|
||||
<h2><a href="#supervision.detection.utils.boxes.denormalize_boxes">denormalize_boxes</a></h2>
|
||||
</div>
|
||||
|
||||
:::supervision.detection.utils.boxes.denormalize_boxes
|
||||
@@ -0,0 +1,78 @@
|
||||
---
|
||||
comments: true
|
||||
status: new
|
||||
---
|
||||
|
||||
# Converters Utils
|
||||
|
||||
<div class="md-typeset">
|
||||
<h2><a href="#supervision.detection.utils.converters.xyxy_to_xywh">xyxy_to_xywh</a></h2>
|
||||
</div>
|
||||
|
||||
:::supervision.detection.utils.converters.xyxy_to_xywh
|
||||
|
||||
<div class="md-typeset">
|
||||
<h2><a href="#supervision.detection.utils.converters.xywh_to_xyxy">xywh_to_xyxy</a></h2>
|
||||
</div>
|
||||
|
||||
:::supervision.detection.utils.converters.xywh_to_xyxy
|
||||
|
||||
<div class="md-typeset">
|
||||
<h2><a href="#supervision.detection.utils.converters.xyxy_to_xcycarh">xyxy_to_xcycarh</a></h2>
|
||||
</div>
|
||||
|
||||
:::supervision.detection.utils.converters.xyxy_to_xcycarh
|
||||
|
||||
<div class="md-typeset">
|
||||
<h2><a href="#supervision.detection.utils.converters.xcycwh_to_xyxy">xcycwh_to_xyxy</a></h2>
|
||||
</div>
|
||||
|
||||
:::supervision.detection.utils.converters.xcycwh_to_xyxy
|
||||
|
||||
<div class="md-typeset">
|
||||
<h2><a href="#supervision.detection.utils.converters.xyxy_to_polygons">xyxy_to_polygons</a></h2>
|
||||
</div>
|
||||
|
||||
:::supervision.detection.utils.converters.xyxy_to_polygons
|
||||
|
||||
<div class="md-typeset">
|
||||
<h2><a href="#supervision.detection.utils.converters.mask_to_xyxy">mask_to_xyxy</a></h2>
|
||||
</div>
|
||||
|
||||
:::supervision.detection.utils.converters.mask_to_xyxy
|
||||
|
||||
<div class="md-typeset">
|
||||
<h2><a href="#supervision.detection.utils.converters.mask_to_polygons">mask_to_polygons</a></h2>
|
||||
</div>
|
||||
|
||||
:::supervision.detection.utils.converters.mask_to_polygons
|
||||
|
||||
<div class="md-typeset">
|
||||
<h2><a href="#supervision.detection.utils.converters.polygon_to_mask">polygon_to_mask</a></h2>
|
||||
</div>
|
||||
|
||||
:::supervision.detection.utils.converters.polygon_to_mask
|
||||
|
||||
<div class="md-typeset">
|
||||
<h2><a href="#supervision.detection.utils.converters.polygon_to_xyxy">polygon_to_xyxy</a></h2>
|
||||
</div>
|
||||
|
||||
:::supervision.detection.utils.converters.polygon_to_xyxy
|
||||
|
||||
<div class="md-typeset">
|
||||
<h2><a href="#supervision.detection.utils.converters.xyxy_to_mask">xyxy_to_mask</a></h2>
|
||||
</div>
|
||||
|
||||
:::supervision.detection.utils.converters.xyxy_to_mask
|
||||
|
||||
<div class="md-typeset">
|
||||
<h2><a href="#supervision.detection.utils.converters.rle_to_mask">rle_to_mask</a></h2>
|
||||
</div>
|
||||
|
||||
:::supervision.detection.utils.converters.rle_to_mask
|
||||
|
||||
<div class="md-typeset">
|
||||
<h2><a href="#supervision.detection.utils.converters.mask_to_rle">mask_to_rle</a></h2>
|
||||
</div>
|
||||
|
||||
:::supervision.detection.utils.converters.mask_to_rle
|
||||
@@ -0,0 +1,71 @@
|
||||
---
|
||||
comments: true
|
||||
---
|
||||
|
||||
# IoU and NMS Utils
|
||||
|
||||
<div class="md-typeset">
|
||||
<h2><a href="#supervision.detection.utils.iou_and_nms.OverlapFilter">OverlapFilter</a></h2>
|
||||
</div>
|
||||
|
||||
:::supervision.detection.utils.iou_and_nms.OverlapFilter
|
||||
|
||||
<div class="md-typeset">
|
||||
<h2><a href="#supervision.detection.utils.iou_and_nms.OverlapMetric">OverlapMetric</a></h2>
|
||||
</div>
|
||||
|
||||
:::supervision.detection.utils.iou_and_nms.OverlapMetric
|
||||
|
||||
<div class="md-typeset">
|
||||
<h2><a href="#supervision.detection.utils.iou_and_nms.utils.box_iou">box_iou</a></h2>
|
||||
</div>
|
||||
|
||||
:::supervision.detection.utils.iou_and_nms.box_iou
|
||||
|
||||
<div class="md-typeset">
|
||||
<h2><a href="#supervision.detection.utils.iou_and_nms.box_iou_batch">box_iou_batch</a></h2>
|
||||
</div>
|
||||
|
||||
:::supervision.detection.utils.iou_and_nms.box_iou_batch
|
||||
|
||||
<div class="md-typeset">
|
||||
<h2><a href="#supervision.detection.utils.iou_and_nms.box_iou_batch_with_jaccard">box_iou_batch_with_jaccard</a></h2>
|
||||
</div>
|
||||
|
||||
:::supervision.detection.utils.iou_and_nms.box_iou_batch_with_jaccard
|
||||
|
||||
<div class="md-typeset">
|
||||
<h2><a href="#supervision.detection.utils.iou_and_nms.mask_iou_batch">mask_iou_batch</a></h2>
|
||||
</div>
|
||||
|
||||
:::supervision.detection.utils.iou_and_nms.mask_iou_batch
|
||||
|
||||
<div class="md-typeset">
|
||||
<h2><a href="#supervision.detection.utils.iou_and_nms.oriented_box_iou_batch">oriented_box_iou_batch</a></h2>
|
||||
</div>
|
||||
|
||||
:::supervision.detection.utils.iou_and_nms.oriented_box_iou_batch
|
||||
|
||||
<div class="md-typeset">
|
||||
<h2><a href="#supervision.detection.utils.iou_and_nms.box_non_max_suppression">box_non_max_suppression</a></h2>
|
||||
</div>
|
||||
|
||||
:::supervision.detection.utils.iou_and_nms.box_non_max_suppression
|
||||
|
||||
<div class="md-typeset">
|
||||
<h2><a href="#supervision.detection.utils.iou_and_nms.mask_non_max_suppression">mask_non_max_suppression</a></h2>
|
||||
</div>
|
||||
|
||||
:::supervision.detection.utils.iou_and_nms.mask_non_max_suppression
|
||||
|
||||
<div class="md-typeset">
|
||||
<h2><a href="#supervision.detection.utils.iou_and_nms.box_non_max_merge">box_non_max_merge</a></h2>
|
||||
</div>
|
||||
|
||||
:::supervision.detection.utils.iou_and_nms.box_non_max_merge
|
||||
|
||||
<div class="md-typeset">
|
||||
<h2><a href="#supervision.detection.utils.iou_and_nms.mask_non_max_merge">mask_non_max_merge</a></h2>
|
||||
</div>
|
||||
|
||||
:::supervision.detection.utils.iou_and_nms.mask_non_max_merge
|
||||
@@ -0,0 +1,30 @@
|
||||
---
|
||||
comments: true
|
||||
status: new
|
||||
---
|
||||
|
||||
# Masks Utils
|
||||
|
||||
<div class="md-typeset">
|
||||
<h2><a href="#supervision.detection.utils.masks.move_masks">move_masks</a></h2>
|
||||
</div>
|
||||
|
||||
:::supervision.detection.utils.masks.move_masks
|
||||
|
||||
<div class="md-typeset">
|
||||
<h2><a href="#supervision.detection.utils.masks.contains_holes">contains_holes</a></h2>
|
||||
</div>
|
||||
|
||||
:::supervision.detection.utils.masks.contains_holes
|
||||
|
||||
<div class="md-typeset">
|
||||
<h2><a href="#supervision.detection.utils.masks.contains_multiple_segments">contains_multiple_segments</a></h2>
|
||||
</div>
|
||||
|
||||
:::supervision.detection.utils.masks.contains_multiple_segments
|
||||
|
||||
<div class="md-typeset">
|
||||
<h2><a href="#supervision.detection.utils.masks.filter_segments_by_distance">filter_segments_by_distance</a></h2>
|
||||
</div>
|
||||
|
||||
:::supervision.detection.utils.masks.filter_segments_by_distance
|
||||
@@ -0,0 +1,17 @@
|
||||
---
|
||||
comments: true
|
||||
---
|
||||
|
||||
# Polygons Utils
|
||||
|
||||
<div class="md-typeset">
|
||||
<h2><a href="#supervision.detection.utils.polygons.filter_polygons_by_area">filter_polygons_by_area</a></h2>
|
||||
</div>
|
||||
|
||||
:::supervision.detection.utils.polygons.filter_polygons_by_area
|
||||
|
||||
<div class="md-typeset">
|
||||
<h2><a href="#supervision.detection.utils.polygons.approximate_polygon">approximate_polygon</a></h2>
|
||||
</div>
|
||||
|
||||
:::supervision.detection.utils.polygons.approximate_polygon
|
||||
@@ -0,0 +1,18 @@
|
||||
---
|
||||
comments: true
|
||||
status: new
|
||||
---
|
||||
|
||||
# VLMs Utils
|
||||
|
||||
<div class="md-typeset">
|
||||
<h2><a href="#supervision.detection.utils.vlms.edit_distance">edit_distance</a></h2>
|
||||
</div>
|
||||
|
||||
:::supervision.detection.utils.vlms.edit_distance
|
||||
|
||||
<div class="md-typeset">
|
||||
<h2><a href="#supervision.detection.utils.vlms.fuzzy_match_index">fuzzy_match_index</a></h2>
|
||||
</div>
|
||||
|
||||
:::supervision.detection.utils.vlms.fuzzy_match_index
|
||||
+58
@@ -0,0 +1,58 @@
|
||||
---
|
||||
comments: true
|
||||
description: Frequently asked questions about installing Supervision, supported computer vision models, datasets, tracking, metrics, and licensing.
|
||||
---
|
||||
|
||||
# Frequently Asked Questions
|
||||
|
||||
## What is Supervision?
|
||||
|
||||
Supervision is an open-source Python library by Roboflow for computer vision workflows. It provides a unified `Detections` class with converters for supported object detection, segmentation, and VLM outputs.
|
||||
|
||||
## How do I install Supervision?
|
||||
|
||||
Install the base package with:
|
||||
|
||||
```bash
|
||||
pip install supervision
|
||||
```
|
||||
|
||||
Use the `metrics` extra when you need optional metric dependencies:
|
||||
|
||||
```bash
|
||||
pip install "supervision[metrics]"
|
||||
```
|
||||
|
||||
Sample asset utilities are part of the base package under `supervision.assets`.
|
||||
|
||||
## Which object detection models work with Supervision?
|
||||
|
||||
Supervision is model agnostic. `sv.Detections` includes converters for Ultralytics YOLO, Roboflow Inference, Hugging Face Transformers outputs, SAM, Detectron2, MMDetection, YOLO-NAS, PaddleDet, NCNN, Azure AI Vision, and VLM parsers including Florence-2, PaliGemma, Qwen VL, Gemini, DeepSeek VL 2, and Moondream. Keypoint outputs have separate `sv.KeyPoints` converters, including MediaPipe.
|
||||
|
||||
## What can I do with Supervision?
|
||||
|
||||
You can annotate images and video, filter detections, track objects, count objects in zones or across lines, load and convert datasets, evaluate models with detection metrics, and export predictions for downstream analysis.
|
||||
|
||||
## How do I track objects across video frames?
|
||||
|
||||
Assign persistent tracker IDs before visualization. The built-in `sv.ByteTrack` wrapper accepts `Detections` through `update_with_detections()`. After tracking, combine the output with annotators such as `sv.TraceAnnotator`, `sv.BoxAnnotator`, and `sv.LabelAnnotator`.
|
||||
|
||||
## What dataset formats does Supervision support?
|
||||
|
||||
For detection datasets, Supervision supports YOLO, COCO JSON, and Pascal VOC. Use `DetectionDataset.from_yolo()`, `DetectionDataset.from_coco()`, or `DetectionDataset.from_pascal_voc()` to load datasets, and the matching `as_*` methods to export them.
|
||||
|
||||
## How do I count objects in a zone?
|
||||
|
||||
Use `sv.PolygonZone` for arbitrary polygon regions and `sv.LineZone` for line-crossing counts. Line crossing requires `detections.tracker_id`, so run a tracker before calling the line zone trigger.
|
||||
|
||||
## How do I benchmark a model?
|
||||
|
||||
Use `supervision.metrics.mean_average_precision.MeanAveragePrecision` for mAP and `sv.ConfusionMatrix` for confusion matrices. Accumulate predictions and ground-truth `Detections`, then call `compute()` to calculate metrics.
|
||||
|
||||
## Is Supervision free to use?
|
||||
|
||||
Yes. Supervision is free and open source under the MIT license.
|
||||
|
||||
## Where is the source code?
|
||||
|
||||
The source code is available at [github.com/roboflow/supervision](https://github.com/roboflow/supervision).
|
||||
@@ -1,6 +1,11 @@
|
||||
---
|
||||
comments: true
|
||||
status: new
|
||||
description: Benchmark object detection models with supervision — compute mAP, confusion matrix, and per-class metrics to compare model performance.
|
||||
authors:
|
||||
- name: Piotr Skalski
|
||||
role: Computer Vision Engineer, Roboflow
|
||||
github: https://github.com/SkalskiP
|
||||
date_modified: 2026-04-22
|
||||
---
|
||||
|
||||

|
||||
@@ -52,7 +57,7 @@ from roboflow import Roboflow
|
||||
|
||||
rf = Roboflow(api_key="<YOUR_API_KEY>")
|
||||
project = rf.workspace("<WORKSPACE_NAME>").project("<PROJECT_NAME>")
|
||||
dataset = project.version(<DATASET_VERSION_NUMBER>).download("<FORMAT>")
|
||||
dataset = project.version("<DATASET_VERSION_NUMBER>").download("<FORMAT>")
|
||||
```
|
||||
|
||||
If your dataset is from Universe, go to `Dataset` > `Download Dataset` > select the format (e.g. `YOLOv11`) > `Show download code`.
|
||||
@@ -75,6 +80,8 @@ This will create a folder called `Corgi-v2-4` with the dataset in the current wo
|
||||
|
||||
Let's load a model.
|
||||
|
||||
Select and instantiate the detection or segmentation model you want to benchmark. Supervision works with Roboflow Inference for both local and cloud-deployed models, as well as Ultralytics YOLO checkpoints. Choose the tab below that matches your preferred framework, then pass images to the loaded model during the evaluation loop.
|
||||
|
||||
=== "Inference, Local"
|
||||
|
||||
Roboflow supports a range of state-of-the-art [pre-trained models](https://inference.roboflow.com/quickstart/aliases/) for object detection, instance segmentation, and pose tracking. You don't even need an API key!
|
||||
@@ -149,7 +156,7 @@ We'll use `supervision` to create a dataset iterator, and then run the model on
|
||||
test_set = sv.DetectionDataset.from_yolo(
|
||||
images_directory_path=f"{dataset.location}/test/images",
|
||||
annotations_directory_path=f"{dataset.location}/test/labels",
|
||||
data_yaml_path=f"{dataset.location}/data.yaml"
|
||||
data_yaml_path=f"{dataset.location}/data.yaml",
|
||||
)
|
||||
|
||||
image_paths = []
|
||||
@@ -173,7 +180,7 @@ We'll use `supervision` to create a dataset iterator, and then run the model on
|
||||
test_set = sv.DetectionDataset.from_yolo(
|
||||
images_directory_path=f"{dataset.location}/test/images",
|
||||
annotations_directory_path=f"{dataset.location}/test/labels",
|
||||
data_yaml_path=f"{dataset.location}/data.yaml"
|
||||
data_yaml_path=f"{dataset.location}/data.yaml",
|
||||
)
|
||||
|
||||
image_paths = []
|
||||
@@ -200,14 +207,16 @@ We need to remap them to match the dataset classes. Here's how to do it:
|
||||
def remap_classes(
|
||||
detections: sv.Detections,
|
||||
class_ids_from_to: dict[int, int],
|
||||
class_names_from_to: dict[str, str]
|
||||
class_names_from_to: dict[str, str],
|
||||
) -> None:
|
||||
new_class_ids = [
|
||||
class_ids_from_to.get(class_id, class_id) for class_id in detections.class_id]
|
||||
class_ids_from_to.get(class_id, class_id) for class_id in detections.class_id
|
||||
]
|
||||
detections.class_id = np.array(new_class_ids)
|
||||
|
||||
new_class_names = [
|
||||
class_names_from_to.get(name, name) for name in detections["class_name"]]
|
||||
class_names_from_to.get(name, name) for name in detections["class_name"]
|
||||
]
|
||||
predictions["class_name"] = np.array(new_class_names)
|
||||
```
|
||||
|
||||
@@ -223,7 +232,7 @@ Let's also remove the predictions that are not in the dataset classes.
|
||||
test_set = sv.DetectionDataset.from_yolo(
|
||||
images_directory_path=f"{dataset.location}/test/images",
|
||||
annotations_directory_path=f"{dataset.location}/test/labels",
|
||||
data_yaml_path=f"{dataset.location}/data.yaml"
|
||||
data_yaml_path=f"{dataset.location}/data.yaml",
|
||||
)
|
||||
|
||||
image_paths = []
|
||||
@@ -237,11 +246,9 @@ Let's also remove the predictions that are not in the dataset classes.
|
||||
remap_classes(
|
||||
detections=predictions,
|
||||
class_ids_from_to={16: 0},
|
||||
class_names_from_to={"dog": "Corgi"}
|
||||
class_names_from_to={"dog": "Corgi"},
|
||||
)
|
||||
predictions = predictions[
|
||||
np.isin(predictions["class_name"], test_set.classes)
|
||||
]
|
||||
predictions = predictions[np.isin(predictions["class_name"], test_set.classes),]
|
||||
|
||||
image_paths.append(image_path)
|
||||
predictions_list.append(predictions)
|
||||
@@ -261,7 +268,7 @@ Let's also remove the predictions that are not in the dataset classes.
|
||||
test_set = sv.DetectionDataset.from_yolo(
|
||||
images_directory_path=f"{dataset.location}/test/images",
|
||||
annotations_directory_path=f"{dataset.location}/test/labels",
|
||||
data_yaml_path=f"{dataset.location}/data.yaml"
|
||||
data_yaml_path=f"{dataset.location}/data.yaml",
|
||||
)
|
||||
|
||||
image_paths = []
|
||||
@@ -275,11 +282,9 @@ Let's also remove the predictions that are not in the dataset classes.
|
||||
remap_classes(
|
||||
detections=predictions,
|
||||
class_ids_from_to={16: 0},
|
||||
class_names_from_to={"dog": "Corgi"}
|
||||
class_names_from_to={"dog": "Corgi"},
|
||||
)
|
||||
predictions = predictions[
|
||||
np.isin(predictions["class_name"], test_set.classes)
|
||||
]
|
||||
predictions = predictions[np.isin(predictions["class_name"], test_set.classes),]
|
||||
|
||||
image_paths.append(image_path)
|
||||
predictions_list.append(predictions)
|
||||
@@ -298,16 +303,22 @@ N = 9
|
||||
GRID_SIZE = (3, 3)
|
||||
|
||||
target_annotator = sv.PolygonAnnotator(color=sv.Color.from_hex("#8315f9"), thickness=8)
|
||||
prediction_annotator = sv.PolygonAnnotator(color=sv.Color.from_hex("#00cfc6"), thickness=6)
|
||||
prediction_annotator = sv.PolygonAnnotator(
|
||||
color=sv.Color.from_hex("#00cfc6"), thickness=6
|
||||
)
|
||||
|
||||
|
||||
annotated_images = []
|
||||
for image_path, predictions, targets in zip(
|
||||
image_paths[:N], predictions_list[:N], targets_list[:N]
|
||||
image_paths[:N], predictions_list[:N], targets_list[:N]
|
||||
):
|
||||
annotated_image = cv2.imread(image_path)
|
||||
annotated_image = target_annotator.annotate(scene=annotated_image, detections=targets)
|
||||
annotated_image = prediction_annotator.annotate(scene=annotated_image, detections=prediction)
|
||||
annotated_image = target_annotator.annotate(
|
||||
scene=annotated_image, detections=targets
|
||||
)
|
||||
annotated_image = prediction_annotator.annotate(
|
||||
scene=annotated_image, detections=prediction
|
||||
)
|
||||
annotated_images.append(annotated_image)
|
||||
|
||||
sv.plot_images_grid(images=annotated_images, grid_size=GRID_SIZE)
|
||||
@@ -439,3 +450,25 @@ A condensed version of this guide is also available as a [Colab Notebook](https:
|
||||
For more details, be sure to check out our [documentation](https://supervision.roboflow.com/latest/) and join our community discussions. If you find any issues, please let us know on [GitHub](https://github.com/roboflow/supervision/issues).
|
||||
|
||||
Best of luck with your benchmarking!
|
||||
|
||||
## Frequently Asked Questions
|
||||
|
||||
### How do I benchmark a model with supervision?
|
||||
|
||||
Use `supervision.metrics.mean_average_precision.MeanAveragePrecision` — accumulate prediction and ground-truth `Detections` with `update(...)` and then call `compute()`. For confusion matrices, use `sv.ConfusionMatrix.from_detections(predictions=predictions, targets=targets, classes=classes)`.
|
||||
|
||||
### What IoU thresholds does MeanAveragePrecision use?
|
||||
|
||||
It computes mAP over IoU thresholds from 0.50 to 0.95 in steps of 0.05 (mAP@50:95), plus mAP@50 and mAP@75 individually.
|
||||
|
||||
### Can I benchmark segmentation models?
|
||||
|
||||
Yes, if you want to evaluate their bounding boxes. Convert model outputs to `Detections` and pass them to `MeanAveragePrecision.update(...)`; the current mAP path prepares COCO-style bounding boxes from `detections.xyxy`.
|
||||
|
||||
### What is a ConfusionMatrix and how do I use it?
|
||||
|
||||
`sv.ConfusionMatrix` visualizes true positives, false positives, and false negatives per class. Create one with `sv.ConfusionMatrix.from_detections(predictions=predictions, targets=targets, classes=classes, conf_threshold=0.5, iou_threshold=0.5)`, then call `metric.plot()` to render a heatmap.
|
||||
|
||||
## Author
|
||||
|
||||
- [Piotr Skalski](https://github.com/SkalskiP) — Computer Vision Engineer, Roboflow
|
||||
|
||||
@@ -0,0 +1,157 @@
|
||||
---
|
||||
comments: true
|
||||
description: Count objects entering a polygon zone in images and video using supervision's PolygonZone — measure throughput and density in any region.
|
||||
authors:
|
||||
- name: Piotr Skalski
|
||||
role: Computer Vision Engineer, Roboflow
|
||||
github: https://github.com/SkalskiP
|
||||
date_modified: 2026-04-22
|
||||
---
|
||||
|
||||
With supervision, you can count the number of objects in a zone in an image or video. In this guide, we will show how to count the number of cars in a traffic video.
|
||||
|
||||
[View the notebook that accompanies this tutorial](https://github.com/roboflow/notebooks/blob/main/notebooks/how-to-use-polygonzone-annotate-and-supervision.ipynb).
|
||||
|
||||
To make it easier for you to follow our tutorial download the video we will use as an example. You can do this using the `supervision.assets` module:
|
||||
|
||||
```python
|
||||
from supervision.assets import download_assets, VideoAssets
|
||||
|
||||
download_assets(VideoAssets.VEHICLES_2)
|
||||
```
|
||||
|
||||
## Initialize a Model and Load Video
|
||||
|
||||
First, we need to initialize a model. Let's use a YOLOv8 model with the default COCO checkpoint. We also need to load a video on which to run inference.
|
||||
|
||||
Create a YOLO model instance and load the source video using supervision's `VideoInfo` helper. The model will process each frame during inference, while `VideoInfo` extracts resolution and frame-rate metadata needed by the polygon zone annotator. A shared color palette ensures consistent zone coloring throughout the output video.
|
||||
|
||||
```python
|
||||
import numpy as np
|
||||
import supervision as sv
|
||||
import cv2
|
||||
|
||||
from ultralytics import YOLO
|
||||
|
||||
model = YOLO("yolov8s.pt")
|
||||
|
||||
VIDEO = str(VideoAssets.VEHICLES_2)
|
||||
|
||||
colors = sv.ColorPalette.default()
|
||||
video_info = sv.VideoInfo.from_video_path(VIDEO)
|
||||
```
|
||||
|
||||
## Calculate Coordinates
|
||||
|
||||
To count objects in a zone, you need to know the coordinates where you want to draw the zone.
|
||||
|
||||
You can calculate coordinates using the [PolygonZone web utility](https://roboflow.github.io/polygonzone/).
|
||||
|
||||
To use the PolygonZone website, you will need to upload an image or frame from a video. You can retrieve a frame using this code:
|
||||
|
||||
```python
|
||||
generator = sv.get_video_frames_generator(VIDEO)
|
||||
iterator = iter(generator)
|
||||
|
||||
frame = next(iterator)
|
||||
|
||||
cv2.imwrite("first_frame.png", frame)
|
||||
```
|
||||
|
||||
PolygonZone will give you NumPy arrays that you can use with supervision to count objects in zones.
|
||||
|
||||
<video width="100%" loop muted autoplay>
|
||||
<source src="https://media.roboflow.com/polygonzone.mp4" type="video/mp4">
|
||||
</video>
|
||||
|
||||
Save the coordinates in an array:
|
||||
|
||||
```python
|
||||
polygons = [
|
||||
np.array([[718, 595], [927, 592], [851, 1062], [42, 1059]]),
|
||||
np.array([[987, 595], [1199, 595], [1893, 1056], [1015, 1062]]),
|
||||
]
|
||||
```
|
||||
|
||||
## Define Zones
|
||||
|
||||
With the coordinates of the zones to draw ready, we can set up our zones:
|
||||
|
||||
Instantiate a `PolygonZone` for each polygon array, pairing it with a `PolygonZoneAnnotator` for visual overlay and a `BoxAnnotator` for drawing detection boxes. Each zone will later trigger on incoming detections to determine which objects fall inside its boundaries, enabling per-zone counting in the inference callback.
|
||||
|
||||
```python
|
||||
zones = [
|
||||
sv.PolygonZone(polygon=polygon, frame_resolution_wh=video_info.resolution_wh)
|
||||
for polygon in polygons
|
||||
]
|
||||
zone_annotators = [
|
||||
sv.PolygonZoneAnnotator(
|
||||
zone=zone,
|
||||
color=colors.by_idx(index),
|
||||
thickness=4,
|
||||
text_thickness=8,
|
||||
text_scale=4,
|
||||
)
|
||||
for index, zone in enumerate(zones)
|
||||
]
|
||||
box_annotators = [
|
||||
sv.BoxAnnotator(
|
||||
color=colors.by_idx(index),
|
||||
thickness=4,
|
||||
text_thickness=4,
|
||||
text_scale=2,
|
||||
)
|
||||
for index in range(len(polygons))
|
||||
]
|
||||
```
|
||||
|
||||
## Run Inference
|
||||
|
||||
We can run inference on a video using the [sv.process_video](https://supervision.roboflow.com/utils/video/#process_video) function. This function accepts a callback that runs inference on each frame and compiles the results into a video.
|
||||
|
||||
Below, we can call our YOLOv8 model, annotate predictions and zones, then save the results to a file called `result.mp4`.
|
||||
|
||||
```python
|
||||
def process_frame(frame: np.ndarray, i) -> np.ndarray:
|
||||
results = model(frame, imgsz=1280, verbose=False)[0]
|
||||
detections = sv.Detections.from_ultralytics(results)
|
||||
|
||||
for zone, zone_annotator, box_annotator in zip(
|
||||
zones, zone_annotators, box_annotators
|
||||
):
|
||||
mask = zone.trigger(detections=detections)
|
||||
detections_filtered = detections[mask]
|
||||
frame = box_annotator.annotate(
|
||||
scene=frame, detections=detections_filtered, skip_label=True
|
||||
)
|
||||
frame = zone_annotator.annotate(scene=frame)
|
||||
|
||||
return frame
|
||||
|
||||
|
||||
sv.process_video(source_path=VIDEO, target_path="result.mp4", callback=process_frame)
|
||||
```
|
||||
|
||||
Here is an example of inference run on the video:
|
||||
|
||||
<video width="100%" loop muted autoplay>
|
||||
<source src="https://blog.roboflow.com/content/media/2023/03/trim-counting.mp4" type="video/mp4">
|
||||
</video>
|
||||
|
||||
## Frequently Asked Questions
|
||||
|
||||
### How do I count objects in a zone with supervision?
|
||||
|
||||
Create `sv.PolygonZone` with a polygon defining your region. Call `zone.trigger(detections)` on each frame — it returns a mask of detections inside the zone.
|
||||
|
||||
### Can I count objects crossing a line instead of entering a zone?
|
||||
|
||||
Yes. Use `sv.LineZone` — define a start and end point. `zone.trigger(detections)` returns a tuple of two boolean arrays, `(crossed_in, crossed_out)`, indicating which detections crossed the line in each direction. `LineZone` requires `detections.tracker_id`; run a tracker first so the same object can be matched across frames.
|
||||
|
||||
### Can I combine zone counting with tracking?
|
||||
|
||||
Yes. You can pass tracker IDs from `sv.ByteTrack` alongside your detections, but `sv.PolygonZone` still evaluates the zone on each frame and reports which objects are currently inside it. If you want to count each object only once when it first enters the zone, maintain a set of seen `tracker_id` values after filtering detections with `zone.trigger(detections)`, or use a dedicated entry/crossing counting tool such as `sv.LineZone` when it better matches your use case.
|
||||
|
||||
## Author
|
||||
|
||||
- [Piotr Skalski](https://github.com/SkalskiP) — Computer Vision Engineer, Roboflow
|
||||
@@ -1,5 +1,14 @@
|
||||
---
|
||||
comments: true
|
||||
description: Learn to load model predictions, create Detections objects, and annotate images with bounding boxes, labels, and masks using supervision.
|
||||
authors:
|
||||
- name: Piotr Skalski
|
||||
role: Computer Vision Engineer, Roboflow
|
||||
github: https://github.com/SkalskiP
|
||||
- name: Borda
|
||||
role: Open Source Engineer, Roboflow
|
||||
github: https://github.com/borda
|
||||
date_modified: 2026-04-22
|
||||
---
|
||||
|
||||
# Detect and Annotate
|
||||
@@ -19,27 +28,32 @@ source image.
|
||||
First, you'll need to obtain predictions from your object detection or segmentation
|
||||
model.
|
||||
|
||||
To run inference, initialize your chosen model and pass the source image to its predict or infer method. Supervision supports Roboflow Inference, Ultralytics YOLO, and Hugging Face Transformers -- select the tab matching your framework. The result is a framework-specific object you will convert to a `Detections` instance in the next step.
|
||||
|
||||
=== "Inference"
|
||||
|
||||
```python
|
||||
import cv2
|
||||
from inference import get_model
|
||||
|
||||
model = get_model(model_id="yolov8n-640")
|
||||
image = cv2.imread(<SOURCE_IMAGE_PATH>)
|
||||
image = cv2.imread("<SOURCE_IMAGE_PATH>")
|
||||
results = model.infer(image)[0]
|
||||
```
|
||||
|
||||
=== "Ultralytics"
|
||||
|
||||
```python
|
||||
import cv2
|
||||
from ultralytics import YOLO
|
||||
|
||||
model = YOLO("yolov8n.pt")
|
||||
image = cv2.imread(<SOURCE_IMAGE_PATH>)
|
||||
image = cv2.imread("<SOURCE_IMAGE_PATH>")
|
||||
results = model(image)[0]
|
||||
```
|
||||
|
||||
=== "Transformers"
|
||||
|
||||
```python
|
||||
import torch
|
||||
from PIL import Image
|
||||
@@ -48,7 +62,7 @@ model.
|
||||
processor = DetrImageProcessor.from_pretrained("facebook/detr-resnet-50")
|
||||
model = DetrForObjectDetection.from_pretrained("facebook/detr-resnet-50")
|
||||
|
||||
image = Image.open(<SOURCE_IMAGE_PATH>)
|
||||
image = Image.open("<SOURCE_IMAGE_PATH>")
|
||||
inputs = processor(images=image, return_tensors="pt")
|
||||
|
||||
with torch.no_grad():
|
||||
@@ -57,15 +71,19 @@ model.
|
||||
width, height = image.size
|
||||
target_size = torch.tensor([[height, width]])
|
||||
results = processor.post_process_object_detection(
|
||||
outputs=outputs, target_sizes=target_size)[0]
|
||||
outputs=outputs, target_sizes=target_size
|
||||
)[0]
|
||||
```
|
||||
|
||||
## Load Predictions into Supervision
|
||||
|
||||
Now that we have predictions from a model, we can load them into Supervision.
|
||||
|
||||
Each supported framework has a dedicated class method on `sv.Detections` that converts raw model output into a unified Supervision object. Call `from_inference`, `from_ultralytics`, or `from_transformers` depending on the package you used for inference. This normalization step ensures all downstream annotators and filters work identically regardless of the source model.
|
||||
|
||||
=== "Inference"
|
||||
We can do so using the [`sv.Detections.from_inference`](/latest/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`](https://supervision.roboflow.com/latest/detection/core/#supervision.detection.core.Detections.from_inference) method, which accepts model results from both detection and segmentation models.
|
||||
|
||||
```{ .py hl_lines="2 8" }
|
||||
import cv2
|
||||
@@ -73,13 +91,14 @@ Now that we have predictions from a model, we can load them into Supervision.
|
||||
from inference import get_model
|
||||
|
||||
model = get_model(model_id="yolov8n-640")
|
||||
image = cv2.imread(<SOURCE_IMAGE_PATH>)
|
||||
image = cv2.imread("<SOURCE_IMAGE_PATH>")
|
||||
results = model.infer(image)[0]
|
||||
detections = sv.Detections.from_inference(results)
|
||||
```
|
||||
|
||||
=== "Ultralytics"
|
||||
We can do so using the [`sv.Detections.from_ultralytics`](/latest/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`](https://supervision.roboflow.com/latest/detection/core/#supervision.detection.core.Detections.from_ultralytics) method, which accepts model results from both detection and segmentation models.
|
||||
|
||||
```{ .py hl_lines="2 8" }
|
||||
import cv2
|
||||
@@ -87,13 +106,14 @@ Now that we have predictions from a model, we can load them into Supervision.
|
||||
from ultralytics import YOLO
|
||||
|
||||
model = YOLO("yolov8n.pt")
|
||||
image = cv2.imread(<SOURCE_IMAGE_PATH>)
|
||||
image = cv2.imread("<SOURCE_IMAGE_PATH>")
|
||||
results = model(image)[0]
|
||||
detections = sv.Detections.from_ultralytics(results)
|
||||
```
|
||||
|
||||
=== "Transformers"
|
||||
We can do so using the [`sv.Detections.from_transformers`](/latest/detection/core/#supervision.detection.core.Detections.from_transformers) method, which accepts model results from both detection and segmentation models.
|
||||
|
||||
We can do so using the [`sv.Detections.from_transformers`](https://supervision.roboflow.com/latest/detection/core/#supervision.detection.core.Detections.from_transformers) method, which accepts model results from both detection and segmentation models.
|
||||
|
||||
```{ .py hl_lines="2 19-21" }
|
||||
import torch
|
||||
@@ -104,7 +124,7 @@ Now that we have predictions from a model, we can load them into Supervision.
|
||||
processor = DetrImageProcessor.from_pretrained("facebook/detr-resnet-50")
|
||||
model = DetrForObjectDetection.from_pretrained("facebook/detr-resnet-50")
|
||||
|
||||
image = Image.open(<SOURCE_IMAGE_PATH>)
|
||||
image = Image.open("<SOURCE_IMAGE_PATH>")
|
||||
inputs = processor(images=image, return_tensors="pt")
|
||||
|
||||
with torch.no_grad():
|
||||
@@ -121,24 +141,27 @@ Now that we have predictions from a model, we can load them into Supervision.
|
||||
|
||||
You can load predictions from other computer vision frameworks and libraries using:
|
||||
|
||||
- [`from_deepsparse`](/latest/detection/core/#supervision.detection.core.Detections.from_deepsparse) ([Deepsparse](https://github.com/neuralmagic/deepsparse))
|
||||
- [`from_detectron2`](/latest/detection/core/#supervision.detection.core.Detections.from_detectron2) ([Detectron2](https://github.com/facebookresearch/detectron2))
|
||||
- [`from_mmdetection`](/latest/detection/core/#supervision.detection.core.Detections.from_mmdetection) ([MMDetection](https://github.com/open-mmlab/mmdetection))
|
||||
- [`from_sam`](/latest/detection/core/#supervision.detection.core.Detections.from_sam) ([Segment Anything Model](https://github.com/facebookresearch/segment-anything))
|
||||
- [`from_yolo_nas`](/latest/detection/core/#supervision.detection.core.Detections.from_yolo_nas) ([YOLO-NAS](https://github.com/Deci-AI/super-gradients/blob/master/YOLONAS.md))
|
||||
- [`from_deepsparse`](https://supervision.roboflow.com/latest/detection/core/#supervision.detection.core.Detections.from_deepsparse) ([Deepsparse](https://github.com/neuralmagic/deepsparse))
|
||||
- [`from_detectron2`](https://supervision.roboflow.com/latest/detection/core/#supervision.detection.core.Detections.from_detectron2) ([Detectron2](https://github.com/facebookresearch/detectron2))
|
||||
- [`from_mmdetection`](https://supervision.roboflow.com/latest/detection/core/#supervision.detection.core.Detections.from_mmdetection) ([MMDetection](https://github.com/open-mmlab/mmdetection))
|
||||
- [`from_sam`](https://supervision.roboflow.com/latest/detection/core/#supervision.detection.core.Detections.from_sam) ([Segment Anything Model](https://github.com/facebookresearch/segment-anything))
|
||||
- [`from_yolo_nas`](https://supervision.roboflow.com/latest/detection/core/#supervision.detection.core.Detections.from_yolo_nas) ([YOLO-NAS](https://github.com/Deci-AI/super-gradients/blob/master/YOLONAS.md))
|
||||
|
||||
## Annotate Image with Detections
|
||||
|
||||
Finally, we can annotate the image with the predictions. Since we are working with an object detection model, we will use the [`sv.BoxAnnotator`](/latest/detection/annotators/#supervision.annotators.core.BoxAnnotator) and [`sv.LabelAnnotator`](/latest/detection/annotators/#supervision.annotators.core.LabelAnnotator) classes.
|
||||
Finally, we can annotate the image with the predictions. Since we are working with an object detection model, we will use the [`sv.BoxAnnotator`](https://supervision.roboflow.com/latest/detection/annotators/#supervision.annotators.core.BoxAnnotator) and [`sv.LabelAnnotator`](https://supervision.roboflow.com/latest/detection/annotators/#supervision.annotators.core.LabelAnnotator) classes.
|
||||
|
||||
To draw bounding boxes and class labels on your image, create a `BoxAnnotator` and a `LabelAnnotator`, then call their `annotate` methods in sequence. Each annotator returns the modified image, so you can chain multiple annotators together. The result is a single NumPy array with all visual overlays rendered and ready for display or saving.
|
||||
|
||||
=== "Inference"
|
||||
|
||||
```{ .py hl_lines="10-16" }
|
||||
import cv2
|
||||
import supervision as sv
|
||||
from inference import get_model
|
||||
|
||||
model = get_model(model_id="yolov8n-640")
|
||||
image = cv2.imread(<SOURCE_IMAGE_PATH>)
|
||||
image = cv2.imread("<SOURCE_IMAGE_PATH>")
|
||||
results = model.infer(image)[0]
|
||||
detections = sv.Detections.from_inference(results)
|
||||
|
||||
@@ -152,13 +175,14 @@ Finally, we can annotate the image with the predictions. Since we are working wi
|
||||
```
|
||||
|
||||
=== "Ultralytics"
|
||||
|
||||
```{ .py hl_lines="10-16" }
|
||||
import cv2
|
||||
import supervision as sv
|
||||
from ultralytics import YOLO
|
||||
|
||||
model = YOLO("yolov8n.pt")
|
||||
image = cv2.imread(<SOURCE_IMAGE_PATH>)
|
||||
image = cv2.imread("<SOURCE_IMAGE_PATH>")
|
||||
results = model(image)[0]
|
||||
detections = sv.Detections.from_ultralytics(results)
|
||||
|
||||
@@ -172,6 +196,7 @@ Finally, we can annotate the image with the predictions. Since we are working wi
|
||||
```
|
||||
|
||||
=== "Transformers"
|
||||
|
||||
```{ .py hl_lines="23-30" }
|
||||
import torch
|
||||
import supervision as sv
|
||||
@@ -181,7 +206,7 @@ Finally, we can annotate the image with the predictions. Since we are working wi
|
||||
processor = DetrImageProcessor.from_pretrained("facebook/detr-resnet-50")
|
||||
model = DetrForObjectDetection.from_pretrained("facebook/detr-resnet-50")
|
||||
|
||||
image = Image.open(<SOURCE_IMAGE_PATH>)
|
||||
image = Image.open("<SOURCE_IMAGE_PATH>")
|
||||
inputs = processor(images=image, return_tensors="pt")
|
||||
|
||||
with torch.no_grad():
|
||||
@@ -208,18 +233,19 @@ Finally, we can annotate the image with the predictions. Since we are working wi
|
||||
|
||||
## Display Custom Labels
|
||||
|
||||
By default, [`sv.LabelAnnotator`](/latest/detection/annotators/#supervision.annotators.core.LabelAnnotator)
|
||||
By default, [`sv.LabelAnnotator`](https://supervision.roboflow.com/latest/detection/annotators/#supervision.annotators.core.LabelAnnotator)
|
||||
will label each detection with its `class_name` (if possible) or `class_id`. You can
|
||||
override this behavior by passing a list of custom `labels` to the `annotate` method.
|
||||
|
||||
=== "Inference"
|
||||
|
||||
```{ .py hl_lines="13-17 22" }
|
||||
import cv2
|
||||
import supervision as sv
|
||||
from inference import get_model
|
||||
|
||||
model = get_model(model_id="yolov8n-640")
|
||||
image = cv2.imread(<SOURCE_IMAGE_PATH>)
|
||||
image = cv2.imread("<SOURCE_IMAGE_PATH>")
|
||||
results = model.infer(image)[0]
|
||||
detections = sv.Detections.from_inference(results)
|
||||
|
||||
@@ -239,13 +265,14 @@ override this behavior by passing a list of custom `labels` to the `annotate` me
|
||||
```
|
||||
|
||||
=== "Ultralytics"
|
||||
|
||||
```{ .py hl_lines="13-17 22" }
|
||||
import cv2
|
||||
import supervision as sv
|
||||
from ultralytics import YOLO
|
||||
|
||||
model = YOLO("yolov8n.pt")
|
||||
image = cv2.imread(<SOURCE_IMAGE_PATH>)
|
||||
image = cv2.imread("<SOURCE_IMAGE_PATH>")
|
||||
results = model(image)[0]
|
||||
detections = sv.Detections.from_ultralytics(results)
|
||||
|
||||
@@ -265,6 +292,7 @@ override this behavior by passing a list of custom `labels` to the `annotate` me
|
||||
```
|
||||
|
||||
=== "Transformers"
|
||||
|
||||
```{ .py hl_lines="26-30 35" }
|
||||
import torch
|
||||
import supervision as sv
|
||||
@@ -274,7 +302,7 @@ override this behavior by passing a list of custom `labels` to the `annotate` me
|
||||
processor = DetrImageProcessor.from_pretrained("facebook/detr-resnet-50")
|
||||
model = DetrForObjectDetection.from_pretrained("facebook/detr-resnet-50")
|
||||
|
||||
image = Image.open(<SOURCE_IMAGE_PATH>)
|
||||
image = Image.open("<SOURCE_IMAGE_PATH>")
|
||||
inputs = processor(images=image, return_tensors="pt")
|
||||
|
||||
with torch.no_grad():
|
||||
@@ -308,19 +336,20 @@ override this behavior by passing a list of custom `labels` to the `annotate` me
|
||||
## Annotate Image with Segmentations
|
||||
|
||||
If you are running the segmentation model
|
||||
[`sv.MaskAnnotator`](/latest/detection/annotators/#supervision.annotators.core.MaskAnnotator)
|
||||
[`sv.MaskAnnotator`](https://supervision.roboflow.com/latest/detection/annotators/#supervision.annotators.core.MaskAnnotator)
|
||||
is a drop-in replacement for
|
||||
[`sv.BoxAnnotator`](/latest/detection/annotators/#supervision.annotators.core.BoxAnnotator)
|
||||
[`sv.BoxAnnotator`](https://supervision.roboflow.com/latest/detection/annotators/#supervision.annotators.core.BoxAnnotator)
|
||||
that will allow you to draw masks instead of boxes.
|
||||
|
||||
=== "Inference"
|
||||
|
||||
```python
|
||||
import cv2
|
||||
import supervision as sv
|
||||
from inference import get_model
|
||||
|
||||
model = get_model(model_id="yolov8n-seg-640")
|
||||
image = cv2.imread(<SOURCE_IMAGE_PATH>)
|
||||
image = cv2.imread("<SOURCE_IMAGE_PATH>")
|
||||
results = model.infer(image)[0]
|
||||
detections = sv.Detections.from_inference(results)
|
||||
|
||||
@@ -328,19 +357,24 @@ that will allow you to draw masks instead of boxes.
|
||||
label_annotator = sv.LabelAnnotator(text_position=sv.Position.CENTER_OF_MASS)
|
||||
|
||||
annotated_image = mask_annotator.annotate(
|
||||
scene=image, detections=detections)
|
||||
scene=image,
|
||||
detections=detections,
|
||||
)
|
||||
annotated_image = label_annotator.annotate(
|
||||
scene=annotated_image, detections=detections)
|
||||
scene=annotated_image,
|
||||
detections=detections,
|
||||
)
|
||||
```
|
||||
|
||||
=== "Ultralytics"
|
||||
|
||||
```python
|
||||
import cv2
|
||||
import supervision as sv
|
||||
from ultralytics import YOLO
|
||||
|
||||
model = YOLO("yolov8n-seg.pt")
|
||||
image = cv2.imread(<SOURCE_IMAGE_PATH>)
|
||||
image = cv2.imread("<SOURCE_IMAGE_PATH>")
|
||||
results = model(image)[0]
|
||||
detections = sv.Detections.from_ultralytics(results)
|
||||
|
||||
@@ -348,12 +382,17 @@ that will allow you to draw masks instead of boxes.
|
||||
label_annotator = sv.LabelAnnotator(text_position=sv.Position.CENTER_OF_MASS)
|
||||
|
||||
annotated_image = mask_annotator.annotate(
|
||||
scene=image, detections=detections)
|
||||
scene=image,
|
||||
detections=detections,
|
||||
)
|
||||
annotated_image = label_annotator.annotate(
|
||||
scene=annotated_image, detections=detections)
|
||||
scene=annotated_image,
|
||||
detections=detections,
|
||||
)
|
||||
```
|
||||
|
||||
=== "Transformers"
|
||||
|
||||
```python
|
||||
import torch
|
||||
import supervision as sv
|
||||
@@ -363,7 +402,7 @@ that will allow you to draw masks instead of boxes.
|
||||
processor = DetrImageProcessor.from_pretrained("facebook/detr-resnet-50-panoptic")
|
||||
model = DetrForSegmentation.from_pretrained("facebook/detr-resnet-50-panoptic")
|
||||
|
||||
image = Image.open(<SOURCE_IMAGE_PATH>)
|
||||
image = Image.open("<SOURCE_IMAGE_PATH>")
|
||||
inputs = processor(images=image, return_tensors="pt")
|
||||
|
||||
with torch.no_grad():
|
||||
@@ -372,24 +411,50 @@ that will allow you to draw masks instead of boxes.
|
||||
width, height = image.size
|
||||
target_size = torch.tensor([[height, width]])
|
||||
results = processor.post_process_segmentation(
|
||||
outputs=outputs, target_sizes=target_size)[0]
|
||||
outputs=outputs, target_sizes=target_size
|
||||
)[0]
|
||||
detections = sv.Detections.from_transformers(
|
||||
transformers_results=results,
|
||||
id2label=model.config.id2label)
|
||||
transformers_results=results, id2label=model.config.id2label
|
||||
)
|
||||
|
||||
mask_annotator = sv.MaskAnnotator()
|
||||
label_annotator = sv.LabelAnnotator(text_position=sv.Position.CENTER_OF_MASS)
|
||||
|
||||
labels = [
|
||||
f"{class_name} {confidence:.2f}"
|
||||
for class_name, confidence
|
||||
in zip(detections['class_name'], detections.confidence)
|
||||
for class_name, confidence in zip(
|
||||
detections["class_name"],
|
||||
detections.confidence,
|
||||
)
|
||||
]
|
||||
|
||||
annotated_image = mask_annotator.annotate(
|
||||
scene=image, detections=detections)
|
||||
annotated_image = mask_annotator.annotate(scene=image, detections=detections)
|
||||
annotated_image = label_annotator.annotate(
|
||||
scene=annotated_image, detections=detections, labels=labels)
|
||||
scene=annotated_image, detections=detections, labels=labels
|
||||
)
|
||||
```
|
||||
|
||||

|
||||
|
||||
## Frequently Asked Questions
|
||||
|
||||
### How do I detect and annotate objects with supervision?
|
||||
|
||||
Pass any model's output to `sv.Detections.from_<model>()` to create a unified `Detections` object. Then pass it to `sv.BoxAnnotator` or `sv.MaskAnnotator` to draw predictions on an image.
|
||||
|
||||
### Can I annotate both bounding boxes and masks at the same time?
|
||||
|
||||
Yes. Chain annotators: first draw boxes with `BoxAnnotator`, then overlay masks with `MaskAnnotator` on the same scene.
|
||||
|
||||
### How do I label detections with class names?
|
||||
|
||||
Use `sv.LabelAnnotator` and pass custom text with the `labels` parameter. If a connector provides class names, they are stored in `detections["class_name"]` / `detections.data["class_name"]`; when `labels` is omitted, `LabelAnnotator` uses class names first, then class IDs, then detection indices.
|
||||
|
||||
### Can I use supervision with Hugging Face models?
|
||||
|
||||
Yes. `sv.Detections.from_transformers()` accepts supported Hugging Face object detection and segmentation outputs. Vision-language model outputs are handled through `sv.Detections.from_vlm(...)`, for example with `sv.VLM.FLORENCE_2` or `sv.VLM.PALIGEMMA`.
|
||||
|
||||
## Authors
|
||||
|
||||
- [Piotr Skalski](https://github.com/SkalskiP) — Computer Vision Engineer, Roboflow
|
||||
- [Borda](https://github.com/borda) — Open Source Engineer, Roboflow
|
||||
|
||||
@@ -1,5 +1,11 @@
|
||||
---
|
||||
comments: true
|
||||
description: Detect small objects in images by applying SAHI inference slicing with supervision's InferenceSlicer — improve recall for tiny targets.
|
||||
authors:
|
||||
- name: Piotr Skalski
|
||||
role: Computer Vision Engineer, Roboflow
|
||||
github: https://github.com/SkalskiP
|
||||
date_modified: 2026-04-22
|
||||
---
|
||||
|
||||
# Detect Small Objects
|
||||
@@ -8,7 +14,7 @@ This guide shows how to detect small objects
|
||||
with the [Inference](https://github.com/roboflow/inference),
|
||||
[Ultralytics](https://github.com/ultralytics/ultralytics) or
|
||||
[Transformers](https://github.com/huggingface/transformers) packages using
|
||||
[`InferenceSlicer`](/latest/detection/tools/inference_slicer/#supervision.detection.tools.inference_slicer.InferenceSlicer).
|
||||
[`InferenceSlicer`](https://supervision.roboflow.com/latest/detection/tools/inference_slicer/#supervision.detection.tools.inference_slicer.InferenceSlicer).
|
||||
|
||||
<video controls>
|
||||
<source src="https://media.roboflow.com/supervision_detect_small_objects_example.mp4" type="video/mp4">
|
||||
@@ -19,14 +25,17 @@ with the [Inference](https://github.com/roboflow/inference),
|
||||
Small object detection in high-resolution images presents challenges due to the objects'
|
||||
size relative to the image resolution.
|
||||
|
||||
Running a standard detection model on the full image establishes a baseline for comparison. Load your chosen model, pass the image through it, and convert the results into a `Detections` object. This baseline reveals how many small objects the model misses at native resolution, motivating the sliced inference approach shown later.
|
||||
|
||||
=== "Inference"
|
||||
|
||||
```python
|
||||
import cv2
|
||||
import supervision as sv
|
||||
from inference import get_model
|
||||
|
||||
model = get_model(model_id="yolov8x-640")
|
||||
image = cv2.imread(<SOURCE_IMAGE_PATH>)
|
||||
image = cv2.imread("<SOURCE_IMAGE_PATH>")
|
||||
results = model.infer(image)[0]
|
||||
detections = sv.Detections.from_inference(results)
|
||||
|
||||
@@ -34,19 +43,24 @@ size relative to the image resolution.
|
||||
label_annotator = sv.LabelAnnotator()
|
||||
|
||||
annotated_image = box_annotator.annotate(
|
||||
scene=image, detections=detections)
|
||||
scene=image,
|
||||
detections=detections,
|
||||
)
|
||||
annotated_image = label_annotator.annotate(
|
||||
scene=annotated_image, detections=detections)
|
||||
scene=annotated_image,
|
||||
detections=detections,
|
||||
)
|
||||
```
|
||||
|
||||
=== "Ultralytics"
|
||||
|
||||
```python
|
||||
import cv2
|
||||
import supervision as sv
|
||||
from ultralytics import YOLO
|
||||
|
||||
model = YOLO("yolov8x.pt")
|
||||
image = cv2.imread(<SOURCE_IMAGE_PATH>)
|
||||
image = cv2.imread("<SOURCE_IMAGE_PATH>")
|
||||
results = model(image)[0]
|
||||
detections = sv.Detections.from_ultralytics(results)
|
||||
|
||||
@@ -54,12 +68,17 @@ size relative to the image resolution.
|
||||
label_annotator = sv.LabelAnnotator()
|
||||
|
||||
annotated_image = box_annotator.annotate(
|
||||
scene=image, detections=detections)
|
||||
scene=image,
|
||||
detections=detections,
|
||||
)
|
||||
annotated_image = label_annotator.annotate(
|
||||
scene=annotated_image, detections=detections)
|
||||
scene=annotated_image,
|
||||
detections=detections,
|
||||
)
|
||||
```
|
||||
|
||||
=== "Transformers"
|
||||
|
||||
```python
|
||||
import torch
|
||||
import supervision as sv
|
||||
@@ -69,7 +88,7 @@ size relative to the image resolution.
|
||||
processor = DetrImageProcessor.from_pretrained("facebook/detr-resnet-50")
|
||||
model = DetrForSegmentation.from_pretrained("facebook/detr-resnet-50")
|
||||
|
||||
image = Image.open(<SOURCE_IMAGE_PATH>)
|
||||
image = Image.open("<SOURCE_IMAGE_PATH>")
|
||||
inputs = processor(images=image, return_tensors="pt")
|
||||
|
||||
with torch.no_grad():
|
||||
@@ -78,22 +97,19 @@ size relative to the image resolution.
|
||||
width, height = image_slice.size
|
||||
target_size = torch.tensor([[width, height]])
|
||||
results = processor.post_process_object_detection(
|
||||
outputs=outputs, target_sizes=target_size)[0]
|
||||
outputs=outputs, target_sizes=target_size
|
||||
)[0]
|
||||
detections = sv.Detections.from_transformers(results)
|
||||
|
||||
box_annotator = sv.BoxAnnotator()
|
||||
label_annotator = sv.LabelAnnotator()
|
||||
|
||||
labels = [
|
||||
model.config.id2label[class_id]
|
||||
for class_id
|
||||
in detections.class_id
|
||||
]
|
||||
labels = [model.config.id2label[class_id] for class_id in detections.class_id]
|
||||
|
||||
annotated_image = box_annotator.annotate(
|
||||
scene=image, detections=detections)
|
||||
annotated_image = box_annotator.annotate(scene=image, detections=detections)
|
||||
annotated_image = label_annotator.annotate(
|
||||
scene=annotated_image, detections=detections, labels=labels)
|
||||
scene=annotated_image, detections=detections, labels=labels
|
||||
)
|
||||
```
|
||||
|
||||

|
||||
@@ -105,13 +121,14 @@ identification at the cost of processing speed and increased memory usage. This
|
||||
is less effective for ultra-high-resolution images (4K and above).
|
||||
|
||||
=== "Inference"
|
||||
|
||||
```{ .py hl_lines="5" }
|
||||
import cv2
|
||||
import supervision as sv
|
||||
from inference import get_model
|
||||
|
||||
model = get_model(model_id="yolov8x-1280")
|
||||
image = cv2.imread(<SOURCE_IMAGE_PATH>)
|
||||
image = cv2.imread("<SOURCE_IMAGE_PATH>")
|
||||
results = model.infer(image)[0]
|
||||
detections = sv.Detections.from_inference(results)
|
||||
|
||||
@@ -125,13 +142,14 @@ is less effective for ultra-high-resolution images (4K and above).
|
||||
```
|
||||
|
||||
=== "Ultralytics"
|
||||
|
||||
```{ .py hl_lines="7" }
|
||||
import cv2
|
||||
import supervision as sv
|
||||
from ultralytics import YOLO
|
||||
|
||||
model = YOLO("yolov8x.pt")
|
||||
image = cv2.imread(<SOURCE_IMAGE_PATH>)
|
||||
image = cv2.imread("<SOURCE_IMAGE_PATH>")
|
||||
results = model(image, imgsz=1280)[0]
|
||||
detections = sv.Detections.from_ultralytics(results)
|
||||
|
||||
@@ -148,7 +166,7 @@ is less effective for ultra-high-resolution images (4K and above).
|
||||
|
||||
## Inference Slicer
|
||||
|
||||
[`InferenceSlicer`](/latest/detection/tools/inference_slicer/#supervision.detection.tools.inference_slicer.InferenceSlicer)
|
||||
[`InferenceSlicer`](https://supervision.roboflow.com/latest/detection/tools/inference_slicer/#supervision.detection.tools.inference_slicer.InferenceSlicer)
|
||||
processes high-resolution images by dividing them into smaller segments, detecting
|
||||
objects within each, and aggregating the results.
|
||||
|
||||
@@ -157,6 +175,7 @@ objects within each, and aggregating the results.
|
||||
</video>
|
||||
|
||||
=== "Inference"
|
||||
|
||||
```{ .py hl_lines="9-14" }
|
||||
import cv2
|
||||
import numpy as np
|
||||
@@ -164,7 +183,7 @@ objects within each, and aggregating the results.
|
||||
from inference import get_model
|
||||
|
||||
model = get_model(model_id="yolov8x-640")
|
||||
image = cv2.imread(<SOURCE_IMAGE_PATH>)
|
||||
image = cv2.imread("<SOURCE_IMAGE_PATH>")
|
||||
|
||||
def callback(image_slice: np.ndarray) -> sv.Detections:
|
||||
results = model.infer(image_slice)[0]
|
||||
@@ -183,6 +202,7 @@ objects within each, and aggregating the results.
|
||||
```
|
||||
|
||||
=== "Ultralytics"
|
||||
|
||||
```{ .py hl_lines="9-14" }
|
||||
import cv2
|
||||
import numpy as np
|
||||
@@ -190,7 +210,7 @@ objects within each, and aggregating the results.
|
||||
from ultralytics import YOLO
|
||||
|
||||
model = YOLO("yolov8x.pt")
|
||||
image = cv2.imread(<SOURCE_IMAGE_PATH>)
|
||||
image = cv2.imread("<SOURCE_IMAGE_PATH>")
|
||||
|
||||
def callback(image_slice: np.ndarray) -> sv.Detections:
|
||||
result = model(image_slice)[0]
|
||||
@@ -209,6 +229,7 @@ objects within each, and aggregating the results.
|
||||
```
|
||||
|
||||
=== "Transformers"
|
||||
|
||||
```{ .py hl_lines="13-28" }
|
||||
import cv2
|
||||
import torch
|
||||
@@ -220,7 +241,7 @@ objects within each, and aggregating the results.
|
||||
processor = DetrImageProcessor.from_pretrained("facebook/detr-resnet-50")
|
||||
model = DetrForObjectDetection.from_pretrained("facebook/detr-resnet-50")
|
||||
|
||||
image = cv2.imread(<SOURCE_IMAGE_PATH>)
|
||||
image = cv2.imread("<SOURCE_IMAGE_PATH>")
|
||||
|
||||
def callback(image_slice: np.ndarray) -> sv.Detections:
|
||||
image_slice = cv2.cvtColor(image_slice, cv2.COLOR_BGR2RGB)
|
||||
@@ -258,9 +279,10 @@ objects within each, and aggregating the results.
|
||||
|
||||
## Small Object Segmentation
|
||||
|
||||
[`InferenceSlicer`](/latest/detection/tools/inference_slicer/#supervision.detection.tools.inference_slicer.InferenceSlicer) can perform segmentation tasks too.
|
||||
[`InferenceSlicer`](https://supervision.roboflow.com/latest/detection/tools/inference_slicer/#supervision.detection.tools.inference_slicer.InferenceSlicer) can perform segmentation tasks too.
|
||||
|
||||
=== "Inference"
|
||||
|
||||
```{ .py hl_lines="6 16 19-20" }
|
||||
import cv2
|
||||
import numpy as np
|
||||
@@ -268,7 +290,7 @@ objects within each, and aggregating the results.
|
||||
from inference import get_model
|
||||
|
||||
model = get_model(model_id="yolov8x-seg-640")
|
||||
image = cv2.imread(<SOURCE_IMAGE_PATH>)
|
||||
image = cv2.imread("<SOURCE_IMAGE_PATH>")
|
||||
|
||||
def callback(image_slice: np.ndarray) -> sv.Detections:
|
||||
results = model.infer(image_slice)[0]
|
||||
@@ -287,6 +309,7 @@ objects within each, and aggregating the results.
|
||||
```
|
||||
|
||||
=== "Ultralytics"
|
||||
|
||||
```{ .py hl_lines="6 16 19-20" }
|
||||
import cv2
|
||||
import numpy as np
|
||||
@@ -294,7 +317,7 @@ objects within each, and aggregating the results.
|
||||
from ultralytics import YOLO
|
||||
|
||||
model = YOLO("yolov8x-seg.pt")
|
||||
image = cv2.imread(<SOURCE_IMAGE_PATH>)
|
||||
image = cv2.imread("<SOURCE_IMAGE_PATH>")
|
||||
|
||||
def callback(image_slice: np.ndarray) -> sv.Detections:
|
||||
result = model(image_slice)[0]
|
||||
@@ -313,3 +336,21 @@ objects within each, and aggregating the results.
|
||||
```
|
||||
|
||||

|
||||
|
||||
## Frequently Asked Questions
|
||||
|
||||
### How do I detect small objects with supervision?
|
||||
|
||||
Use `sv.InferenceSlicer` to split a high-resolution image into overlapping tiles, run detection on each tile, and merge results with non-maximum suppression. This dramatically improves recall for tiny targets.
|
||||
|
||||
### What overlap should I use between tiles?
|
||||
|
||||
`InferenceSlicer` takes overlap in pixels via `overlap_wh`, not as a percentage. The default is `100` pixels in both directions. Increase `overlap_wh` when objects are close to the tile size or often appear on tile boundaries, and decrease it when speed is more important.
|
||||
|
||||
### Can I use InferenceSlicer with any detection model?
|
||||
|
||||
Yes. Wrap any model or converter path that can produce `sv.Detections` in a callback, pass that callback to `sv.InferenceSlicer(callback=...)`, and then call the slicer with your image.
|
||||
|
||||
## Author
|
||||
|
||||
- [Piotr Skalski](https://github.com/SkalskiP) — Computer Vision Engineer, Roboflow
|
||||
|
||||
@@ -1,5 +1,11 @@
|
||||
---
|
||||
comments: true
|
||||
description: Filter and query detection results by class, confidence, or spatial overlap using supervision's Detections API — clean predictions in one line.
|
||||
authors:
|
||||
- name: Piotr Skalski
|
||||
role: Computer Vision Engineer, Roboflow
|
||||
github: https://github.com/SkalskiP
|
||||
date_modified: 2026-04-22
|
||||
---
|
||||
|
||||
# Filter Detections
|
||||
@@ -15,6 +21,7 @@ the filters in their applications.
|
||||
Allows you to select detections that belong only to one selected class.
|
||||
|
||||
=== "After"
|
||||
|
||||
```python
|
||||
import supervision as sv
|
||||
|
||||
@@ -29,6 +36,7 @@ Allows you to select detections that belong only to one selected class.
|
||||
</div>
|
||||
|
||||
=== "Before"
|
||||
|
||||
```python
|
||||
import supervision as sv
|
||||
|
||||
@@ -47,6 +55,7 @@ Allows you to select detections that belong only to one selected class.
|
||||
Allows you to select detections that belong only to selected set of classes.
|
||||
|
||||
=== "After"
|
||||
|
||||
```python
|
||||
import numpy as np
|
||||
import supervision as sv
|
||||
@@ -63,6 +72,7 @@ Allows you to select detections that belong only to selected set of classes.
|
||||
</div>
|
||||
|
||||
=== "Before"
|
||||
|
||||
```python
|
||||
import numpy as np
|
||||
import supervision as sv
|
||||
@@ -83,6 +93,7 @@ Allows you to select detections that belong only to selected set of classes.
|
||||
Allows you to select detections with specific confidence value, for example higher than selected threshold.
|
||||
|
||||
=== "After"
|
||||
|
||||
```python
|
||||
import supervision as sv
|
||||
|
||||
@@ -97,6 +108,7 @@ Allows you to select detections with specific confidence value, for example high
|
||||
</div>
|
||||
|
||||
=== "Before"
|
||||
|
||||
```python
|
||||
import supervision as sv
|
||||
|
||||
@@ -116,6 +128,7 @@ Allows you to select detections based on their size. We define the area as the n
|
||||
detection in the image. In the example below, we have sifted out the detections that are too small.
|
||||
|
||||
=== "After"
|
||||
|
||||
```python
|
||||
import supervision as sv
|
||||
|
||||
@@ -130,6 +143,7 @@ detection in the image. In the example below, we have sifted out the detections
|
||||
</div>
|
||||
|
||||
=== "Before"
|
||||
|
||||
```python
|
||||
import supervision as sv
|
||||
|
||||
@@ -151,6 +165,7 @@ but small on a 3840x2160 image. In such cases, we can filter out detections base
|
||||
occupied by them. In the example below, we remove too large detections.
|
||||
|
||||
=== "After"
|
||||
|
||||
```python
|
||||
import supervision as sv
|
||||
|
||||
@@ -169,6 +184,7 @@ occupied by them. In the example below, we remove too large detections.
|
||||
</div>
|
||||
|
||||
=== "Before"
|
||||
|
||||
```python
|
||||
import supervision as sv
|
||||
|
||||
@@ -193,6 +209,7 @@ can be criteria for rejecting detection. Implementing such filtering requires a
|
||||
simple and fast.
|
||||
|
||||
=== "After"
|
||||
|
||||
```python
|
||||
import supervision as sv
|
||||
|
||||
@@ -209,6 +226,7 @@ simple and fast.
|
||||
</div>
|
||||
|
||||
=== "Before"
|
||||
|
||||
```python
|
||||
import supervision as sv
|
||||
|
||||
@@ -230,6 +248,7 @@ Allows you to use `Detections` in combination with `PolygonZone` to weed out bou
|
||||
zone. In the example below you can see how to filter out all detections located in the lower part of the image.
|
||||
|
||||
=== "After"
|
||||
|
||||
```python
|
||||
import supervision as sv
|
||||
|
||||
@@ -246,6 +265,7 @@ zone. In the example below you can see how to filter out all detections located
|
||||
</div>
|
||||
|
||||
=== "Before"
|
||||
|
||||
```python
|
||||
import supervision as sv
|
||||
|
||||
@@ -266,6 +286,7 @@ zone. In the example below you can see how to filter out all detections located
|
||||
`Detections`' greatest strength, however, is that you can build arbitrarily complex logical conditions by simply combining separate conditions using `&` or `|`.
|
||||
|
||||
=== "After"
|
||||
|
||||
```python
|
||||
import supervision as sv
|
||||
|
||||
@@ -282,6 +303,7 @@ zone. In the example below you can see how to filter out all detections located
|
||||
</div>
|
||||
|
||||
=== "Before"
|
||||
|
||||
```python
|
||||
import supervision as sv
|
||||
|
||||
@@ -296,3 +318,29 @@ zone. In the example below you can see how to filter out all detections located
|
||||
{ align=center width="800" }
|
||||
|
||||
</div>
|
||||
|
||||
## Frequently Asked Questions
|
||||
|
||||
### How do I filter detections by class in supervision?
|
||||
|
||||
Use NumPy-style boolean indexing: `detections[detections.class_id == 0]` for class 0. Combine with `&` or `|` for multiple conditions.
|
||||
|
||||
### How do I filter by confidence threshold?
|
||||
|
||||
`detections[detections.confidence > 0.5]` returns only detections above the threshold. Chain with class filters for precise results.
|
||||
|
||||
### How do I filter by bounding box area?
|
||||
|
||||
`detections[detections.area > 1000]` filters by pixel area. If masks are present, `detections.area` uses mask area; otherwise it uses bounding box area from `xyxy`. Use `detections.box_area` when you specifically need bounding box area.
|
||||
|
||||
### Can I filter by box aspect ratio or dimensions?
|
||||
|
||||
Yes. Use `detections.box_aspect_ratio` for aspect ratio filtering. If you need explicit box dimensions, compute them from `detections.xyxy` as `width = detections.xyxy[:, 2] - detections.xyxy[:, 0]` and `height = detections.xyxy[:, 3] - detections.xyxy[:, 1]`.
|
||||
|
||||
### How do I remove duplicate detections (NMS) from my results?
|
||||
|
||||
Use `detections.with_nms(threshold=0.5)` — it applies non-maximum suppression on the `xyxy` boxes.
|
||||
|
||||
## Author
|
||||
|
||||
- [Piotr Skalski](https://github.com/SkalskiP) — Computer Vision Engineer, Roboflow
|
||||
|
||||
@@ -1,5 +1,11 @@
|
||||
---
|
||||
comments: true
|
||||
description: Load, split, merge, and convert computer vision datasets between YOLO, COCO, and Pascal VOC formats using supervision's DetectionDataset.
|
||||
authors:
|
||||
- name: Piotr Skalski
|
||||
role: Computer Vision Engineer, Roboflow
|
||||
github: https://github.com/SkalskiP
|
||||
date_modified: 2026-04-22
|
||||
---
|
||||
|
||||
With Supervision, you can load and manipulate classification, object detection, and
|
||||
@@ -32,8 +38,8 @@ your workspace ID, project ID, and version number.
|
||||
roboflow.login()
|
||||
|
||||
rf = roboflow.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")
|
||||
```
|
||||
|
||||
=== "YOLO"
|
||||
@@ -44,8 +50,8 @@ your workspace ID, project ID, and version number.
|
||||
roboflow.login()
|
||||
|
||||
rf = roboflow.Roboflow()
|
||||
project = rf.workspace('<WORKSPACE_ID>').project('<PROJECT_ID>')
|
||||
dataset = project.version('<PROJECT_VERSION>').download("yolov8")
|
||||
project = rf.workspace("<WORKSPACE_ID>").project("<PROJECT_ID>")
|
||||
dataset = project.version("<PROJECT_VERSION>").download("yolov8")
|
||||
```
|
||||
|
||||
=== "Pascal VOC"
|
||||
@@ -56,8 +62,8 @@ your workspace ID, project ID, and version number.
|
||||
roboflow.login()
|
||||
|
||||
rf = roboflow.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")
|
||||
```
|
||||
|
||||
## Load Dataset
|
||||
@@ -75,16 +81,16 @@ instances.
|
||||
import supervision as sv
|
||||
|
||||
ds_train = sv.DetectionDataset.from_coco(
|
||||
images_directory_path=f'{dataset.location}/train',
|
||||
annotations_path=f'{dataset.location}/train/_annotations.coco.json',
|
||||
images_directory_path=f"{dataset.location}/train",
|
||||
annotations_path=f"{dataset.location}/train/_annotations.coco.json",
|
||||
)
|
||||
ds_valid = sv.DetectionDataset.from_coco(
|
||||
images_directory_path=f'{dataset.location}/valid',
|
||||
annotations_path=f'{dataset.location}/valid/_annotations.coco.json',
|
||||
images_directory_path=f"{dataset.location}/valid",
|
||||
annotations_path=f"{dataset.location}/valid/_annotations.coco.json",
|
||||
)
|
||||
ds_test = sv.DetectionDataset.from_coco(
|
||||
images_directory_path=f'{dataset.location}/test',
|
||||
annotations_path=f'{dataset.location}/test/_annotations.coco.json',
|
||||
images_directory_path=f"{dataset.location}/test",
|
||||
annotations_path=f"{dataset.location}/test/_annotations.coco.json",
|
||||
)
|
||||
|
||||
ds_train.classes
|
||||
@@ -102,19 +108,19 @@ instances.
|
||||
import supervision as sv
|
||||
|
||||
ds_train = 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'
|
||||
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_valid = sv.DetectionDataset.from_yolo(
|
||||
images_directory_path=f'{dataset.location}/valid/images',
|
||||
annotations_directory_path=f'{dataset.location}/valid/labels',
|
||||
data_yaml_path=f'{dataset.location}/data.yaml'
|
||||
images_directory_path=f"{dataset.location}/valid/images",
|
||||
annotations_directory_path=f"{dataset.location}/valid/labels",
|
||||
data_yaml_path=f"{dataset.location}/data.yaml",
|
||||
)
|
||||
ds_test = sv.DetectionDataset.from_yolo(
|
||||
images_directory_path=f'{dataset.location}/test/images',
|
||||
annotations_directory_path=f'{dataset.location}/test/labels',
|
||||
data_yaml_path=f'{dataset.location}/data.yaml'
|
||||
images_directory_path=f"{dataset.location}/test/images",
|
||||
annotations_directory_path=f"{dataset.location}/test/labels",
|
||||
data_yaml_path=f"{dataset.location}/data.yaml",
|
||||
)
|
||||
|
||||
ds_train.classes
|
||||
@@ -132,16 +138,16 @@ instances.
|
||||
import supervision as sv
|
||||
|
||||
ds_train = sv.DetectionDataset.from_pascal_voc(
|
||||
images_directory_path=f'{dataset.location}/train/images',
|
||||
annotations_directory_path=f'{dataset.location}/train/labels'
|
||||
images_directory_path=f"{dataset.location}/train/images",
|
||||
annotations_directory_path=f"{dataset.location}/train/labels",
|
||||
)
|
||||
ds_valid = sv.DetectionDataset.from_pascal_voc(
|
||||
images_directory_path=f'{dataset.location}/valid/images',
|
||||
annotations_directory_path=f'{dataset.location}/valid/labels'
|
||||
images_directory_path=f"{dataset.location}/valid/images",
|
||||
annotations_directory_path=f"{dataset.location}/valid/labels",
|
||||
)
|
||||
ds_test = sv.DetectionDataset.from_pascal_voc(
|
||||
images_directory_path=f'{dataset.location}/test/images',
|
||||
annotations_directory_path=f'{dataset.location}/test/labels'
|
||||
images_directory_path=f"{dataset.location}/test/images",
|
||||
annotations_directory_path=f"{dataset.location}/test/labels",
|
||||
)
|
||||
|
||||
ds_train.classes
|
||||
@@ -294,12 +300,12 @@ ds = sv.DetectionDataset(...)
|
||||
|
||||
# Option 1
|
||||
for image_path, image, annotations in ds:
|
||||
... # Process each image and its annotations
|
||||
... # Process each image and its annotations
|
||||
|
||||
# Option 2
|
||||
for idx in range(len(ds)):
|
||||
image_path, image, annotations = ds[idx]
|
||||
... # Process the image and annotations at index `idx`
|
||||
... # Process the image and annotations at index `idx`
|
||||
```
|
||||
|
||||
## Visualize Dataset
|
||||
@@ -331,12 +337,9 @@ for i in range(16):
|
||||
annotated_image = label_annotator.annotate(annotated_image, annotations, labels)
|
||||
annotated_images.append(annotated_image)
|
||||
|
||||
grid = sv.create_tiles(
|
||||
sv.plot_images_grid(
|
||||
annotated_images,
|
||||
grid_size=(4, 4),
|
||||
single_tile_size=(400, 400),
|
||||
tile_padding_color=sv.Color.WHITE,
|
||||
tile_margin_color=sv.Color.WHITE
|
||||
)
|
||||
```
|
||||
|
||||
@@ -354,8 +357,8 @@ grid = sv.create_tiles(
|
||||
ds = sv.DetectionDataset(...)
|
||||
|
||||
ds.as_coco(
|
||||
images_directory_path='<IMAGE_DIRECTORY_PATH>',
|
||||
annotations_path='<ANNOTATIONS_PATH>'
|
||||
images_directory_path="<IMAGE_DIRECTORY_PATH>",
|
||||
annotations_path="<ANNOTATIONS_PATH>",
|
||||
)
|
||||
```
|
||||
|
||||
@@ -369,9 +372,9 @@ grid = sv.create_tiles(
|
||||
ds = sv.DetectionDataset(...)
|
||||
|
||||
ds.as_yolo(
|
||||
images_directory_path='<IMAGE_DIRECTORY_PATH>',
|
||||
annotations_directory_path='<ANNOTATIONS_DIRECTORY_PATH>',
|
||||
data_yaml_path='<DATA_YAML_PATH>'
|
||||
images_directory_path="<IMAGE_DIRECTORY_PATH>",
|
||||
annotations_directory_path="<ANNOTATIONS_DIRECTORY_PATH>",
|
||||
data_yaml_path="<DATA_YAML_PATH>",
|
||||
)
|
||||
```
|
||||
|
||||
@@ -385,8 +388,8 @@ grid = sv.create_tiles(
|
||||
ds = sv.DetectionDataset(...)
|
||||
|
||||
ds.as_pascal_voc(
|
||||
images_directory_path='<IMAGE_DIRECTORY_PATH>',
|
||||
annotations_directory_path='<ANNOTATIONS_DIRECTORY_PATH>'
|
||||
images_directory_path="<IMAGE_DIRECTORY_PATH>",
|
||||
annotations_directory_path="<ANNOTATIONS_DIRECTORY_PATH>",
|
||||
)
|
||||
```
|
||||
|
||||
@@ -398,16 +401,16 @@ increase the size and diversity of training datasets, leading to improved model
|
||||
performance and generalization.
|
||||
|
||||
```bash
|
||||
pip install augmentation
|
||||
pip install albumentations
|
||||
```
|
||||
|
||||
Albumentations provides a flexible and powerful API for image augmentation. The core of
|
||||
the library is the [`Compose`](https://albumentations.ai/docs/api_reference/full_reference/?h=compose#albumentations.core.composition.Compose)
|
||||
the library is the [`Compose`](https://albumentations.ai/docs/api-reference/albumentations/core/composition/#Compose)
|
||||
class, which allows you to chain multiple image transformations together. Each
|
||||
transformation is defined using a dedicated class, such as
|
||||
[`HorizontalFlip`](https://albumentations.ai/docs/api_reference/full_reference/?h=horizontalflip#albumentations.augmentations.geometric.transforms.HorizontalFlip),
|
||||
[`RandomBrightnessContrast`](https://albumentations.ai/docs/api_reference/full_reference/?h=horizontalflip#albumentations.augmentations.transforms.RandomBrightnessContrast),
|
||||
or [`Perspective`](https://albumentations.ai/docs/api_reference/full_reference/?h=horizontalflip#albumentations.augmentations.geometric.transforms.Perspective).
|
||||
[`HorizontalFlip`](https://albumentations.ai/docs/api-reference/albumentations/augmentations/geometric/flip/#HorizontalFlip),
|
||||
[`RandomBrightnessContrast`](https://albumentations.ai/docs/api-reference/albumentations/augmentations/pixel/transforms/#RandomBrightnessContrast),
|
||||
or [`Perspective`](https://albumentations.ai/docs/api-reference/albumentations/augmentations/geometric/transforms/#Perspective).
|
||||
|
||||
```python
|
||||
import albumentations as A
|
||||
@@ -416,11 +419,11 @@ augmentation = A.Compose(
|
||||
transforms=[
|
||||
A.Perspective(p=0.1),
|
||||
A.HorizontalFlip(p=0.5),
|
||||
A.RandomBrightnessContrast(p=0.5)
|
||||
A.RandomBrightnessContrast(p=0.5),
|
||||
],
|
||||
bbox_params=A.BboxParams(
|
||||
format='pascal_voc',
|
||||
label_fields=['category']
|
||||
format="pascal_voc",
|
||||
label_fields=["category"],
|
||||
),
|
||||
)
|
||||
```
|
||||
@@ -440,15 +443,37 @@ _, original_image, original_annotations = ds[0]
|
||||
output = augmentation(
|
||||
image=original_image,
|
||||
bboxes=original_annotations.xyxy,
|
||||
category=original_annotations.class_id
|
||||
category=original_annotations.class_id,
|
||||
)
|
||||
|
||||
augmented_image = output['image']
|
||||
augmented_image = output["image"]
|
||||
augmented_annotations = replace(
|
||||
original_annotations,
|
||||
xyxy=np.array(output['bboxes']),
|
||||
class_id=np.array(output['category'])
|
||||
xyxy=np.array(output["bboxes"]),
|
||||
class_id=np.array(output["category"]),
|
||||
)
|
||||
```
|
||||
|
||||

|
||||
|
||||
## Frequently Asked Questions
|
||||
|
||||
### What dataset formats does supervision support?
|
||||
|
||||
For detection datasets, supervision supports YOLO, COCO JSON, and Pascal VOC. Use `DetectionDataset.from_yolo()`, `from_coco()`, or `from_pascal_voc()` to load, and `as_yolo()`, `as_coco()`, or `as_pascal_voc()` to save. Classification datasets use `ClassificationDataset.from_folder_structure()` and `as_folder_structure()`.
|
||||
|
||||
### Can I split a dataset into train/val/test sets?
|
||||
|
||||
`DetectionDataset.split(split_ratio=0.8)` returns exactly two datasets: train (80%) and test (20%). If you need a validation set, split one of those subsets in a separate step.
|
||||
|
||||
### Can I merge two datasets together?
|
||||
|
||||
Yes. `DetectionDataset.merge([dataset_a, dataset_b])` combines multiple datasets into one. Useful for combining datasets from different sources.
|
||||
|
||||
### What augmentations are available?
|
||||
|
||||
Common augmentations such as flip, rotate, translate, scale, crop, color jitter, and Gaussian blur can be applied using an external library like Albumentations, as shown in the augmentation example above. Supervision does not provide an `sv.Augmenter` pipeline.
|
||||
|
||||
## Author
|
||||
|
||||
- [Piotr Skalski](https://github.com/SkalskiP) — Computer Vision Engineer, Roboflow
|
||||
|
||||
@@ -1,5 +1,11 @@
|
||||
---
|
||||
comments: true
|
||||
description: Save object detection results to CSV or JSON with supervision's CSVSink and JSONSink — export predictions for analysis and downstream pipelines.
|
||||
authors:
|
||||
- name: Piotr Skalski
|
||||
role: Computer Vision Engineer, Roboflow
|
||||
github: https://github.com/SkalskiP
|
||||
date_modified: 2026-04-22
|
||||
---
|
||||
|
||||
# Save Detections
|
||||
@@ -9,44 +15,47 @@ processing. This guide demonstrates how to perform video inference using the
|
||||
[Inference](https://github.com/roboflow/inference),
|
||||
[Ultralytics](https://github.com/ultralytics/ultralytics) or
|
||||
[Transformers](https://github.com/huggingface/transformers) packages and save their results with
|
||||
[`sv.CSVSink`](/latest/detection/tools/save_detections/#supervision.detection.tools.csv_sink.CSVSink) and
|
||||
[`sv.JSONSink`](/latest/detection/tools/save_detections/#supervision.detection.tools.csv_sink.JSONSink).
|
||||
[`sv.CSVSink`](https://supervision.roboflow.com/latest/detection/tools/save_detections/#supervision.detection.tools.csv_sink.CSVSink) and
|
||||
[`sv.JSONSink`](https://supervision.roboflow.com/latest/detection/tools/save_detections/#supervision.detection.tools.json_sink.JSONSink).
|
||||
|
||||
## Run Detection
|
||||
|
||||
First, you'll need to obtain predictions from your object detection or segmentation
|
||||
model. You can learn more on this topic in our
|
||||
[How to Detect and Annotate](/latest/how_to/detect_and_annotate.md) guide.
|
||||
[How to Detect and Annotate](https://supervision.roboflow.com/latest/how_to/detect_and_annotate/) guide.
|
||||
|
||||
To generate predictions for saving, initialize your model and iterate over video frames using `sv.get_video_frames_generator`. Each frame is passed to the model, and the raw output is converted into a `sv.Detections` object. This detection loop forms the foundation for both CSV and JSON export workflows shown below.
|
||||
|
||||
=== "Inference"
|
||||
|
||||
```python
|
||||
import supervision as sv
|
||||
from inference import get_model
|
||||
|
||||
model = get_model(model_id="yolov8n-640")
|
||||
frames_generator = sv.get_video_frames_generator(<SOURCE_VIDEO_PATH>)
|
||||
frames_generator = sv.get_video_frames_generator("<SOURCE_VIDEO_PATH>")
|
||||
|
||||
for frame in frames_generator:
|
||||
|
||||
results = model.infer(image)[0]
|
||||
detections = sv.Detections.from_inference(results)
|
||||
```
|
||||
|
||||
=== "Ultralytics"
|
||||
|
||||
```python
|
||||
import supervision as sv
|
||||
from ultralytics import YOLO
|
||||
|
||||
model = YOLO("yolov8n.pt")
|
||||
frames_generator = sv.get_video_frames_generator(<SOURCE_VIDEO_PATH>)
|
||||
frames_generator = sv.get_video_frames_generator("<SOURCE_VIDEO_PATH>")
|
||||
|
||||
for frame in frames_generator:
|
||||
|
||||
results = model(frame)[0]
|
||||
detections = sv.Detections.from_ultralytics(results)
|
||||
```
|
||||
|
||||
=== "Transformers"
|
||||
|
||||
```python
|
||||
import torch
|
||||
import supervision as sv
|
||||
@@ -54,10 +63,9 @@ model. You can learn more on this topic in our
|
||||
|
||||
processor = DetrImageProcessor.from_pretrained("facebook/detr-resnet-50")
|
||||
model = DetrForObjectDetection.from_pretrained("facebook/detr-resnet-50")
|
||||
frames_generator = sv.get_video_frames_generator(<SOURCE_VIDEO_PATH>)
|
||||
frames_generator = sv.get_video_frames_generator("<SOURCE_VIDEO_PATH>")
|
||||
|
||||
for frame in frames_generator:
|
||||
|
||||
frame = sv.cv2_to_pillow(frame)
|
||||
inputs = processor(images=frame, return_tensors="pt")
|
||||
|
||||
@@ -67,27 +75,29 @@ model. You can learn more on this topic in our
|
||||
width, height = frame.size
|
||||
target_size = torch.tensor([[height, width]])
|
||||
results = processor.post_process_object_detection(
|
||||
outputs=outputs, target_sizes=target_size)[0]
|
||||
outputs=outputs, target_sizes=target_size
|
||||
)[0]
|
||||
detections = sv.Detections.from_transformers(results)
|
||||
```
|
||||
|
||||
## Save Detections as CSV
|
||||
|
||||
To save detections to a `.CSV` file, open our
|
||||
[`sv.CSVSink`](/latest/detection/tools/save_detections/#supervision.detection.tools.csv_sink.CSVSink)
|
||||
[`sv.CSVSink`](https://supervision.roboflow.com/latest/detection/tools/save_detections/#supervision.detection.tools.csv_sink.CSVSink)
|
||||
and then pass the
|
||||
[`sv.Detections`](/latest/detection/core/#supervision.detection.core.Detections)
|
||||
[`sv.Detections`](https://supervision.roboflow.com/latest/detection/core/#supervision.detection.core.Detections)
|
||||
object resulting from the inference to it. Its fields are parsed and saved on disk.
|
||||
|
||||
=== "Inference"
|
||||
|
||||
```{ .py hl_lines="7 12" }
|
||||
import supervision as sv
|
||||
from inference import get_model
|
||||
|
||||
model = get_model(model_id="yolov8n-640")
|
||||
frames_generator = sv.get_video_frames_generator(<SOURCE_VIDEO_PATH>)
|
||||
frames_generator = sv.get_video_frames_generator("<SOURCE_VIDEO_PATH>")
|
||||
|
||||
with sv.CSVSink(<TARGET_CSV_PATH>) as sink:
|
||||
with sv.CSVSink("<TARGET_CSV_PATH>") as sink:
|
||||
for frame in frames_generator:
|
||||
|
||||
results = model.infer(image)[0]
|
||||
@@ -96,14 +106,15 @@ object resulting from the inference to it. Its fields are parsed and saved on di
|
||||
```
|
||||
|
||||
=== "Ultralytics"
|
||||
|
||||
```{ .py hl_lines="7 12" }
|
||||
import supervision as sv
|
||||
from ultralytics import YOLO
|
||||
|
||||
model = YOLO("yolov8n.pt")
|
||||
frames_generator = sv.get_video_frames_generator(<SOURCE_VIDEO_PATH>)
|
||||
frames_generator = sv.get_video_frames_generator("<SOURCE_VIDEO_PATH>")
|
||||
|
||||
with sv.CSVSink(<TARGET_CSV_PATH>) as sink:
|
||||
with sv.CSVSink("<TARGET_CSV_PATH>") as sink:
|
||||
for frame in frames_generator:
|
||||
|
||||
results = model(frame)[0]
|
||||
@@ -112,6 +123,7 @@ object resulting from the inference to it. Its fields are parsed and saved on di
|
||||
```
|
||||
|
||||
=== "Transformers"
|
||||
|
||||
```{ .py hl_lines="9 23" }
|
||||
import torch
|
||||
import supervision as sv
|
||||
@@ -119,9 +131,9 @@ object resulting from the inference to it. Its fields are parsed and saved on di
|
||||
|
||||
processor = DetrImageProcessor.from_pretrained("facebook/detr-resnet-50")
|
||||
model = DetrForObjectDetection.from_pretrained("facebook/detr-resnet-50")
|
||||
frames_generator = sv.get_video_frames_generator(<SOURCE_VIDEO_PATH>)
|
||||
frames_generator = sv.get_video_frames_generator("<SOURCE_VIDEO_PATH>")
|
||||
|
||||
with sv.CSVSink(<TARGET_CSV_PATH>) as sink:
|
||||
with sv.CSVSink("<TARGET_CSV_PATH>") as sink:
|
||||
for frame in frames_generator:
|
||||
|
||||
frame = sv.cv2_to_pillow(frame)
|
||||
@@ -147,21 +159,22 @@ object resulting from the inference to it. Its fields are parsed and saved on di
|
||||
## Custom Fields
|
||||
|
||||
Besides regular fields in
|
||||
[`sv.Detections`](/latest/detection/core/#supervision.detection.core.Detections),
|
||||
[`sv.CSVSink`](/latest/detection/tools/save_detections/#supervision.detection.tools.csv_sink.CSVSink)
|
||||
[`sv.Detections`](https://supervision.roboflow.com/latest/detection/core/#supervision.detection.core.Detections),
|
||||
[`sv.CSVSink`](https://supervision.roboflow.com/latest/detection/tools/save_detections/#supervision.detection.tools.csv_sink.CSVSink)
|
||||
also allows you to add custom information to each row, which can be passed via the
|
||||
`custom_data` dictionary. Let's utilize this feature to save information about the
|
||||
frame index from which the detections originate.
|
||||
|
||||
=== "Inference"
|
||||
|
||||
```{ .py hl_lines="8 12" }
|
||||
import supervision as sv
|
||||
from inference import get_model
|
||||
|
||||
model = get_model(model_id="yolov8n-640")
|
||||
frames_generator = sv.get_video_frames_generator(<SOURCE_VIDEO_PATH>)
|
||||
frames_generator = sv.get_video_frames_generator("<SOURCE_VIDEO_PATH>")
|
||||
|
||||
with sv.CSVSink(<TARGET_CSV_PATH>) as sink:
|
||||
with sv.CSVSink("<TARGET_CSV_PATH>") as sink:
|
||||
for frame_index, frame in enumerate(frames_generator):
|
||||
|
||||
results = model.infer(image)[0]
|
||||
@@ -170,14 +183,15 @@ frame index from which the detections originate.
|
||||
```
|
||||
|
||||
=== "Ultralytics"
|
||||
|
||||
```{ .py hl_lines="8 12" }
|
||||
import supervision as sv
|
||||
from ultralytics import YOLO
|
||||
|
||||
model = YOLO("yolov8n.pt")
|
||||
frames_generator = sv.get_video_frames_generator(<SOURCE_VIDEO_PATH>)
|
||||
frames_generator = sv.get_video_frames_generator("<SOURCE_VIDEO_PATH>")
|
||||
|
||||
with sv.CSVSink(<TARGET_CSV_PATH>) as sink:
|
||||
with sv.CSVSink("<TARGET_CSV_PATH>") as sink:
|
||||
for frame_index, frame in enumerate(frames_generator):
|
||||
|
||||
results = model(frame)[0]
|
||||
@@ -186,6 +200,7 @@ frame index from which the detections originate.
|
||||
```
|
||||
|
||||
=== "Transformers"
|
||||
|
||||
```{ .py hl_lines="10 23" }
|
||||
import torch
|
||||
import supervision as sv
|
||||
@@ -193,9 +208,9 @@ frame index from which the detections originate.
|
||||
|
||||
processor = DetrImageProcessor.from_pretrained("facebook/detr-resnet-50")
|
||||
model = DetrForObjectDetection.from_pretrained("facebook/detr-resnet-50")
|
||||
frames_generator = sv.get_video_frames_generator(<SOURCE_VIDEO_PATH>)
|
||||
frames_generator = sv.get_video_frames_generator("<SOURCE_VIDEO_PATH>")
|
||||
|
||||
with sv.CSVSink(<TARGET_CSV_PATH>) as sink:
|
||||
with sv.CSVSink("<TARGET_CSV_PATH>") as sink:
|
||||
for frame_index, frame in enumerate(frames_generator):
|
||||
|
||||
frame = sv.cv2_to_pillow(frame)
|
||||
@@ -222,19 +237,20 @@ frame index from which the detections originate.
|
||||
|
||||
If you prefer to save the result in a `.JSON` file instead of a `.CSV` file, all you
|
||||
need to do is replace
|
||||
[`sv.CSVSink`](/latest/detection/tools/save_detections/#supervision.detection.tools.csv_sink.CSVSink)
|
||||
[`sv.CSVSink`](https://supervision.roboflow.com/latest/detection/tools/save_detections/#supervision.detection.tools.csv_sink.CSVSink)
|
||||
with
|
||||
[`sv.JSONSink`](/latest/detection/tools/save_detections/#supervision.detection.tools.csv_sink.JSONSink).
|
||||
[`sv.JSONSink`](https://supervision.roboflow.com/latest/detection/tools/save_detections/#supervision.detection.tools.json_sink.JSONSink).
|
||||
|
||||
=== "Inference"
|
||||
|
||||
```{ .py hl_lines="7" }
|
||||
import supervision as sv
|
||||
from inference import get_model
|
||||
|
||||
model = get_model(model_id="yolov8n-640")
|
||||
frames_generator = sv.get_video_frames_generator(<SOURCE_VIDEO_PATH>)
|
||||
frames_generator = sv.get_video_frames_generator("<SOURCE_VIDEO_PATH>")
|
||||
|
||||
with sv.JSONSink(<TARGET_CSV_PATH>) as sink:
|
||||
with sv.JSONSink("<TARGET_JSON_PATH>") as sink:
|
||||
for frame_index, frame in enumerate(frames_generator):
|
||||
|
||||
results = model.infer(image)[0]
|
||||
@@ -243,14 +259,15 @@ with
|
||||
```
|
||||
|
||||
=== "Ultralytics"
|
||||
|
||||
```{ .py hl_lines="7" }
|
||||
import supervision as sv
|
||||
from ultralytics import YOLO
|
||||
|
||||
model = YOLO("yolov8n.pt")
|
||||
frames_generator = sv.get_video_frames_generator(<SOURCE_VIDEO_PATH>)
|
||||
frames_generator = sv.get_video_frames_generator("<SOURCE_VIDEO_PATH>")
|
||||
|
||||
with sv.JSONSink(<TARGET_CSV_PATH>) as sink:
|
||||
with sv.JSONSink("<TARGET_JSON_PATH>") as sink:
|
||||
for frame_index, frame in enumerate(frames_generator):
|
||||
|
||||
results = model(frame)[0]
|
||||
@@ -259,6 +276,7 @@ with
|
||||
```
|
||||
|
||||
=== "Transformers"
|
||||
|
||||
```{ .py hl_lines="9" }
|
||||
import torch
|
||||
import supervision as sv
|
||||
@@ -266,9 +284,9 @@ with
|
||||
|
||||
processor = DetrImageProcessor.from_pretrained("facebook/detr-resnet-50")
|
||||
model = DetrForObjectDetection.from_pretrained("facebook/detr-resnet-50")
|
||||
frames_generator = sv.get_video_frames_generator(<SOURCE_VIDEO_PATH>)
|
||||
frames_generator = sv.get_video_frames_generator("<SOURCE_VIDEO_PATH>")
|
||||
|
||||
with sv.JSONSink(<TARGET_CSV_PATH>) as sink:
|
||||
with sv.JSONSink("<TARGET_JSON_PATH>") as sink:
|
||||
for frame_index, frame in enumerate(frames_generator):
|
||||
|
||||
frame = sv.cv2_to_pillow(frame)
|
||||
@@ -284,3 +302,25 @@ with
|
||||
detections = sv.Detections.from_transformers(results)
|
||||
sink.append(detections, {"frame_index": frame_index})
|
||||
```
|
||||
|
||||
## Frequently Asked Questions
|
||||
|
||||
### How do I save detections to CSV with supervision?
|
||||
|
||||
Open `sv.CSVSink("output.csv")` as a context manager and call `sink.append(detections)` for each frame. The CSV includes box coordinates, confidence, class ID, tracker ID, and any fields stored in `detections.data`.
|
||||
|
||||
### Can I save detections to JSON instead?
|
||||
|
||||
Yes. Open `sv.JSONSink("output.json")` as a context manager and call `sink.append(detections)` for each frame. The file is written as a JSON array when the context exits.
|
||||
|
||||
### Can I add custom fields to the saved output?
|
||||
|
||||
Yes. Pass a dict as the second argument: `sink.append(detections, {"frame_index": 5})` — the keys become extra columns in the CSV or extra fields in the JSON.
|
||||
|
||||
### Can I save only specific classes or confidence levels?
|
||||
|
||||
Filter the `Detections` object before saving: `sink.append(detections[detections.confidence > 0.7])`.
|
||||
|
||||
## Author
|
||||
|
||||
- [Piotr Skalski](https://github.com/SkalskiP) — Computer Vision Engineer, Roboflow
|
||||
|
||||
@@ -1,12 +1,20 @@
|
||||
---
|
||||
comments: true
|
||||
status: new
|
||||
description: Track objects across video frames with ByteTrack in supervision — assign persistent IDs and analyze motion from any object detection model.
|
||||
authors:
|
||||
- name: Piotr Skalski
|
||||
role: Computer Vision Engineer, Roboflow
|
||||
github: https://github.com/SkalskiP
|
||||
- name: Soumik Mandal
|
||||
role: ML Engineer, Roboflow
|
||||
github: https://github.com/soumik12345
|
||||
date_modified: 2026-04-22
|
||||
---
|
||||
|
||||
# Track Objects
|
||||
|
||||
Leverage Supervision's advanced capabilities for enhancing your video analysis by
|
||||
seamlessly [tracking](/latest/trackers/) objects recognized by
|
||||
seamlessly [tracking](https://supervision.roboflow.com/latest/trackers/) objects recognized by
|
||||
a multitude of object detection, segmentation and keypoint 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
|
||||
@@ -17,8 +25,10 @@ for a deeper analysis.
|
||||
## Object Detection & Segmentation
|
||||
|
||||
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]`](/latest/assets/) extension.
|
||||
example. You can do this using the
|
||||
[`supervision.assets`](https://supervision.roboflow.com/latest/assets/) module included in the base package.
|
||||
|
||||
This section demonstrates how to detect and segment objects in video frames using YOLOv8 with either the Inference or Ultralytics package. You will download a sample video, define a per-frame callback function that runs model prediction, and process the entire video to produce an annotated output file.
|
||||
|
||||
```python
|
||||
from supervision.assets import download_assets, VideoAssets
|
||||
@@ -35,7 +45,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](/latest/how_to/detect_and_annotate/#load-predictions-into-supervision)
|
||||
[link](https://supervision.roboflow.com/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
|
||||
@@ -55,7 +65,7 @@ it will be modified to include tracking, labeling, and trace annotations.
|
||||
from ultralytics import YOLO
|
||||
|
||||
model = YOLO("yolov8n.pt")
|
||||
box_annotator = sv.BoundingBoxAnnotator()
|
||||
box_annotator = sv.BoxAnnotator()
|
||||
|
||||
def callback(frame: np.ndarray, _: int) -> np.ndarray:
|
||||
results = model(frame)[0]
|
||||
@@ -76,8 +86,8 @@ it will be modified to include tracking, labeling, and trace annotations.
|
||||
import supervision as sv
|
||||
from inference.models.utils import get_roboflow_model
|
||||
|
||||
model = get_roboflow_model(model_id="yolov8n-640", api_key=<ROBOFLOW API KEY>)
|
||||
box_annotator = sv.BoundingBoxAnnotator()
|
||||
model = get_roboflow_model(model_id="yolov8n-640", api_key="<ROBOFLOW_API_KEY>")
|
||||
box_annotator = sv.BoxAnnotator()
|
||||
|
||||
def callback(frame: np.ndarray, _: int) -> np.ndarray:
|
||||
results = model.infer(frame)[0]
|
||||
@@ -99,7 +109,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`](/latest/trackers/#supervision.tracker.byte_tracker.core.ByteTrack)
|
||||
[`sv.ByteTrack`](https://supervision.roboflow.com/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.
|
||||
|
||||
@@ -112,7 +122,7 @@ enabling the continuous following of the object's motion path across different f
|
||||
|
||||
model = YOLO("yolov8n.pt")
|
||||
tracker = sv.ByteTrack()
|
||||
box_annotator = sv.BoundingBoxAnnotator()
|
||||
box_annotator = sv.BoxAnnotator()
|
||||
|
||||
def callback(frame: np.ndarray, _: int) -> np.ndarray:
|
||||
results = model(frame)[0]
|
||||
@@ -134,9 +144,9 @@ enabling the continuous following of the object's motion path across different f
|
||||
import supervision as sv
|
||||
from inference.models.utils import get_roboflow_model
|
||||
|
||||
model = get_roboflow_model(model_id="yolov8n-640", api_key=<ROBOFLOW API KEY>)
|
||||
model = get_roboflow_model(model_id="yolov8n-640", api_key="<ROBOFLOW_API_KEY>")
|
||||
tracker = sv.ByteTrack()
|
||||
box_annotator = sv.BoundingBoxAnnotator()
|
||||
box_annotator = sv.BoxAnnotator()
|
||||
|
||||
def callback(frame: np.ndarray, _: int) -> np.ndarray:
|
||||
results = model.infer(frame)[0]
|
||||
@@ -155,7 +165,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`](/latest/detection/annotators/#supervision.annotators.core.LabelAnnotator)
|
||||
[`sv.LabelAnnotator`](https://supervision.roboflow.com/latest/detection/annotators/#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.
|
||||
|
||||
@@ -168,7 +178,7 @@ offering a clear visual representation of each object's class and unique identif
|
||||
|
||||
model = YOLO("yolov8n.pt")
|
||||
tracker = sv.ByteTrack()
|
||||
box_annotator = sv.BoundingBoxAnnotator()
|
||||
box_annotator = sv.BoxAnnotator()
|
||||
label_annotator = sv.LabelAnnotator()
|
||||
|
||||
def callback(frame: np.ndarray, _: int) -> np.ndarray:
|
||||
@@ -177,9 +187,9 @@ offering a clear visual representation of each object's class and unique identif
|
||||
detections = tracker.update_with_detections(detections)
|
||||
|
||||
labels = [
|
||||
f"#{tracker_id} {results.names[class_id]}"
|
||||
for class_id, tracker_id
|
||||
in zip(detections.class_id, detections.tracker_id)
|
||||
f"#{tracker_id} {class_name}"
|
||||
for class_name, tracker_id
|
||||
in zip(detections.data["class_name"], detections.tracker_id)
|
||||
]
|
||||
|
||||
annotated_frame = box_annotator.annotate(
|
||||
@@ -201,9 +211,9 @@ offering a clear visual representation of each object's class and unique identif
|
||||
import supervision as sv
|
||||
from inference.models.utils import get_roboflow_model
|
||||
|
||||
model = get_roboflow_model(model_id="yolov8n-640", api_key=<ROBOFLOW API KEY>)
|
||||
model = get_roboflow_model(model_id="yolov8n-640", api_key="<ROBOFLOW_API_KEY>")
|
||||
tracker = sv.ByteTrack()
|
||||
box_annotator = sv.BoundingBoxAnnotator()
|
||||
box_annotator = sv.BoxAnnotator()
|
||||
label_annotator = sv.LabelAnnotator()
|
||||
|
||||
def callback(frame: np.ndarray, _: int) -> np.ndarray:
|
||||
@@ -212,9 +222,9 @@ offering a clear visual representation of each object's class and unique identif
|
||||
detections = tracker.update_with_detections(detections)
|
||||
|
||||
labels = [
|
||||
f"#{tracker_id} {results.names[class_id]}"
|
||||
for class_id, tracker_id
|
||||
in zip(detections.class_id, detections.tracker_id)
|
||||
f"#{tracker_id} {class_name}"
|
||||
for class_name, tracker_id
|
||||
in zip(detections.data["class_name"], detections.tracker_id)
|
||||
]
|
||||
|
||||
annotated_frame = box_annotator.annotate(
|
||||
@@ -237,7 +247,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`](/latest/detection/annotators/#supervision.annotators.core.TraceAnnotator),
|
||||
[`sv.TraceAnnotator`](https://supervision.roboflow.com/latest/detection/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.
|
||||
|
||||
@@ -250,7 +260,7 @@ movement patterns and interactions between objects in the video.
|
||||
|
||||
model = YOLO("yolov8n.pt")
|
||||
tracker = sv.ByteTrack()
|
||||
box_annotator = sv.BoundingBoxAnnotator()
|
||||
box_annotator = sv.BoxAnnotator()
|
||||
label_annotator = sv.LabelAnnotator()
|
||||
trace_annotator = sv.TraceAnnotator()
|
||||
|
||||
@@ -260,9 +270,9 @@ movement patterns and interactions between objects in the video.
|
||||
detections = tracker.update_with_detections(detections)
|
||||
|
||||
labels = [
|
||||
f"#{tracker_id} {results.names[class_id]}"
|
||||
for class_id, tracker_id
|
||||
in zip(detections.class_id, detections.tracker_id)
|
||||
f"#{tracker_id} {class_name}"
|
||||
for class_name, tracker_id
|
||||
in zip(detections.data["class_name"], detections.tracker_id)
|
||||
]
|
||||
|
||||
annotated_frame = box_annotator.annotate(
|
||||
@@ -286,9 +296,9 @@ movement patterns and interactions between objects in the video.
|
||||
import supervision as sv
|
||||
from inference.models.utils import get_roboflow_model
|
||||
|
||||
model = get_roboflow_model(model_id="yolov8n-640", api_key=<ROBOFLOW API KEY>)
|
||||
model = get_roboflow_model(model_id="yolov8n-640", api_key="<ROBOFLOW_API_KEY>")
|
||||
tracker = sv.ByteTrack()
|
||||
box_annotator = sv.BoundingBoxAnnotator()
|
||||
box_annotator = sv.BoxAnnotator()
|
||||
label_annotator = sv.LabelAnnotator()
|
||||
trace_annotator = sv.TraceAnnotator()
|
||||
|
||||
@@ -298,9 +308,9 @@ movement patterns and interactions between objects in the video.
|
||||
detections = tracker.update_with_detections(detections)
|
||||
|
||||
labels = [
|
||||
f"#{tracker_id} {results.names[class_id]}"
|
||||
for class_id, tracker_id
|
||||
in zip(detections.class_id, detections.tracker_id)
|
||||
f"#{tracker_id} {class_name}"
|
||||
for class_name, tracker_id
|
||||
in zip(detections.data["class_name"], detections.tracker_id)
|
||||
]
|
||||
|
||||
annotated_frame = box_annotator.annotate(
|
||||
@@ -326,7 +336,7 @@ movement patterns and interactions between objects in the video.
|
||||
Models aren't limited to object detection and segmentation. Keypoint detection allows for detailed analysis of body joints and connections, especially valuable for applications like human pose estimation. This section introduces keypoint tracking. We'll walk through the steps of annotating keypoints, converting them into bounding box detections compatible with `ByteTrack`, and applying detection smoothing for enhanced stability.
|
||||
|
||||
To make it easier for you to follow our tutorial, let's download the video we will use as an
|
||||
example. You can do this using [`supervision[assets]`](/latest/assets/) extension.
|
||||
example. You can do this using the [`supervision.assets`](https://supervision.roboflow.com/latest/assets/) module included in the base package.
|
||||
|
||||
```python
|
||||
from supervision.assets import download_assets, VideoAssets
|
||||
@@ -341,11 +351,11 @@ download_assets(VideoAssets.SKIING)
|
||||
### Keypoint Detection
|
||||
|
||||
First, you'll need to obtain predictions from your keypoint detection 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](/latest/keypoint/core/) for guidance on how to plug in other models.
|
||||
Supervision is versatile and compatible with various models. Check this [link](https://supervision.roboflow.com/latest/keypoint/core/) for guidance on how to plug in other models.
|
||||
|
||||
We will define a `callback` function, which will process each frame of the video by obtaining model predictions and then annotating the frame based on these predictions.
|
||||
|
||||
Let's immediately visualize the results with our [`EdgeAnnotator`](/latest/keypoint/annotators/#supervision.keypoint.annotators.EdgeAnnotator) and [`VertexAnnotator`](https://supervision.roboflow.com/latest/keypoint/annotators/#supervision.keypoint.annotators.VertexAnnotator).
|
||||
Let's immediately visualize the results with our [`EdgeAnnotator`](https://supervision.roboflow.com/latest/keypoint/annotators/#supervision.key_points.annotators.EdgeAnnotator) and [`VertexAnnotator`](https://supervision.roboflow.com/latest/keypoint/annotators/#supervision.key_points.annotators.VertexAnnotator).
|
||||
|
||||
=== "Ultralytics"
|
||||
|
||||
@@ -382,7 +392,7 @@ Let's immediately visualize the results with our [`EdgeAnnotator`](/latest/keypo
|
||||
from inference.models.utils import get_roboflow_model
|
||||
|
||||
model = get_roboflow_model(
|
||||
model_id="yolov8m-pose-640", api_key=<ROBOFLOW API KEY>)
|
||||
model_id="yolov8m-pose-640", api_key="<ROBOFLOW_API_KEY>")
|
||||
edge_annotator = sv.EdgeAnnotator()
|
||||
vertex_annotator = sv.VertexAnnotator()
|
||||
|
||||
@@ -408,9 +418,9 @@ Let's immediately visualize the results with our [`EdgeAnnotator`](/latest/keypo
|
||||
|
||||
### Convert to Detections
|
||||
|
||||
Keypoint tracking is currently supported via the conversion of `KeyPoints` to `Detections`. This is achieved with the [`KeyPoints.as_detections()`](/latest/keypoint/core/#supervision.keypoint.core.KeyPoints.as_detections) function.
|
||||
Keypoint tracking is currently supported via the conversion of `KeyPoints` to `Detections`. This is achieved with the [`KeyPoints.as_detections()`](https://supervision.roboflow.com/latest/keypoint/core/#supervision.key_points.core.KeyPoints.as_detections) function.
|
||||
|
||||
Let's convert to detections and visualize the results with our [`BoxAnnotator`](/latest/detection/annotators/#supervision.annotators.core.BoxAnnotator).
|
||||
Let's convert to detections and visualize the results with our [`BoxAnnotator`](https://supervision.roboflow.com/latest/detection/annotators/#supervision.annotators.core.BoxAnnotator).
|
||||
|
||||
!!! tip
|
||||
|
||||
@@ -455,7 +465,7 @@ Let's convert to detections and visualize the results with our [`BoxAnnotator`](
|
||||
from inference.models.utils import get_roboflow_model
|
||||
|
||||
model = get_roboflow_model(
|
||||
model_id="yolov8m-pose-640", api_key=<ROBOFLOW API KEY>)
|
||||
model_id="yolov8m-pose-640", api_key="<ROBOFLOW_API_KEY>")
|
||||
edge_annotator = sv.EdgeAnnotator()
|
||||
vertex_annotator = sv.VertexAnnotator()
|
||||
box_annotator = sv.BoxAnnotator()
|
||||
@@ -485,7 +495,7 @@ Let's convert to detections and visualize the results with our [`BoxAnnotator`](
|
||||
|
||||
### Keypoint Tracking
|
||||
|
||||
Now that we have a `Detections` object, we can track it throughout the video. Utilizing Supervision’s [`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. We shall visualize the result with `TraceAnnotator`.
|
||||
Now that we have a `Detections` object, we can track it throughout the video. Utilizing Supervision's [`sv.ByteTrack`](https://supervision.roboflow.com/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. We shall visualize the result with `TraceAnnotator`.
|
||||
|
||||
=== "Ultralytics"
|
||||
|
||||
@@ -532,7 +542,7 @@ Now that we have a `Detections` object, we can track it throughout the video. Ut
|
||||
from inference.models.utils import get_roboflow_model
|
||||
|
||||
model = get_roboflow_model(
|
||||
model_id="yolov8m-pose-640", api_key=<ROBOFLOW API KEY>)
|
||||
model_id="yolov8m-pose-640", api_key="<ROBOFLOW_API_KEY>")
|
||||
edge_annotator = sv.EdgeAnnotator()
|
||||
vertex_annotator = sv.VertexAnnotator()
|
||||
box_annotator = sv.BoxAnnotator()
|
||||
@@ -568,7 +578,7 @@ Now that we have a `Detections` object, we can track it throughout the video. Ut
|
||||
|
||||
### Bonus: Smoothing
|
||||
|
||||
We could stop here as we have successfully tracked the object detected by the keypoint model. However, we can further enhance the stability of the boxes by applying [`DetectionsSmoother`](/latest/detection/tools/smoother/). This tool helps in stabilizing the boxes by smoothing the bounding box coordinates across frames. It is very simple to use:
|
||||
We could stop here as we have successfully tracked the object detected by the keypoint model. However, we can further enhance the stability of the boxes by applying [`DetectionsSmoother`](https://supervision.roboflow.com/latest/detection/tools/smoother/). This tool helps in stabilizing the boxes by smoothing the bounding box coordinates across frames. It is very simple to use:
|
||||
|
||||
=== "Ultralytics"
|
||||
|
||||
@@ -617,7 +627,7 @@ We could stop here as we have successfully tracked the object detected by the ke
|
||||
from inference.models.utils import get_roboflow_model
|
||||
|
||||
model = get_roboflow_model(
|
||||
model_id="yolov8m-pose-640", api_key=<ROBOFLOW API KEY>)
|
||||
model_id="yolov8m-pose-640", api_key="<ROBOFLOW_API_KEY>")
|
||||
edge_annotator = sv.EdgeAnnotator()
|
||||
vertex_annotator = sv.VertexAnnotator()
|
||||
box_annotator = sv.BoxAnnotator()
|
||||
@@ -654,3 +664,26 @@ We could stop here as we have successfully tracked the object detected by the ke
|
||||
</video>
|
||||
|
||||
This structured walkthrough should give a detailed pathway to annotate videos effectively using Supervision’s various functionalities, including object tracking and trace annotations.
|
||||
|
||||
## Frequently Asked Questions
|
||||
|
||||
### How do I track objects across video frames with supervision?
|
||||
|
||||
Pass `Detections` to `sv.ByteTrack.update_with_detections()` on each frame. The tracker assigns persistent IDs. Combine with `sv.TraceAnnotator` to visualize trajectories. `sv.ByteTrack` is deprecated in favor of `ByteTrackTracker` from the `trackers` package, where the update method is named `update()`.
|
||||
|
||||
### What should I know about ByteTrack?
|
||||
|
||||
ByteTrack uses low-confidence detections during association, which can improve continuity during missed or weak detections. Supervision's built-in `ByteTrack` wrapper is deprecated in favor of the external `trackers` package.
|
||||
|
||||
### Can I track instances instead of bounding boxes?
|
||||
|
||||
Yes. ByteTrack tracks bounding boxes. For instance masks, use `sv.MaskAnnotator` with the tracker IDs to color-code each tracked object consistently.
|
||||
|
||||
### Does ByteTrack work with any detection model?
|
||||
|
||||
Yes. ByteTrack is model-agnostic - it accepts any `Detections` object with bounding boxes, regardless of the supported converter or model output that produced it.
|
||||
|
||||
## Authors
|
||||
|
||||
- [Piotr Skalski](https://github.com/SkalskiP) — Computer Vision Engineer, Roboflow
|
||||
- [Soumik Mandal](https://github.com/soumik12345) — ML Engineer, Roboflow
|
||||
|
||||
+36
-11
@@ -4,19 +4,34 @@ comments: true
|
||||
hide:
|
||||
- navigation
|
||||
- toc
|
||||
description: Open-source Python library providing computer vision tools for annotating detections, tracking objects, counting in zones, and processing datasets.
|
||||
---
|
||||
|
||||
<div class="md-typeset">
|
||||
<h1></h1>
|
||||
</div>
|
||||
|
||||
<div align="center" id="logo">
|
||||
<div align="center" id="logo" style="padding-top: 1rem;">
|
||||
<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>
|
||||
|
||||
<style>
|
||||
#hello {
|
||||
margin: 0;
|
||||
}
|
||||
</style>
|
||||
|
||||
## What is Supervision?
|
||||
|
||||
Supervision is an open-source Python library by Roboflow for building computer vision applications. It provides a unified `Detections` object with converters for supported outputs from Ultralytics, Roboflow Inference, Transformers, SAM, Detectron2, MMDetection, YOLO-NAS, PaddleDet, NCNN, Azure AI Vision, and VLM parsers.
|
||||
|
||||
With Supervision you can annotate images and video with bounding boxes, masks, and labels; track objects across frames with persistent IDs; count and filter detections inside polygon zones; load and convert datasets between YOLO, COCO, and Pascal VOC formats; and benchmark model performance with mAP and confusion matrices.
|
||||
|
||||
Supervision is MIT licensed, has 38,000+ GitHub stars, and over 1 million monthly PyPI downloads. It is developed in public on GitHub for production computer vision workflows.
|
||||
|
||||
## 👋 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!
|
||||
@@ -31,14 +46,15 @@ We write your reusable computer vision tools. Whether you need to load your data
|
||||
## 💻 Install
|
||||
|
||||
You can install `supervision` in a
|
||||
[**Python>=3.8**](https://www.python.org/) environment.
|
||||
[**Python>=3.9**](https://www.python.org/) environment.
|
||||
|
||||
!!! example "Installation"
|
||||
|
||||
=== "pip (recommended)"
|
||||
|
||||
[](https://badge.fury.io/py/supervision)
|
||||
[](https://pypistats.org/packages/supervision)
|
||||
[](https://github.com/roboflow/supervision/blob/main/LICENSE.md)
|
||||
[](../LICENSE.md)
|
||||
[](https://badge.fury.io/py/supervision)
|
||||
|
||||
```bash
|
||||
@@ -46,9 +62,10 @@ You can install `supervision` in a
|
||||
```
|
||||
|
||||
=== "poetry"
|
||||
|
||||
[](https://badge.fury.io/py/supervision)
|
||||
[](https://pypistats.org/packages/supervision)
|
||||
[](https://github.com/roboflow/supervision/blob/main/LICENSE.md)
|
||||
[](../LICENSE.md)
|
||||
[](https://badge.fury.io/py/supervision)
|
||||
|
||||
```bash
|
||||
@@ -56,9 +73,10 @@ You can install `supervision` in a
|
||||
```
|
||||
|
||||
=== "uv"
|
||||
|
||||
[](https://badge.fury.io/py/supervision)
|
||||
[](https://pypistats.org/packages/supervision)
|
||||
[](https://github.com/roboflow/supervision/blob/main/LICENSE.md)
|
||||
[](../LICENSE.md)
|
||||
[](https://badge.fury.io/py/supervision)
|
||||
|
||||
```bash
|
||||
@@ -72,18 +90,20 @@ You can install `supervision` in a
|
||||
```
|
||||
|
||||
=== "rye"
|
||||
|
||||
[](https://badge.fury.io/py/supervision)
|
||||
[](https://pypistats.org/packages/supervision)
|
||||
[](https://github.com/roboflow/supervision/blob/main/LICENSE.md)
|
||||
[](../LICENSE.md)
|
||||
[](https://badge.fury.io/py/supervision)
|
||||
|
||||
```bash
|
||||
rye add supervision
|
||||
```
|
||||
|
||||
|
||||
!!! example "conda/mamba install"
|
||||
|
||||
=== "conda"
|
||||
|
||||
[](https://anaconda.org/conda-forge/supervision) [](https://anaconda.org/conda-forge/supervision) [](https://anaconda.org/conda-forge/supervision) [](https://anaconda.org/conda-forge/supervision)
|
||||
|
||||
```bash
|
||||
@@ -91,6 +111,7 @@ You can install `supervision` in a
|
||||
```
|
||||
|
||||
=== "mamba"
|
||||
|
||||
[](https://anaconda.org/conda-forge/supervision) [](https://anaconda.org/conda-forge/supervision) [](https://anaconda.org/conda-forge/supervision) [](https://anaconda.org/conda-forge/supervision)
|
||||
|
||||
```bash
|
||||
@@ -98,7 +119,9 @@ You can install `supervision` in a
|
||||
```
|
||||
|
||||
!!! example "git clone (for development)"
|
||||
|
||||
=== "virtualenv"
|
||||
|
||||
```bash
|
||||
# clone repository and navigate to root directory
|
||||
git clone --depth 1 -b develop https://github.com/roboflow/supervision.git
|
||||
@@ -113,18 +136,20 @@ You can install `supervision` in a
|
||||
pip install -e "."
|
||||
```
|
||||
|
||||
=== "poetry"
|
||||
=== "uv"
|
||||
|
||||
```bash
|
||||
# clone repository and navigate to root directory
|
||||
git clone --depth 1 -b develop https://github.com/roboflow/supervision.git
|
||||
cd supervision
|
||||
|
||||
# setup python environment and activate it
|
||||
poetry env use python3.10
|
||||
poetry shell
|
||||
uv venv
|
||||
source .venv/bin/activate
|
||||
|
||||
# installation
|
||||
poetry install
|
||||
uv pip install -r pyproject.toml -e . --all-extras
|
||||
|
||||
```
|
||||
|
||||
## 🚀 Quickstart
|
||||
|
||||
@@ -59,7 +59,7 @@ document.addEventListener("DOMContentLoaded", function () {
|
||||
<div
|
||||
class="author-container"
|
||||
data-login="${authorData.login}-${elementIndex}"
|
||||
style="margin-left: ${marginLeft}; z-index: ${zIndex};"
|
||||
style="margin-left: ${marginLeft};"
|
||||
>
|
||||
<a
|
||||
href="https://github.com/${authorData.login}"
|
||||
@@ -90,14 +90,17 @@ document.addEventListener("DOMContentLoaded", function () {
|
||||
).join(', ');
|
||||
|
||||
let authorsHTML = `
|
||||
<div class="authors">
|
||||
<div class="authors" style="margin: 0;">
|
||||
${authorAvatarsHTML}
|
||||
<div class="author-names">${authorNamesHTML}</div>
|
||||
</div>
|
||||
`;
|
||||
|
||||
element.innerText = `
|
||||
<div style="flex-direction: column; height: 100%; display: flex;
|
||||
<div style="
|
||||
display: grid !important;
|
||||
grid-template-rows: auto;
|
||||
height: 100%;
|
||||
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};">
|
||||
@@ -105,13 +108,14 @@ document.addEventListener("DOMContentLoaded", function () {
|
||||
</span>
|
||||
</div>
|
||||
${authorsHTML}
|
||||
<div style="font-size: 12px; color: ${theme.color}; display: flex; flex: 0; justify-content: space-between">
|
||||
<div style="font-size: 12px; color: ${theme.color}; display: grid; grid-template-columns: auto 3fr; justify-content: space-between; gap: 1rem;">
|
||||
<div style="display: flex; align-items: center;">
|
||||
<img src="/assets/supervision-lenny.png" aria-label="stars" width="20" height="20" role="img" />
|
||||
|
||||
<span style="margin-left: 4px">${version}</span>
|
||||
</div>
|
||||
<div style="display: flex; align-items: center; flex-wrap: wrap">
|
||||
<div style="display: flex; align-items: center; flex-wrap: wrap; align-content: right;
|
||||
gap: 0.1rem;">
|
||||
${labelHTML}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
window.MathJax = {
|
||||
tex: {
|
||||
inlineMath: [["\\(", "\\)"]],
|
||||
displayMath: [["\\[", "\\]"]],
|
||||
processEscapes: true,
|
||||
processEnvironments: true
|
||||
},
|
||||
options: {
|
||||
ignoreHtmlClass: ".*|",
|
||||
processHtmlClass: "arithmatex"
|
||||
}
|
||||
};
|
||||
|
||||
document$.subscribe(() => {
|
||||
MathJax.startup.output.clearCache()
|
||||
MathJax.typesetClear()
|
||||
MathJax.texReset()
|
||||
MathJax.typesetPromise()
|
||||
})
|
||||
@@ -0,0 +1,197 @@
|
||||
/**
|
||||
* Custom copy handler for Python console (pycon) code blocks.
|
||||
* Strips >>> and ... prompts when copying code examples.
|
||||
*/
|
||||
document.addEventListener("DOMContentLoaded", function () {
|
||||
const COPY_BUTTON_SELECTOR = ".md-clipboard, .md-code__button";
|
||||
|
||||
function handleCopyButtonClick(event) {
|
||||
const copyButton = event.target.closest(COPY_BUTTON_SELECTOR);
|
||||
if (!copyButton) return;
|
||||
|
||||
const codeBlock = findCodeBlockForCopyButton(copyButton);
|
||||
if (!codeBlock) return;
|
||||
|
||||
const rawText = codeBlock.textContent || "";
|
||||
if (!shouldStripPrompts(codeBlock, rawText)) return;
|
||||
|
||||
const strippedText = stripPythonPrompts(rawText);
|
||||
primeClipboardButton(copyButton, strippedText);
|
||||
}
|
||||
|
||||
function handleCopyButtonPointerDown(event) {
|
||||
const copyButton = event.target.closest(COPY_BUTTON_SELECTOR);
|
||||
if (!copyButton) return;
|
||||
|
||||
const codeBlock = findCodeBlockForCopyButton(copyButton);
|
||||
if (!codeBlock) return;
|
||||
|
||||
const rawText = codeBlock.textContent || "";
|
||||
if (!shouldStripPrompts(codeBlock, rawText)) return;
|
||||
|
||||
const strippedText = stripPythonPrompts(rawText);
|
||||
primeClipboardButton(copyButton, strippedText);
|
||||
}
|
||||
|
||||
function handleSelectionCopy(event) {
|
||||
const selection = window.getSelection();
|
||||
if (!selection || selection.rangeCount === 0) return;
|
||||
|
||||
const range = selection.getRangeAt(0);
|
||||
const anchorNode = range.commonAncestorContainer;
|
||||
const codeBlock =
|
||||
anchorNode.nodeType === Node.ELEMENT_NODE
|
||||
? anchorNode.closest("code")
|
||||
: anchorNode.parentElement?.closest("code");
|
||||
|
||||
if (!codeBlock) return;
|
||||
|
||||
const rawText = selection.toString();
|
||||
if (!shouldStripPrompts(codeBlock, rawText)) return;
|
||||
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
|
||||
const strippedText = stripPythonPrompts(rawText);
|
||||
event.clipboardData?.setData("text/plain", strippedText);
|
||||
}
|
||||
|
||||
function bindCopyButtons(root) {
|
||||
root
|
||||
.querySelectorAll(COPY_BUTTON_SELECTOR)
|
||||
.forEach((button) => {
|
||||
button.removeEventListener("click", handleCopyButtonClick, true);
|
||||
button.addEventListener("click", handleCopyButtonClick, true);
|
||||
button.removeEventListener(
|
||||
"pointerdown",
|
||||
handleCopyButtonPointerDown,
|
||||
true
|
||||
);
|
||||
button.addEventListener(
|
||||
"pointerdown",
|
||||
handleCopyButtonPointerDown,
|
||||
true
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
function observeDynamicCopyButtons() {
|
||||
const observer = new MutationObserver((mutations) => {
|
||||
for (const mutation of mutations) {
|
||||
if (mutation.type !== "childList") continue;
|
||||
mutation.addedNodes.forEach((node) => {
|
||||
if (node.nodeType !== Node.ELEMENT_NODE) return;
|
||||
if (node.matches?.(COPY_BUTTON_SELECTOR)) {
|
||||
bindCopyButtons(node.parentElement || document);
|
||||
return;
|
||||
}
|
||||
if (node.querySelectorAll) {
|
||||
const hasButtons = node.querySelectorAll(COPY_BUTTON_SELECTOR);
|
||||
if (hasButtons.length > 0) {
|
||||
bindCopyButtons(node);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
observer.observe(document.body, { childList: true, subtree: true });
|
||||
}
|
||||
|
||||
document.addEventListener("click", handleCopyButtonClick, true);
|
||||
document.addEventListener("pointerdown", handleCopyButtonPointerDown, true);
|
||||
document.addEventListener("copy", handleSelectionCopy, true);
|
||||
bindCopyButtons(document);
|
||||
observeDynamicCopyButtons();
|
||||
});
|
||||
|
||||
function primeClipboardButton(copyButton, strippedText) {
|
||||
copyButton.setAttribute("data-clipboard-text", strippedText);
|
||||
copyButton.removeAttribute("data-clipboard-target");
|
||||
copyButton.setAttribute("data-md-clipboard", "true");
|
||||
}
|
||||
|
||||
function shouldStripPrompts(codeBlock, rawText) {
|
||||
const hasReplPrompts = /(^|\n)[ \t]*(>>>|\.\.\.)/.test(rawText);
|
||||
return (
|
||||
hasReplPrompts ||
|
||||
codeBlock.classList.contains("language-pycon") ||
|
||||
codeBlock.closest("pre")?.classList.contains("pycon") ||
|
||||
codeBlock.closest(".pycon") !== null ||
|
||||
codeBlock.closest(".highlight")?.classList.contains("pycon")
|
||||
);
|
||||
}
|
||||
|
||||
function findCodeBlockForCopyButton(copyButton) {
|
||||
const targetSelector = copyButton.getAttribute("data-clipboard-target");
|
||||
if (targetSelector) {
|
||||
const target = document.querySelector(targetSelector);
|
||||
const targetCode = target?.querySelector?.("code") || target;
|
||||
if (targetCode?.tagName?.toLowerCase() === "code") {
|
||||
return targetCode;
|
||||
}
|
||||
}
|
||||
return (
|
||||
copyButton.closest("pre")?.querySelector("code") ||
|
||||
copyButton.parentElement?.querySelector("pre code") ||
|
||||
copyButton
|
||||
.closest(".highlight, .codehilite, .md-typeset__scrollwrap, .md-typeset")
|
||||
?.querySelector("pre code") ||
|
||||
copyButton
|
||||
.closest(".highlight, .codehilite, .md-typeset__scrollwrap, .md-typeset")
|
||||
?.querySelector("code")
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Strips Python REPL prompts (>>> and ...) from code text.
|
||||
* Also removes output lines (lines that don't start with >>> or ...).
|
||||
*
|
||||
* NOTE: This is a best-effort parser. It preserves unprompted lines inside
|
||||
* triple-quoted strings, but it does not fully model Python's tokenizer.
|
||||
*/
|
||||
function stripPythonPrompts(text) {
|
||||
const lines = text.split("\n");
|
||||
const codeLines = [];
|
||||
let inTripleQuotedString = false;
|
||||
|
||||
function toggleTripleQuoteState(sourceLine) {
|
||||
const tripleQuotePattern = /("""|''')/g;
|
||||
const matches = sourceLine.match(tripleQuotePattern);
|
||||
if (!matches) return;
|
||||
if (matches.length % 2 === 1) {
|
||||
inTripleQuotedString = !inTripleQuotedString;
|
||||
}
|
||||
}
|
||||
|
||||
for (const line of lines) {
|
||||
const trimmedLine = line.trimEnd();
|
||||
// Primary prompt: ">>> "
|
||||
if (trimmedLine.startsWith(">>> ")) {
|
||||
const stripped = trimmedLine.slice(4);
|
||||
codeLines.push(stripped);
|
||||
toggleTripleQuoteState(stripped);
|
||||
}
|
||||
// Continuation prompt: "... "
|
||||
else if (trimmedLine.startsWith("... ")) {
|
||||
const stripped = trimmedLine.slice(4);
|
||||
codeLines.push(stripped);
|
||||
toggleTripleQuoteState(stripped);
|
||||
}
|
||||
// Handle prompts without space after (edge case)
|
||||
else if (trimmedLine === ">>>") {
|
||||
codeLines.push("");
|
||||
}
|
||||
else if (trimmedLine === "...") {
|
||||
codeLines.push("");
|
||||
}
|
||||
else if (inTripleQuotedString) {
|
||||
codeLines.push(trimmedLine);
|
||||
toggleTripleQuoteState(trimmedLine);
|
||||
}
|
||||
// Skip output lines (lines that don't start with prompts)
|
||||
// This intentionally excludes output like "1.0" from the copied text
|
||||
}
|
||||
|
||||
return codeLines.join("\n").trim();
|
||||
}
|
||||
@@ -0,0 +1,4 @@
|
||||
!function(){var i="analytics",analytics=window[i]=window[i]||[];if(!analytics.initialize)if(analytics.invoked)window.console&&console.error&&console.error("Segment snippet included twice.");else{analytics.invoked=!0;analytics.methods=["trackSubmit","trackClick","trackLink","trackForm","pageview","identify","reset","group","track","ready","alias","debug","page","screen","once","off","on","addSourceMiddleware","addIntegrationMiddleware","setAnonymousId","addDestinationMiddleware","register"];analytics.factory=function(e){return function(){if(window[i].initialized)return window[i][e].apply(window[i],arguments);var n=Array.prototype.slice.call(arguments);if(["track","screen","alias","group","page","identify"].indexOf(e)>-1){var c=document.querySelector("link[rel='canonical']");n.push({__t:"bpc",c:c&&c.getAttribute("href")||void 0,p:location.pathname,u:location.href,s:location.search,t:document.title,r:document.referrer})}n.unshift(e);analytics.push(n);return analytics}};for(var n=0;n<analytics.methods.length;n++){var key=analytics.methods[n];analytics[key]=analytics.factory(key)}analytics.load=function(key,n){var t=document.createElement("script");t.type="text/javascript";t.async=!0;t.setAttribute("data-global-segment-analytics-key",i);t.src="https://cdn.segment.com/analytics.js/v1/" + key + "/analytics.min.js";var r=document.getElementsByTagName("script")[0];r.parentNode.insertBefore(t,r);analytics._loadOptions=n};analytics._writeKey="rMvrPeZBJYyOPJSGCNhMlnTJb8VhFiWU";;analytics.SNIPPET_VERSION="5.2.0";
|
||||
analytics.load("eohFog7VZiAhGJGEr5Sh7BM1mFKmUvDC");
|
||||
document$.subscribe(analytics.page);
|
||||
}}();
|
||||
+12
-13
@@ -1,6 +1,5 @@
|
||||
---
|
||||
comments: true
|
||||
status: new
|
||||
---
|
||||
|
||||
# Annotators
|
||||
@@ -15,11 +14,11 @@ status: new
|
||||
|
||||
vertex_annotator = sv.VertexAnnotator(
|
||||
color=sv.Color.GREEN,
|
||||
radius=10
|
||||
radius=10,
|
||||
)
|
||||
annotated_frame = vertex_annotator.annotate(
|
||||
scene=image.copy(),
|
||||
key_points=key_points
|
||||
key_points=key_points,
|
||||
)
|
||||
```
|
||||
|
||||
@@ -39,11 +38,11 @@ status: new
|
||||
|
||||
edge_annotator = sv.EdgeAnnotator(
|
||||
color=sv.Color.GREEN,
|
||||
thickness=5
|
||||
thickness=5,
|
||||
)
|
||||
annotated_frame = edge_annotator.annotate(
|
||||
scene=image.copy(),
|
||||
key_points=key_points
|
||||
key_points=key_points,
|
||||
)
|
||||
```
|
||||
|
||||
@@ -64,11 +63,11 @@ status: new
|
||||
vertex_label_annotator = sv.VertexLabelAnnotator(
|
||||
color=sv.Color.GREEN,
|
||||
text_color=sv.Color.BLACK,
|
||||
border_radius=5
|
||||
border_radius=5,
|
||||
)
|
||||
annotated_frame = vertex_label_annotator.annotate(
|
||||
scene=image.copy(),
|
||||
key_points=key_points
|
||||
key_points=key_points,
|
||||
)
|
||||
```
|
||||
|
||||
@@ -79,19 +78,19 @@ status: new
|
||||
</div>
|
||||
|
||||
<div class="md-typeset">
|
||||
<h2><a href="#supervision.keypoint.annotators.VertexAnnotator">VertexAnnotator</a></h2>
|
||||
<h2><a href="#supervision.key_points.annotators.VertexAnnotator">VertexAnnotator</a></h2>
|
||||
</div>
|
||||
|
||||
:::supervision.keypoint.annotators.VertexAnnotator
|
||||
:::supervision.key_points.annotators.VertexAnnotator
|
||||
|
||||
<div class="md-typeset">
|
||||
<h2><a href="#supervision.keypoint.annotators.EdgeAnnotator">EdgeAnnotator</a></h2>
|
||||
<h2><a href="#supervision.key_points.annotators.EdgeAnnotator">EdgeAnnotator</a></h2>
|
||||
</div>
|
||||
|
||||
:::supervision.keypoint.annotators.EdgeAnnotator
|
||||
:::supervision.key_points.annotators.EdgeAnnotator
|
||||
|
||||
<div class="md-typeset">
|
||||
<h2><a href="#supervision.keypoint.annotators.VertexLabelAnnotator">VertexLabelAnnotator</a></h2>
|
||||
<h2><a href="#supervision.key_points.annotators.VertexLabelAnnotator">VertexLabelAnnotator</a></h2>
|
||||
</div>
|
||||
|
||||
:::supervision.keypoint.annotators.VertexLabelAnnotator
|
||||
:::supervision.key_points.annotators.VertexLabelAnnotator
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
---
|
||||
comments: true
|
||||
status: new
|
||||
---
|
||||
|
||||
# Keypoint Detection
|
||||
|
||||
:::supervision.keypoint.core.KeyPoints
|
||||
:::supervision.key_points.core.KeyPoints
|
||||
|
||||
@@ -0,0 +1,192 @@
|
||||
# supervision
|
||||
|
||||
> Large-context AI crawler summary for Supervision documentation.
|
||||
|
||||
Supervision is an open-source Python library by Roboflow for computer vision workflows. It provides a model-agnostic `Detections` class and composable tools for object detection, instance segmentation, keypoint detection, annotation, tracking, zone counting, dataset conversion, and model evaluation.
|
||||
|
||||
Supervision is MIT licensed, published on PyPI, developed on GitHub, and used by researchers and practitioners in production computer vision systems. The library includes converters for supported outputs from Ultralytics, Roboflow Inference, Hugging Face Transformers, SAM, Detectron2, MMDetection, YOLO-NAS, PaddleDet, NCNN, Azure AI Vision, and VLM parsers.
|
||||
|
||||
## Primary Links
|
||||
|
||||
- Latest stable docs: https://supervision.roboflow.com/latest/
|
||||
- Development docs: https://supervision.roboflow.com/develop/
|
||||
- Source code: https://github.com/roboflow/supervision
|
||||
- PyPI package: https://pypi.org/project/supervision/
|
||||
- Changelog: https://supervision.roboflow.com/latest/changelog/
|
||||
- Sitemap: https://supervision.roboflow.com/sitemap.xml
|
||||
- Standard LLM summary: https://supervision.roboflow.com/llms.txt
|
||||
- Full LLM summary: https://supervision.roboflow.com/llms.full.txt
|
||||
|
||||
## AI Access
|
||||
|
||||
The documentation is static HTML and is open for AI crawler consumption. `robots.txt` explicitly allows general crawlers plus GPTBot, ClaudeBot, PerplexityBot, Bytespider, CCBot, GoogleOther, and Applebot.
|
||||
|
||||
## Install
|
||||
|
||||
```bash
|
||||
pip install supervision
|
||||
```
|
||||
|
||||
Optional extras:
|
||||
|
||||
```bash
|
||||
pip install "supervision[metrics]"
|
||||
```
|
||||
|
||||
Sample asset utilities are included in the base package under `supervision.assets`.
|
||||
|
||||
## Core Concepts
|
||||
|
||||
### `sv.Detections`
|
||||
|
||||
`sv.Detections` is the central data structure in Supervision. It stores bounding boxes, segmentation masks, confidence scores, class IDs, tracker IDs, and arbitrary per-detection metadata in a `data` dictionary. It supports NumPy-style indexing for filtering by confidence, class, area, and spatial constraints.
|
||||
|
||||
Most connectors, annotators, trackers, dataset tools, and metrics either accept or return `Detections`, which makes it possible to change the upstream model while keeping downstream processing code stable.
|
||||
|
||||
### Model Connectors
|
||||
|
||||
Supervision normalizes outputs from multiple computer vision frameworks into the same `Detections` API. Common constructors include:
|
||||
|
||||
- `sv.Detections.from_ultralytics(...)`
|
||||
- `sv.Detections.from_inference(...)`
|
||||
- `sv.Detections.from_transformers(...)`
|
||||
- `sv.Detections.from_vlm(...)`
|
||||
- `sv.Detections.from_sam(...)`
|
||||
- `sv.Detections.from_detectron2(...)`
|
||||
- `sv.Detections.from_mmdetection(...)`
|
||||
|
||||
### Annotation
|
||||
|
||||
Supervision includes annotators for drawing boxes, masks, labels, traces, zones, vertices, edges, and other overlays on images and video frames. Common annotators include:
|
||||
|
||||
- `sv.BoxAnnotator`
|
||||
- `sv.MaskAnnotator`
|
||||
- `sv.LabelAnnotator`
|
||||
- `sv.TraceAnnotator`
|
||||
- `sv.PolygonZoneAnnotator`
|
||||
- `sv.LineZoneAnnotator`
|
||||
|
||||
### Tracking
|
||||
|
||||
The built-in `sv.ByteTrack` wrapper assigns persistent IDs across video frames through `update_with_detections()`. The docs also note the migration path toward `ByteTrackTracker` from the external `trackers` package. Tracked detections can be passed to label, trace, zone, and line-counting annotators.
|
||||
|
||||
### Zones and Counting
|
||||
|
||||
`sv.PolygonZone` checks whether detections are inside an arbitrary polygon. `sv.LineZone` counts line crossings and requires `detections.tracker_id` so objects can be matched across frames. These tools are typically used with video callbacks and annotators to build traffic, occupancy, queue, and throughput analytics.
|
||||
|
||||
### Datasets
|
||||
|
||||
`sv.DetectionDataset` loads, merges, splits, and converts object detection datasets. Supported formats include YOLO, COCO JSON, and Pascal VOC. `sv.ClassificationDataset` supports folder-structured classification datasets.
|
||||
|
||||
### Metrics
|
||||
|
||||
Supervision includes detection metrics including mean average precision, mean average recall, precision, recall, F1 score, and confusion matrices. The current mAP workflow uses `supervision.metrics.mean_average_precision.MeanAveragePrecision` with `update(...)` and `compute()`.
|
||||
|
||||
## How-To Guides
|
||||
|
||||
- Detect and annotate: https://supervision.roboflow.com/latest/how_to/detect_and_annotate/
|
||||
- Track objects: https://supervision.roboflow.com/latest/how_to/track_objects/
|
||||
- Detect small objects: https://supervision.roboflow.com/latest/how_to/detect_small_objects/
|
||||
- Filter detections: https://supervision.roboflow.com/latest/how_to/filter_detections/
|
||||
- Save detections: https://supervision.roboflow.com/latest/how_to/save_detections/
|
||||
- Count in zone: https://supervision.roboflow.com/latest/how_to/count_in_zone/
|
||||
- Benchmark a model: https://supervision.roboflow.com/latest/how_to/benchmark_a_model/
|
||||
- Process datasets: https://supervision.roboflow.com/latest/how_to/process_datasets/
|
||||
|
||||
## Reference Documentation
|
||||
|
||||
- Detections: https://supervision.roboflow.com/latest/detection/core/
|
||||
- Detection annotators: https://supervision.roboflow.com/latest/detection/annotators/
|
||||
- Compact masks: https://supervision.roboflow.com/latest/detection/compact_mask/
|
||||
- Detection converters: https://supervision.roboflow.com/latest/detection/utils/converters/
|
||||
- IoU and NMS: https://supervision.roboflow.com/latest/detection/utils/iou_and_nms/
|
||||
- Boxes: https://supervision.roboflow.com/latest/detection/utils/boxes/
|
||||
- Masks: https://supervision.roboflow.com/latest/detection/utils/masks/
|
||||
- Polygons: https://supervision.roboflow.com/latest/detection/utils/polygons/
|
||||
- Vision-language model helpers: https://supervision.roboflow.com/latest/detection/utils/vlms/
|
||||
- Keypoint core: https://supervision.roboflow.com/latest/keypoint/core/
|
||||
- Keypoint annotators: https://supervision.roboflow.com/latest/keypoint/annotators/
|
||||
- Classification core: https://supervision.roboflow.com/latest/classification/core/
|
||||
- Trackers: https://supervision.roboflow.com/latest/trackers/
|
||||
- Dataset core: https://supervision.roboflow.com/latest/datasets/core/
|
||||
- Mean average precision: https://supervision.roboflow.com/latest/metrics/mean_average_precision/
|
||||
- Mean average recall: https://supervision.roboflow.com/latest/metrics/mean_average_recall/
|
||||
- Precision: https://supervision.roboflow.com/latest/metrics/precision/
|
||||
- Recall: https://supervision.roboflow.com/latest/metrics/recall/
|
||||
- F1 score: https://supervision.roboflow.com/latest/metrics/f1_score/
|
||||
- Common metric values: https://supervision.roboflow.com/latest/metrics/common_values/
|
||||
- Line zone: https://supervision.roboflow.com/latest/detection/tools/line_zone/
|
||||
- Polygon zone: https://supervision.roboflow.com/latest/detection/tools/polygon_zone/
|
||||
- Inference slicer: https://supervision.roboflow.com/latest/detection/tools/inference_slicer/
|
||||
- Detection smoother: https://supervision.roboflow.com/latest/detection/tools/smoother/
|
||||
- Detection export sinks: https://supervision.roboflow.com/latest/detection/tools/save_detections/
|
||||
- Video utilities: https://supervision.roboflow.com/latest/utils/video/
|
||||
- Image utilities: https://supervision.roboflow.com/latest/utils/image/
|
||||
- Iterable utilities: https://supervision.roboflow.com/latest/utils/iterables/
|
||||
- Notebook utilities: https://supervision.roboflow.com/latest/utils/notebook/
|
||||
- File utilities: https://supervision.roboflow.com/latest/utils/file/
|
||||
- Draw utilities: https://supervision.roboflow.com/latest/utils/draw/
|
||||
- Geometry utilities: https://supervision.roboflow.com/latest/utils/geometry/
|
||||
- Assets: https://supervision.roboflow.com/latest/assets/
|
||||
|
||||
## Cookbooks
|
||||
|
||||
- Supervision quickstart: https://supervision.roboflow.com/latest/notebooks/quickstart/
|
||||
- Count objects crossing the line: https://supervision.roboflow.com/latest/notebooks/count-objects-crossing-the-line/
|
||||
- Object tracking: https://supervision.roboflow.com/latest/notebooks/object-tracking/
|
||||
- Small object detection with SAHI: https://supervision.roboflow.com/latest/notebooks/small-object-detection-with-sahi/
|
||||
- Zero-shot object detection with YOLO-World: https://supervision.roboflow.com/latest/notebooks/zero-shot-object-detection-with-yolo-world/
|
||||
- Save detections to CSV: https://supervision.roboflow.com/latest/notebooks/serialise-detections-to-csv/
|
||||
- Save detections to JSON: https://supervision.roboflow.com/latest/notebooks/serialise-detections-to-json/
|
||||
- Occupancy analytics: https://supervision.roboflow.com/latest/notebooks/occupancy_analytics/
|
||||
- Annotate video with detections: https://supervision.roboflow.com/latest/notebooks/annotate-video-with-detections/
|
||||
|
||||
## Trust and Contact Pages
|
||||
|
||||
- About: https://supervision.roboflow.com/latest/about/
|
||||
- Contact: https://supervision.roboflow.com/latest/contact/
|
||||
- FAQ: https://supervision.roboflow.com/latest/faq/
|
||||
- License: https://github.com/roboflow/supervision/blob/develop/LICENSE.md
|
||||
- Issues: https://github.com/roboflow/supervision/issues
|
||||
- Community: https://discord.gg/GbfgXGJ8Bk
|
||||
|
||||
## Frequently Asked Questions
|
||||
|
||||
### What is Supervision?
|
||||
|
||||
Supervision is an open-source Python library by Roboflow for computer vision workflows. It provides a unified `Detections` class with converters for supported detection, segmentation, and VLM outputs.
|
||||
|
||||
### Is Supervision tied to one model provider?
|
||||
|
||||
No. Supervision is model agnostic. It is designed to normalize model outputs into a common API so downstream annotation, filtering, tracking, metrics, and dataset code can be reused.
|
||||
|
||||
### What dataset formats are supported?
|
||||
|
||||
For object detection datasets, Supervision supports YOLO, COCO JSON, and Pascal VOC import and export. For classification datasets, it supports folder-structure import and export.
|
||||
|
||||
### How do I detect small objects?
|
||||
|
||||
Use `sv.InferenceSlicer` to split large images into overlapping tiles, run inference on each tile, and merge the resulting detections with non-maximum suppression or non-maximum merge.
|
||||
|
||||
### How do I count objects crossing a line?
|
||||
|
||||
Run a tracker first to assign `detections.tracker_id`, then use `sv.LineZone.trigger(detections)` to calculate crossing events. Use `sv.LineZoneAnnotator` for visualization.
|
||||
|
||||
### How do I benchmark a model?
|
||||
|
||||
Load predictions and ground truth as `Detections`, update a `MeanAveragePrecision` metric object, and call `compute()`. Use `sv.ConfusionMatrix` when class-level confusion analysis is needed.
|
||||
|
||||
## Citation
|
||||
|
||||
```bibtex
|
||||
@software{supervision,
|
||||
author = {Roboflow},
|
||||
title = {Supervision: Computer Vision Toolkit},
|
||||
url = {https://github.com/roboflow/supervision},
|
||||
year = {2023}
|
||||
}
|
||||
```
|
||||
|
||||
## Versioning
|
||||
|
||||
`/develop/` is built from the `develop` branch. `/latest/` is built from the `release/latest` branch. Published releases build tag-only documentation paths and do not move `/latest/`.
|
||||
@@ -0,0 +1,188 @@
|
||||
# supervision
|
||||
|
||||
> Open-source Python library for computer vision — annotate, track, count, filter, and convert.
|
||||
|
||||
Supervision is a Python library by Roboflow that provides a model-agnostic `Detections` class and composable tools for object detection and segmentation workflows. It includes converters for supported outputs from Ultralytics, Roboflow Inference, Hugging Face Transformers, SAM, Detectron2, MMDetection, YOLO-NAS, PaddleDet, NCNN, Azure AI Vision, and VLM parsers.
|
||||
|
||||
Supervision is MIT licensed, published on PyPI, and developed in public on GitHub.
|
||||
|
||||
## AI Access
|
||||
|
||||
The documentation is static HTML and open for AI consumption. `robots.txt` explicitly allows general crawlers plus selected AI crawlers.
|
||||
|
||||
- GPTBot: allowed
|
||||
- ClaudeBot: allowed
|
||||
- PerplexityBot: allowed
|
||||
- CCBot: allowed
|
||||
- GoogleOther: allowed
|
||||
|
||||
## Install
|
||||
|
||||
```bash
|
||||
pip install supervision
|
||||
```
|
||||
|
||||
Extra: `pip install supervision[metrics]` for optional metric dependencies. Sample asset utilities are included in the base package under `supervision.assets`.
|
||||
|
||||
## Links
|
||||
|
||||
- GitHub: https://github.com/roboflow/supervision
|
||||
- PyPI: https://pypi.org/project/supervision
|
||||
- Docs (latest stable): https://supervision.roboflow.com/latest/
|
||||
- Docs (develop): https://supervision.roboflow.com/develop/
|
||||
- Changelog: https://supervision.roboflow.com/latest/changelog/
|
||||
- Sitemap: https://supervision.roboflow.com/sitemap.xml
|
||||
|
||||
## Key APIs
|
||||
|
||||
### sv.Detections
|
||||
|
||||
Core data structure for bounding boxes, masks, confidence scores, class IDs, tracker IDs, and arbitrary per-detection metadata stored in a `data` dict. The lingua franca of the entire library — every connector, annotator, and tracker accepts or returns `Detections`. Supports NumPy-style boolean indexing for filtering by class, confidence, area, and spatial regions.
|
||||
|
||||
### sv.BoxAnnotator, sv.MaskAnnotator, sv.LabelAnnotator
|
||||
|
||||
Draw bounding boxes, segmentation masks, and text labels on images. Annotators expose `annotate(scene=..., detections=...)`; pass an input image and a `Detections` object to get the annotated output. `LabelAnnotator` can use explicit `labels` or fall back to `detections["class_name"]`, class IDs, then detection indices. Colors can be assigned by class or manually specified.
|
||||
|
||||
### sv.ByteTrack
|
||||
|
||||
Object tracker wrapper that assigns persistent IDs across video frames. The built-in `sv.ByteTrack` accepts `Detections` via `update_with_detections()`, but it is deprecated in favor of `ByteTrackTracker` from the external `trackers` package, where the method is named `update()`. Use tracked `Detections` with `sv.TraceAnnotator` to visualize trajectories.
|
||||
|
||||
### sv.PolygonZone and sv.LineZone
|
||||
|
||||
Zone-based counting. `PolygonZone.trigger(detections)` returns a boolean mask for detections currently inside an arbitrary polygon. `LineZone.trigger(detections)` returns `(crossed_in, crossed_out)` arrays for line crossings and requires `detections.tracker_id` so objects can be matched across frames. Both are commonly paired with zone annotators for visualization.
|
||||
|
||||
### sv.DetectionDataset and sv.ClassificationDataset
|
||||
|
||||
For detection datasets, load, merge, split, and convert between YOLO, COCO JSON, and Pascal VOC formats. Classification datasets use folder-structure import and export via `ClassificationDataset.from_folder_structure()` and `as_folder_structure()`.
|
||||
|
||||
### sv.InferenceSlicer
|
||||
|
||||
SAHI-style inference slicing: split high-resolution images into overlapping tiles, run detection on each tile, merge results with non-maximum suppression or non-maximum merge. Configure tile overlap in pixels with `overlap_wh`.
|
||||
|
||||
### supervision.metrics.MeanAveragePrecision and sv.ConfusionMatrix
|
||||
|
||||
Benchmarking tools. For mAP@0.5:0.95, use `supervision.metrics.MeanAveragePrecision` with `update()` and `compute()` rather than the deprecated top-level `sv.MeanAveragePrecision.from_detections()`. `ConfusionMatrix.from_detections(predictions=predictions, targets=targets, classes=classes)` generates a confusion matrix for detection results.
|
||||
|
||||
### sv.CSVSink and sv.JSONSink
|
||||
|
||||
Export detection results to structured files. Use `CSVSink` and `JSONSink` as context managers, call `sink.append(detections, custom_data=...)`, and they write one row/object per detection with box coordinates, confidence, class ID, tracker ID, and data fields.
|
||||
|
||||
## How-To Guides
|
||||
|
||||
- Detect and annotate: https://supervision.roboflow.com/latest/how_to/detect_and_annotate/
|
||||
- Track objects: https://supervision.roboflow.com/latest/how_to/track_objects/
|
||||
- Detect small objects: https://supervision.roboflow.com/latest/how_to/detect_small_objects/
|
||||
- Filter detections: https://supervision.roboflow.com/latest/how_to/filter_detections/
|
||||
- Save detections: https://supervision.roboflow.com/latest/how_to/save_detections/
|
||||
- Count in zone: https://supervision.roboflow.com/latest/how_to/count_in_zone/
|
||||
- Benchmark a model: https://supervision.roboflow.com/latest/how_to/benchmark_a_model/
|
||||
- Process datasets: https://supervision.roboflow.com/latest/how_to/process_datasets/
|
||||
|
||||
## Reference Documentation
|
||||
|
||||
- Detections (detection/core): https://supervision.roboflow.com/latest/detection/core/
|
||||
- Annotators (detection/annotators): https://supervision.roboflow.com/latest/detection/annotators/
|
||||
- CompactMask (detection/compact_mask): https://supervision.roboflow.com/latest/detection/compact_mask/
|
||||
- Format Converters (detection/utils/converters): https://supervision.roboflow.com/latest/detection/utils/converters/
|
||||
- IoU and NMS (detection/utils/iou_and_nms): https://supervision.roboflow.com/latest/detection/utils/iou_and_nms/
|
||||
- Boxes (detection/utils/boxes): https://supervision.roboflow.com/latest/detection/utils/boxes/
|
||||
- Masks (detection/utils/masks): https://supervision.roboflow.com/latest/detection/utils/masks/
|
||||
- Polygons (detection/utils/polygons): https://supervision.roboflow.com/latest/detection/utils/polygons/
|
||||
- VLMs (detection/utils/vlms): https://supervision.roboflow.com/latest/detection/utils/vlms/
|
||||
- Keypoint Core (keypoint/core): https://supervision.roboflow.com/latest/keypoint/core/
|
||||
- Keypoint Annotators (keypoint/annotators): https://supervision.roboflow.com/latest/keypoint/annotators/
|
||||
- Classification Core (classification/core): https://supervision.roboflow.com/latest/classification/core/
|
||||
- ByteTrack Tracker (trackers): https://supervision.roboflow.com/latest/trackers/
|
||||
- Datasets Core (datasets/core): https://supervision.roboflow.com/latest/datasets/core/
|
||||
- mAP (metrics/mean_average_precision): https://supervision.roboflow.com/latest/metrics/mean_average_precision/
|
||||
- mAR (metrics/mean_average_recall): https://supervision.roboflow.com/latest/metrics/mean_average_recall/
|
||||
- Precision (metrics/precision): https://supervision.roboflow.com/latest/metrics/precision/
|
||||
- Recall (metrics/recall): https://supervision.roboflow.com/latest/metrics/recall/
|
||||
- F1 Score (metrics/f1_score): https://supervision.roboflow.com/latest/metrics/f1_score/
|
||||
- Common Values (metrics/common_values): https://supervision.roboflow.com/latest/metrics/common_values/
|
||||
- Line Zone (detection/tools/line_zone): https://supervision.roboflow.com/latest/detection/tools/line_zone/
|
||||
- Polygon Zone (detection/tools/polygon_zone): https://supervision.roboflow.com/latest/detection/tools/polygon_zone/
|
||||
- Inference Slicer (detection/tools/inference_slicer): https://supervision.roboflow.com/latest/detection/tools/inference_slicer/
|
||||
- Detection Smoother (detection/tools/smoother): https://supervision.roboflow.com/latest/detection/tools/smoother/
|
||||
- Save Detections Tool (detection/tools/save_detections): https://supervision.roboflow.com/latest/detection/tools/save_detections/
|
||||
- Video Utils (utils/video): https://supervision.roboflow.com/latest/utils/video/
|
||||
- Image Utils (utils/image): https://supervision.roboflow.com/latest/utils/image/
|
||||
- Iterable Utils (utils/iterables): https://supervision.roboflow.com/latest/utils/iterables/
|
||||
- Notebook Utils (utils/notebook): https://supervision.roboflow.com/latest/utils/notebook/
|
||||
- File Utils (utils/file): https://supervision.roboflow.com/latest/utils/file/
|
||||
- Draw Utils (utils/draw): https://supervision.roboflow.com/latest/utils/draw/
|
||||
- Geometry (utils/geometry): https://supervision.roboflow.com/latest/utils/geometry/
|
||||
- Assets (assets): https://supervision.roboflow.com/latest/assets/
|
||||
|
||||
## Cookbooks
|
||||
|
||||
- Object tracking: https://supervision.roboflow.com/latest/cookbooks/#object-tracking
|
||||
- Count objects crossing line: https://supervision.roboflow.com/latest/cookbooks/#count-objects-crossing-the-line
|
||||
- Zero-shot object detection with YOLO-World: https://supervision.roboflow.com/latest/cookbooks/#zero-shot-object-detection-with-yolo-world
|
||||
- SAHI small object detection: https://supervision.roboflow.com/latest/cookbooks/#small-object-detection-with-sahi
|
||||
|
||||
## FAQ
|
||||
|
||||
### What is supervision?
|
||||
|
||||
Supervision is an open-source Python library by Roboflow for computer vision workflows. It provides a unified `Detections` class with converters for supported detection, segmentation, and VLM outputs, plus tools for annotation, tracking, zone counting, dataset management, and model benchmarking.
|
||||
|
||||
### How do I install supervision?
|
||||
|
||||
Install with `pip install supervision`. For optional metric dependencies use `pip install supervision[metrics]`. Sample asset utilities are included in the base package under `supervision.assets`. The current package metadata requires Python 3.9+.
|
||||
|
||||
### What can I do with supervision?
|
||||
|
||||
Annotate images and video with bounding boxes, masks, and labels; track objects across frames with persistent IDs; count detections inside polygon zones or line crossings; filter and query detection results; load, split, and convert detection datasets between YOLO, COCO, and Pascal VOC formats; manage classification datasets with folder structures; and benchmark model performance with mAP and confusion matrices.
|
||||
|
||||
### Is supervision free to use?
|
||||
|
||||
Yes. Supervision is free and open-source under the MIT license. Source code is at https://github.com/roboflow/supervision.
|
||||
|
||||
### Which object detection models work with supervision?
|
||||
|
||||
Supervision is model-agnostic and works with supported outputs from Ultralytics YOLO, Roboflow Inference, Hugging Face Transformers, SAM, Detectron2, MMDetection, YOLO-NAS, PaddleDet, NCNN, Azure AI Vision, and VLM parsers such as Florence-2, PaliGemma, Qwen VL, Gemini, DeepSeek VL 2, and Moondream. Keypoint outputs have separate converters, including MediaPipe.
|
||||
|
||||
### How do I benchmark a model with supervision?
|
||||
|
||||
Use `supervision.metrics.mean_average_precision.MeanAveragePrecision` for mAP — accumulate predictions and ground truth with `update(...)` then call `compute()`. For confusion matrices, use `sv.ConfusionMatrix.from_detections(predictions=predictions, targets=targets, classes=classes)`. See the Benchmark a Model how-to guide for a complete walkthrough.
|
||||
|
||||
### How do I track objects across video frames?
|
||||
|
||||
Use a tracker to assign persistent IDs. The built-in `sv.ByteTrack` wrapper accepts `Detections` with `update_with_detections()`, but it is deprecated in favor of `ByteTrackTracker` from the external `trackers` package. Combine tracked detections with `sv.TraceAnnotator` to visualize trajectories.
|
||||
|
||||
### What dataset formats does supervision support?
|
||||
|
||||
For detection datasets, supervision supports YOLO, COCO JSON, and Pascal VOC. Use `DetectionDataset.from_yolo()`, `from_coco()`, or `from_pascal_voc()` to load, and `as_yolo()`, `as_coco()`, or `as_pascal_voc()` to save. For classification datasets, use `ClassificationDataset.from_folder_structure()` and `as_folder_structure()`.
|
||||
|
||||
### How do I count objects in a zone?
|
||||
|
||||
Use `sv.PolygonZone` for arbitrary polygon zones. Use `sv.LineZone` for line-crossing counts after assigning tracker IDs, because `LineZone` needs `detections.tracker_id` to match objects across frames.
|
||||
|
||||
### How do I detect small objects with supervision?
|
||||
|
||||
Use `sv.InferenceSlicer` to split high-resolution images into overlapping tiles, run detection on each tile, and merge results with non-maximum suppression. Configure tile overlap in pixels with `overlap_wh`. See the Detect Small Objects how-to guide.
|
||||
|
||||
## Benchmarking
|
||||
|
||||
Supervision includes `supervision.metrics.MeanAveragePrecision` and `sv.ConfusionMatrix` for benchmarking object detection models. A curated [Model Leaderboard](https://leaderboard.roboflow.com/) compares YOLOv8, YOLOv11, and other models on standard datasets. The leaderboard repository is open source at https://github.com/roboflow/model-leaderboard.
|
||||
|
||||
## License
|
||||
|
||||
MIT — https://github.com/roboflow/supervision/blob/develop/LICENSE.md
|
||||
|
||||
## Citation
|
||||
|
||||
```bibtex
|
||||
@software{supervision,
|
||||
author = {Roboflow},
|
||||
title = {Supervision: Computer Vision Toolkit},
|
||||
url = {https://github.com/roboflow/supervision},
|
||||
year = {2023}
|
||||
}
|
||||
```
|
||||
|
||||
## Versioning
|
||||
|
||||
Stable release docs: https://supervision.roboflow.com/latest/
|
||||
Development branch: https://supervision.roboflow.com/develop/
|
||||
+179
@@ -0,0 +1,179 @@
|
||||
# supervision
|
||||
|
||||
> Open-source Python library for computer vision — annotate, track, count, filter, and convert.
|
||||
|
||||
Supervision is a Python library by Roboflow that provides a model-agnostic `Detections` class and composable tools for object detection and segmentation workflows. It includes converters for supported outputs from Ultralytics, Roboflow Inference, Hugging Face Transformers, SAM, Detectron2, MMDetection, YOLO-NAS, PaddleDet, NCNN, Azure AI Vision, and VLM parsers.
|
||||
|
||||
Supervision is MIT licensed, published on PyPI, and developed in public on GitHub.
|
||||
|
||||
## AI Access
|
||||
|
||||
The documentation is static HTML and open for AI consumption. `robots.txt` explicitly allows general crawlers plus selected AI crawlers.
|
||||
|
||||
- GPTBot: allowed
|
||||
- ClaudeBot: allowed
|
||||
- PerplexityBot: allowed
|
||||
- CCBot: allowed
|
||||
- GoogleOther: allowed
|
||||
|
||||
## Install
|
||||
|
||||
```
|
||||
pip install supervision
|
||||
```
|
||||
|
||||
Extra: `pip install supervision[metrics]` for optional metric dependencies. Sample asset utilities are included in the base package under `supervision.assets`.
|
||||
|
||||
## Links
|
||||
|
||||
- GitHub: https://github.com/roboflow/supervision
|
||||
- PyPI: https://pypi.org/project/supervision
|
||||
- Docs (latest stable): https://supervision.roboflow.com/latest/
|
||||
- Changelog: https://supervision.roboflow.com/latest/changelog/
|
||||
- Sitemap: https://supervision.roboflow.com/sitemap.xml
|
||||
|
||||
## Key APIs
|
||||
|
||||
### sv.Detections
|
||||
Core data structure for bounding boxes, masks, confidence scores, class IDs, tracker IDs, and arbitrary per-detection metadata stored in a `data` dict. The lingua franca of the entire library — every connector, annotator, and tracker accepts or returns `Detections`. Supports NumPy-style boolean indexing for filtering by class, confidence, area, and spatial regions.
|
||||
|
||||
### sv.BoxAnnotator, sv.MaskAnnotator, sv.LabelAnnotator
|
||||
Draw bounding boxes, segmentation masks, and text labels on images. Annotators expose `annotate(scene=..., detections=...)`; pass an input image and a `Detections` object to get the annotated output. `LabelAnnotator` can use explicit `labels` or fall back to `detections["class_name"]`, class IDs, then detection indices. Colors can be assigned by class or manually specified.
|
||||
|
||||
### sv.ByteTrack
|
||||
Object tracker wrapper that assigns persistent IDs across video frames. The built-in `sv.ByteTrack` accepts `Detections` via `update_with_detections()`, but it is deprecated in favor of `ByteTrackTracker` from the external `trackers` package, where the method is named `update()`. Use tracked `Detections` with `sv.TraceAnnotator` to visualize trajectories.
|
||||
|
||||
### sv.PolygonZone and sv.LineZone
|
||||
Zone-based counting. `PolygonZone.trigger(detections)` returns a boolean mask for detections currently inside an arbitrary polygon. `LineZone.trigger(detections)` returns `(crossed_in, crossed_out)` arrays for line crossings and requires `detections.tracker_id` so objects can be matched across frames. Both are commonly paired with zone annotators for visualization.
|
||||
|
||||
### sv.DetectionDataset and sv.ClassificationDataset
|
||||
For detection datasets, load, merge, split, and convert between YOLO, COCO JSON, and Pascal VOC formats. Classification datasets use folder-structure import and export via `ClassificationDataset.from_folder_structure()` and `as_folder_structure()`.
|
||||
|
||||
### sv.InferenceSlicer
|
||||
SAHI-style inference slicing: split high-resolution images into overlapping tiles, run detection on each tile, merge results with non-maximum suppression or non-maximum merge. Configure tile overlap in pixels with `overlap_wh`.
|
||||
|
||||
### supervision.metrics.MeanAveragePrecision and sv.ConfusionMatrix
|
||||
Benchmarking tools. For mAP@0.5:0.95, use `supervision.metrics.MeanAveragePrecision` with `update()` and `compute()` rather than the deprecated top-level `sv.MeanAveragePrecision.from_detections()`. `ConfusionMatrix.from_detections(predictions=predictions, targets=targets, classes=classes)` generates a confusion matrix for detection results.
|
||||
|
||||
### sv.CSVSink and sv.JSONSink
|
||||
Export detection results to structured files. Use `CSVSink` and `JSONSink` as context managers, call `sink.append(detections, custom_data=...)`, and they write one row/object per detection with box coordinates, confidence, class ID, tracker ID, and data fields.
|
||||
|
||||
## How-To Guides
|
||||
|
||||
- Detect and annotate: https://supervision.roboflow.com/latest/how_to/detect_and_annotate/
|
||||
- Track objects: https://supervision.roboflow.com/latest/how_to/track_objects/
|
||||
- Detect small objects: https://supervision.roboflow.com/latest/how_to/detect_small_objects/
|
||||
- Filter detections: https://supervision.roboflow.com/latest/how_to/filter_detections/
|
||||
- Save detections: https://supervision.roboflow.com/latest/how_to/save_detections/
|
||||
- Count in zone: https://supervision.roboflow.com/latest/how_to/count_in_zone/
|
||||
- Benchmark a model: https://supervision.roboflow.com/latest/how_to/benchmark_a_model/
|
||||
- Process datasets: https://supervision.roboflow.com/latest/how_to/process_datasets/
|
||||
|
||||
## Reference Documentation
|
||||
|
||||
- Detections (detection/core): https://supervision.roboflow.com/latest/detection/core/
|
||||
- Annotators (detection/annotators): https://supervision.roboflow.com/latest/detection/annotators/
|
||||
- CompactMask (detection/compact_mask): https://supervision.roboflow.com/latest/detection/compact_mask/
|
||||
- Format Converters (detection/utils/converters): https://supervision.roboflow.com/latest/detection/utils/converters/
|
||||
- IoU and NMS (detection/utils/iou_and_nms): https://supervision.roboflow.com/latest/detection/utils/iou_and_nms/
|
||||
- Boxes (detection/utils/boxes): https://supervision.roboflow.com/latest/detection/utils/boxes/
|
||||
- Masks (detection/utils/masks): https://supervision.roboflow.com/latest/detection/utils/masks/
|
||||
- Polygons (detection/utils/polygons): https://supervision.roboflow.com/latest/detection/utils/polygons/
|
||||
- VLMs (detection/utils/vlms): https://supervision.roboflow.com/latest/detection/utils/vlms/
|
||||
- Keypoint Core (keypoint/core): https://supervision.roboflow.com/latest/keypoint/core/
|
||||
- Keypoint Annotators (keypoint/annotators): https://supervision.roboflow.com/latest/keypoint/annotators/
|
||||
- Classification Core (classification/core): https://supervision.roboflow.com/latest/classification/core/
|
||||
- ByteTrack Tracker (trackers): https://supervision.roboflow.com/latest/trackers/
|
||||
- Datasets Core (datasets/core): https://supervision.roboflow.com/latest/datasets/core/
|
||||
- mAP (metrics/mean_average_precision): https://supervision.roboflow.com/latest/metrics/mean_average_precision/
|
||||
- mAR (metrics/mean_average_recall): https://supervision.roboflow.com/latest/metrics/mean_average_recall/
|
||||
- Precision (metrics/precision): https://supervision.roboflow.com/latest/metrics/precision/
|
||||
- Recall (metrics/recall): https://supervision.roboflow.com/latest/metrics/recall/
|
||||
- F1 Score (metrics/f1_score): https://supervision.roboflow.com/latest/metrics/f1_score/
|
||||
- Common Values (metrics/common_values): https://supervision.roboflow.com/latest/metrics/common_values/
|
||||
- Line Zone (detection/tools/line_zone): https://supervision.roboflow.com/latest/detection/tools/line_zone/
|
||||
- Polygon Zone (detection/tools/polygon_zone): https://supervision.roboflow.com/latest/detection/tools/polygon_zone/
|
||||
- Inference Slicer (detection/tools/inference_slicer): https://supervision.roboflow.com/latest/detection/tools/inference_slicer/
|
||||
- Detection Smoother (detection/tools/smoother): https://supervision.roboflow.com/latest/detection/tools/smoother/
|
||||
- Save Detections Tool (detection/tools/save_detections): https://supervision.roboflow.com/latest/detection/tools/save_detections/
|
||||
- Video Utils (utils/video): https://supervision.roboflow.com/latest/utils/video/
|
||||
- Image Utils (utils/image): https://supervision.roboflow.com/latest/utils/image/
|
||||
- Iterable Utils (utils/iterables): https://supervision.roboflow.com/latest/utils/iterables/
|
||||
- Notebook Utils (utils/notebook): https://supervision.roboflow.com/latest/utils/notebook/
|
||||
- File Utils (utils/file): https://supervision.roboflow.com/latest/utils/file/
|
||||
- Draw Utils (utils/draw): https://supervision.roboflow.com/latest/utils/draw/
|
||||
- Geometry (utils/geometry): https://supervision.roboflow.com/latest/utils/geometry/
|
||||
- Assets (assets): https://supervision.roboflow.com/latest/assets/
|
||||
|
||||
## Cookbooks
|
||||
|
||||
- Object tracking: https://supervision.roboflow.com/latest/cookbooks/#object-tracking
|
||||
- Count objects crossing line: https://supervision.roboflow.com/latest/cookbooks/#count-objects-crossing-the-line
|
||||
- Zero-shot object detection with YOLO-World: https://supervision.roboflow.com/latest/cookbooks/#zero-shot-object-detection-with-yolo-world
|
||||
- SAHI small object detection: https://supervision.roboflow.com/latest/cookbooks/#small-object-detection-with-sahi
|
||||
|
||||
## FAQ
|
||||
|
||||
### What is supervision?
|
||||
|
||||
Supervision is an open-source Python library by Roboflow for computer vision workflows. It provides a unified `Detections` class with converters for supported detection, segmentation, and VLM outputs, plus tools for annotation, tracking, zone counting, dataset management, and model benchmarking.
|
||||
|
||||
### How do I install supervision?
|
||||
|
||||
Install with `pip install supervision`. For optional metric dependencies use `pip install supervision[metrics]`. Sample asset utilities are included in the base package under `supervision.assets`. The current package metadata requires Python 3.9+.
|
||||
|
||||
### What can I do with supervision?
|
||||
|
||||
Annotate images and video with bounding boxes, masks, and labels; track objects across frames with persistent IDs; count detections inside polygon zones or line crossings; filter and query detection results; load, split, and convert detection datasets between YOLO, COCO, and Pascal VOC formats; manage classification datasets with folder structures; and benchmark model performance with mAP and confusion matrices.
|
||||
|
||||
### Is supervision free to use?
|
||||
|
||||
Yes. Supervision is free and open-source under the MIT license. Source code is at https://github.com/roboflow/supervision.
|
||||
|
||||
### Which object detection models work with supervision?
|
||||
|
||||
Supervision is model-agnostic and works with supported outputs from Ultralytics YOLO, Roboflow Inference, Hugging Face Transformers, SAM, Detectron2, MMDetection, YOLO-NAS, PaddleDet, NCNN, Azure AI Vision, and VLM parsers such as Florence-2, PaliGemma, Qwen VL, Gemini, DeepSeek VL 2, and Moondream. Keypoint outputs have separate converters, including MediaPipe.
|
||||
|
||||
### How do I benchmark a model with supervision?
|
||||
|
||||
Use `supervision.metrics.mean_average_precision.MeanAveragePrecision` for mAP — accumulate predictions and ground truth with `update(...)` then call `compute()`. For confusion matrices, use `sv.ConfusionMatrix.from_detections(predictions=predictions, targets=targets, classes=classes)`. See the Benchmark a Model how-to guide for a complete walkthrough.
|
||||
|
||||
### How do I track objects across video frames?
|
||||
|
||||
Use a tracker to assign persistent IDs. The built-in `sv.ByteTrack` wrapper accepts `Detections` with `update_with_detections()`, but it is deprecated in favor of `ByteTrackTracker` from the external `trackers` package. Combine tracked detections with `sv.TraceAnnotator` to visualize trajectories.
|
||||
|
||||
### What dataset formats does supervision support?
|
||||
|
||||
For detection datasets, supervision supports YOLO, COCO JSON, and Pascal VOC. Use `DetectionDataset.from_yolo()`, `from_coco()`, or `from_pascal_voc()` to load, and `as_yolo()`, `as_coco()`, or `as_pascal_voc()` to save. For classification datasets, use `ClassificationDataset.from_folder_structure()` and `as_folder_structure()`.
|
||||
|
||||
### How do I count objects in a zone?
|
||||
|
||||
Use `sv.PolygonZone` for arbitrary polygon zones. Use `sv.LineZone` for line-crossing counts after assigning tracker IDs, because `LineZone` needs `detections.tracker_id` to match objects across frames.
|
||||
|
||||
### How do I detect small objects with supervision?
|
||||
|
||||
Use `sv.InferenceSlicer` to split high-resolution images into overlapping tiles, run detection on each tile, and merge results with non-maximum suppression. Configure tile overlap in pixels with `overlap_wh`. See the Detect Small Objects how-to guide.
|
||||
|
||||
## Benchmarking
|
||||
|
||||
Supervision includes `supervision.metrics.MeanAveragePrecision` and `sv.ConfusionMatrix` for benchmarking object detection models. A curated [Model Leaderboard](https://leaderboard.roboflow.com/) compares YOLOv8, YOLOv11, and other models on standard datasets. The leaderboard repository is open source at https://github.com/roboflow/model-leaderboard.
|
||||
|
||||
## License
|
||||
|
||||
MIT — https://github.com/roboflow/supervision/blob/develop/LICENSE.md
|
||||
|
||||
## Citation
|
||||
|
||||
```bibtex
|
||||
@software{supervision,
|
||||
author = {Roboflow},
|
||||
title = {Supervision: Computer Vision Toolkit},
|
||||
url = {https://github.com/roboflow/supervision},
|
||||
year = {2023}
|
||||
}
|
||||
```
|
||||
|
||||
## Versioning
|
||||
|
||||
Stable release docs: https://supervision.roboflow.com/latest/
|
||||
Development branch: https://supervision.roboflow.com/develop/
|
||||
@@ -1,6 +1,5 @@
|
||||
---
|
||||
comments: true
|
||||
status: new
|
||||
---
|
||||
|
||||
# Common Values
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
---
|
||||
comments: true
|
||||
status: new
|
||||
---
|
||||
|
||||
# F1 Score
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
---
|
||||
comments: true
|
||||
status: new
|
||||
description: API reference for MeanAveragePrecision — compute mAP for object detection benchmarking with bounding boxes.
|
||||
---
|
||||
|
||||
# Mean Average Precision
|
||||
@@ -16,3 +16,9 @@ status: new
|
||||
</div>
|
||||
|
||||
:::supervision.metrics.mean_average_precision.MeanAveragePrecisionResult
|
||||
|
||||
<div class="md-typeset">
|
||||
<h2><a href="#supervision.dataset.formats.coco.get_coco_class_index_mapping">get_coco_class_index_mapping</a></h2>
|
||||
</div>
|
||||
|
||||
:::supervision.dataset.formats.coco.get_coco_class_index_mapping
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
---
|
||||
comments: true
|
||||
status: new
|
||||
---
|
||||
|
||||
# Mean Average Recall
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
---
|
||||
comments: true
|
||||
status: new
|
||||
---
|
||||
|
||||
# Precision
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
---
|
||||
comments: true
|
||||
status: new
|
||||
---
|
||||
|
||||
# Recall
|
||||
|
||||
+2
-3
@@ -93,7 +93,7 @@
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"!pip install -q inference-gpu \"supervision[assets]\""
|
||||
"!pip install -q inference-gpu \"supervision\""
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -156,7 +156,7 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 4,
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"colab": {
|
||||
"base_uri": "https://localhost:8080/"
|
||||
@@ -207,7 +207,6 @@
|
||||
],
|
||||
"source": [
|
||||
"import supervision as sv\n",
|
||||
"from supervision.assets import download_assets, VideoAssets\n",
|
||||
"from inference.models.utils import get_roboflow_model\n",
|
||||
"\n",
|
||||
"\n",
|
||||
|
||||
+24
-14
File diff suppressed because one or more lines are too long
+2
-2
@@ -17,7 +17,7 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 10,
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"vscode": {
|
||||
"languageId": "shellscript"
|
||||
@@ -25,7 +25,7 @@
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"!pip install -q \"supervision[assets]\""
|
||||
"pip install -q \"supervision\""
|
||||
]
|
||||
},
|
||||
{
|
||||
|
||||
+1
-1
@@ -101,7 +101,7 @@
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"!pip install -q torch diffusers accelerate inference-gpu[yolo-world] dill git+https://github.com/openai/CLIP.git supervision==0.19.0rc5"
|
||||
"!pip install -q torch diffusers accelerate inference-gpu[yolo-world] dill git+https://github.com/openai/CLIP.git supervision"
|
||||
]
|
||||
},
|
||||
{
|
||||
|
||||
Vendored
+1
-1
@@ -92,7 +92,7 @@
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"!pip install -q inference-gpu \"supervision[assets]\""
|
||||
"!pip install -q inference-gpu \"supervision\""
|
||||
]
|
||||
},
|
||||
{
|
||||
|
||||
+1
-1
@@ -72,7 +72,7 @@
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"!pip install roboflow supervision==0.19.0 -q"
|
||||
"!pip install roboflow supervision -q"
|
||||
]
|
||||
},
|
||||
{
|
||||
|
||||
Vendored
+5
-5
@@ -300,7 +300,7 @@
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"!pip install -q \"ultralytics<=8.3.40\""
|
||||
"!pip install -q ultralytics"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -495,7 +495,7 @@
|
||||
"source": [
|
||||
"from ultralytics import YOLO\n",
|
||||
"\n",
|
||||
"model = YOLO(\"yolov8x.pt\")\n",
|
||||
"model = YOLO(\"yolo11x.pt\")\n",
|
||||
"result = model(image, verbose=False)[0]\n",
|
||||
"detections = sv.Detections.from_ultralytics(result)"
|
||||
]
|
||||
@@ -594,7 +594,7 @@
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 33,
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"id": "yM6dmicTRGl6"
|
||||
},
|
||||
@@ -602,7 +602,7 @@
|
||||
"source": [
|
||||
"from ultralytics import YOLO\n",
|
||||
"\n",
|
||||
"model = YOLO(\"yolov8x-seg.pt\")\n",
|
||||
"model = YOLO(\"yolo11x-seg.pt\")\n",
|
||||
"result = model(image, verbose=False)[0]\n",
|
||||
"detections = sv.Detections.from_ultralytics(result)"
|
||||
]
|
||||
@@ -926,7 +926,7 @@
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"!pip install -q supervision[assets]"
|
||||
"!pip install -q supervision"
|
||||
]
|
||||
},
|
||||
{
|
||||
|
||||
+9
-19
File diff suppressed because one or more lines are too long
+4
-4
@@ -32,7 +32,7 @@
|
||||
},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"!pip install -q inference requests tqdm supervision==0.21.0"
|
||||
"!pip install -q inference requests tqdm supervision"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -695,12 +695,12 @@
|
||||
"source": [
|
||||
"###\u00a0Annotate Image with Detections\n",
|
||||
"\n",
|
||||
"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/latest/detection/annotators/#supervision.annotators.core.BoundingBoxAnnotator) and [`sv.LabelAnnotator`](https://supervision.roboflow.com/latest/detection/annotators/#supervision.annotators.core.LabelAnnotator) classes."
|
||||
"Finally, we can annotate the image with the predictions. Since we are working with an object detection model, we will use the [`sv.BoxAnnotator`](https://supervision.roboflow.com/latest/detection/annotators/#supervision.annotators.core.BoxAnnotator) and [`sv.LabelAnnotator`](https://supervision.roboflow.com/latest/detection/annotators/#supervision.annotators.core.LabelAnnotator) classes."
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 49,
|
||||
"execution_count": null,
|
||||
"metadata": {
|
||||
"colab": {
|
||||
"base_uri": "https://localhost:8080/",
|
||||
@@ -722,7 +722,7 @@
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"bounding_box_annotator = sv.BoundingBoxAnnotator()\n",
|
||||
"bounding_box_annotator = sv.BoxAnnotator()\n",
|
||||
"label_annotator = sv.LabelAnnotator()\n",
|
||||
"\n",
|
||||
"annotated_frame = frame.copy()\n",
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -0,0 +1,25 @@
|
||||
User-agent: *
|
||||
Allow: /
|
||||
|
||||
User-agent: GPTBot
|
||||
Allow: /
|
||||
|
||||
User-agent: ClaudeBot
|
||||
Allow: /
|
||||
|
||||
User-agent: PerplexityBot
|
||||
Allow: /
|
||||
|
||||
User-agent: Bytespider
|
||||
Allow: /
|
||||
|
||||
User-agent: CCBot
|
||||
Allow: /
|
||||
|
||||
User-agent: GoogleOther
|
||||
Allow: /
|
||||
|
||||
User-agent: Applebot
|
||||
Allow: /
|
||||
|
||||
Sitemap: https://supervision.roboflow.com/sitemap.xml
|
||||
@@ -15,7 +15,7 @@
|
||||
/* Large screens (1024px and up) */
|
||||
@media (min-width: 1024px) {
|
||||
.custom-grid {
|
||||
grid-template-columns: repeat(3, minmax(0, 1fr));
|
||||
grid-template-columns: repeat(4, minmax(0, 1fr));
|
||||
}
|
||||
}
|
||||
|
||||
+241
-2
@@ -1,7 +1,10 @@
|
||||
:root {
|
||||
:root, body {
|
||||
/* Default to light theme */
|
||||
--md-primary-fg-color: #8315F9;
|
||||
--md-accent-fg-color: #00FFCE;
|
||||
--md-code-hl-color: #8315F9 !important;
|
||||
--md-accent-fg-color: #8315F9 !important;
|
||||
--md-code-hl-color--light: #e8d2ff89 !important;
|
||||
--md-footer-fg-color--light: rgb(111, 108, 121) !important;
|
||||
}
|
||||
|
||||
body.light {
|
||||
@@ -9,6 +12,202 @@ body.light {
|
||||
--md-text-color: #000000;
|
||||
--md-h2-color: #000000;
|
||||
}
|
||||
.md-grid {
|
||||
max-width: 85%;
|
||||
margin: auto;
|
||||
}
|
||||
.sublist {
|
||||
display: none;
|
||||
list-style: none;
|
||||
padding-left: 0;
|
||||
background: white;
|
||||
position: absolute;
|
||||
border-radius: 8px;
|
||||
margin-top: 0.25rem;
|
||||
}
|
||||
.sublist {
|
||||
transition: opacity 0.5s ease-in-out;
|
||||
display: none;
|
||||
position: absolute; /* Ensure it overlaps and doesn't break flow */
|
||||
background: white; /* So it's visible */
|
||||
z-index: 1000;
|
||||
}
|
||||
.sublist li {
|
||||
padding: 0.5rem;
|
||||
}
|
||||
#products-list *:hover .products-sublist {
|
||||
display: block;
|
||||
}
|
||||
#resources-list *, #products-list * {
|
||||
cursor: pointer;
|
||||
}
|
||||
.products-sublist, .resources-sublist {
|
||||
padding: 0.25rem;
|
||||
}
|
||||
.products-sublist li:hover, .resources-sublist li:hover, .md-nav__link[href]:hover {
|
||||
background: rgb(242, 241, 247) !important;
|
||||
border-radius: 6px;
|
||||
color: initial !important;
|
||||
}
|
||||
.md-search {
|
||||
flex-grow: 2;
|
||||
}
|
||||
.portfolio-section .md-grid {
|
||||
max-width: 100%;
|
||||
}
|
||||
.md-header__inner {
|
||||
align-items: center;
|
||||
display: grid;
|
||||
grid-template-columns: 0.1fr 1.4fr 2fr 2fr;
|
||||
padding-right: 1rem;
|
||||
}
|
||||
.md-search__inner {
|
||||
max-width: 600px;
|
||||
width: 100%;
|
||||
min-width: 100%;
|
||||
}
|
||||
.md-search__input {
|
||||
background: white;
|
||||
border: 1px solid rgb(229, 231, 235);
|
||||
border-radius: 8px;
|
||||
color: rgb(111, 108, 121);
|
||||
}
|
||||
.md-search__form *, .md-search__icon, .md-search__input {
|
||||
color: rgb(111, 108, 121);
|
||||
}
|
||||
.md-search__input::placeholder {
|
||||
color: rgb(156, 163, 175);
|
||||
}
|
||||
.md-search__form {
|
||||
background: none !important;
|
||||
}
|
||||
.md-footer, .md-footer-meta {
|
||||
background-color: transparent;
|
||||
color: rgb(111, 108, 121);
|
||||
}
|
||||
.md-typeset .tabbed-set > input:first-child:checked ~ .tabbed-labels > :first-child, .md-typeset .tabbed-set > input:nth-child(10):checked ~ .tabbed-labels > :nth-child(10), .md-typeset .tabbed-set > input:nth-child(11):checked ~ .tabbed-labels > :nth-child(11), .md-typeset .tabbed-set > input:nth-child(12):checked ~ .tabbed-labels > :nth-child(12), .md-typeset .tabbed-set > input:nth-child(13):checked ~ .tabbed-labels > :nth-child(13), .md-typeset .tabbed-set > input:nth-child(14):checked ~ .tabbed-labels > :nth-child(14), .md-typeset .tabbed-set > input:nth-child(15):checked ~ .tabbed-labels > :nth-child(15), .md-typeset .tabbed-set > input:nth-child(16):checked ~ .tabbed-labels > :nth-child(16), .md-typeset .tabbed-set > input:nth-child(17):checked ~ .tabbed-labels > :nth-child(17), .md-typeset .tabbed-set > input:nth-child(18):checked ~ .tabbed-labels > :nth-child(18), .md-typeset .tabbed-set > input:nth-child(19):checked ~ .tabbed-labels > :nth-child(19), .md-typeset .tabbed-set > input:nth-child(2):checked ~ .tabbed-labels > :nth-child(2), .md-typeset .tabbed-set > input:nth-child(20):checked ~ .tabbed-labels > :nth-child(20), .md-typeset .tabbed-set > input:nth-child(3):checked ~ .tabbed-labels > :nth-child(3), .md-typeset .tabbed-set > input:nth-child(4):checked ~ .tabbed-labels > :nth-child(4), .md-typeset .tabbed-set > input:nth-child(5):checked ~ .tabbed-labels > :nth-child(5), .md-typeset .tabbed-set > input:nth-child(6):checked ~ .tabbed-labels > :nth-child(6), .md-typeset .tabbed-set > input:nth-child(7):checked ~ .tabbed-labels > :nth-child(7), .md-typeset .tabbed-set > input:nth-child(8):checked ~ .tabbed-labels > :nth-child(8), .md-typeset .tabbed-set > input:nth-child(9):checked ~ .tabbed-labels > :nth-child(9) {
|
||||
color: #8315F9;
|
||||
border-bottom: 1px solid #8315F9;
|
||||
}
|
||||
.md-footer *, html .md-footer-meta.md-typeset a {
|
||||
color: rgb(111, 108, 121);
|
||||
}
|
||||
.repo-card {
|
||||
height: 100%;
|
||||
}
|
||||
.header-btn {
|
||||
text-align: center;
|
||||
}
|
||||
.header-btn, .sublist {
|
||||
box-shadow: rgb(255, 255, 255) 0px 0px 0px 0px, rgb(217, 215, 226) 0px 0px 0px 1px, rgb(217, 215, 226) 0px 1px 2px 0px;
|
||||
}
|
||||
.header-btn:hover {
|
||||
box-shadow: rgb(255, 255, 255) 0px 0px 0px 0px, rgb(217, 215, 226) 0px 0px 0px 1px, rgb(217, 215, 226) 0px 1.0001px 2.00013px -0.0000327245px, rgba(0, 0, 0, 0) 0px 0.000065449px 0.000130898px -0.000065449px;
|
||||
}
|
||||
.md-typeset .headerlink:hover, .md-typeset .headerlink:target {
|
||||
color: #8315F9;
|
||||
}
|
||||
.md-typeset h1, .md-header__title {
|
||||
color: black;
|
||||
font-weight: 800;
|
||||
}
|
||||
.md-typeset h1 {
|
||||
font-weight: normal;
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
body {
|
||||
background: linear-gradient(to left bottom, rgb(243, 238, 255), rgb(255, 255, 255) 60%) no-repeat;
|
||||
}
|
||||
|
||||
/* .md-nav__link:has([tabindex=""]) {
|
||||
text-transform: uppercase;
|
||||
} */
|
||||
|
||||
.header-list {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 1rem;
|
||||
list-style: none;
|
||||
font-size: 0.75rem;
|
||||
justify-content: flex-end;
|
||||
}
|
||||
.md-nav__list label, .md-nav--secondary label {
|
||||
/* text-transform: uppercase; */
|
||||
color: rgb(29, 29, 31) !important;
|
||||
font-size: 0.7rem;
|
||||
margin-bottom: 0;
|
||||
}
|
||||
.md-nav--secondary label {
|
||||
margin-left: 0.5rem;
|
||||
}
|
||||
|
||||
.md-nav__link {
|
||||
padding: 0.25rem;
|
||||
padding-left: 0.5rem;
|
||||
padding-right: 0.5rem;
|
||||
}
|
||||
|
||||
.md-nav__link--active {
|
||||
background: rgb(243, 238, 255);
|
||||
border-radius: 6px;
|
||||
padding-top: 0.25rem;
|
||||
}
|
||||
|
||||
.md-tabs__item--active {
|
||||
color: var(--md-primary-fg-color);
|
||||
border-bottom: 2px solid var(--md-primary-fg-color);
|
||||
}
|
||||
|
||||
.md-nav--secondary .md-nav__title {
|
||||
background: transparent;
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
.md-header, .md-tabs {
|
||||
color: rgb(111, 108, 121);
|
||||
background-color: transparent;
|
||||
}
|
||||
.md-header--shadow {
|
||||
background: linear-gradient(to left bottom, rgb(243, 238, 255), rgb(255, 255, 255) 60%);
|
||||
box-shadow: none;
|
||||
border-bottom: 1px solid rgb(229, 231, 235);
|
||||
}
|
||||
|
||||
#item-logo {
|
||||
display: none;
|
||||
}
|
||||
.md-main__inner, .md-header__inner, .md-grid {
|
||||
max-width: 100%;
|
||||
}
|
||||
@media (max-width: 1200px) {
|
||||
.md-header__inner {
|
||||
display: flex;
|
||||
}
|
||||
.header-list {
|
||||
display: none;
|
||||
}
|
||||
#item-logo {
|
||||
display: block;
|
||||
}
|
||||
}
|
||||
.md-content {
|
||||
max-width: 40rem;
|
||||
margin: auto;
|
||||
}
|
||||
/* // if no md-sidebar--primary, make .md-content full width */
|
||||
.md-main__inner:has(.md-sidebar--primary[hidden]) .md-content {
|
||||
max-width: 100%;
|
||||
}
|
||||
.md-sidebar--primary {
|
||||
flex: 0 20%;
|
||||
}
|
||||
.md-tabs {
|
||||
border-bottom: 1px solid rgb(229, 231, 235);
|
||||
}
|
||||
.md-main__inner {
|
||||
padding-top: 1rem;
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
body.dark {
|
||||
/* Dark theme */
|
||||
@@ -29,3 +228,43 @@ body[data-md-url$="/cookbooks/"] .md-content {
|
||||
margin-left: 0;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.md-main, nav .md-grid, .md-header__inner {
|
||||
max-width: 1600px;
|
||||
width: 100%;
|
||||
margin: auto;
|
||||
}
|
||||
.md-search__scrollwrap {
|
||||
width: 100% !important;
|
||||
}
|
||||
.md-nav--secondary .md-nav__title {
|
||||
position: initial !important;
|
||||
}
|
||||
|
||||
.md-header__title .md-ellipsis {
|
||||
overflow: initial !important;
|
||||
text-overflow: initial !important;
|
||||
}
|
||||
.md-search {
|
||||
flex-grow: 0;
|
||||
}
|
||||
|
||||
/* Table style */
|
||||
|
||||
th, td {
|
||||
border: 1px solid var(--md-typeset-table-color);
|
||||
}
|
||||
|
||||
.md-typeset__table {
|
||||
line-height: 1.5;
|
||||
}
|
||||
|
||||
.md-typeset__table table:not([class]) {
|
||||
font-size: 0.6rem;
|
||||
border-collapse: collapse;
|
||||
}
|
||||
|
||||
.md-typeset__table table:not([class]) td,
|
||||
.md-typeset__table table:not([class]) th {
|
||||
padding: 10px;
|
||||
}
|
||||
|
||||
Vendored
+24
-20
@@ -11,48 +11,52 @@
|
||||
<h1>Supervision Cookbooks</h1>
|
||||
</div>
|
||||
<div class="custom-grid">
|
||||
<a href="/develop/notebooks/quickstart"> <p class="card repo-card" data-name="Supervision Quickstart" data-labels="ANNOTATOR,DETECTION,SAM"
|
||||
data-version="v0.18.0" data-author="SkalskiP,onuralpszr"></p>
|
||||
<a href="../notebooks/quickstart/"> <p class="card repo-card" data-name="Supervision Quickstart" data-labels="ANNOTATOR,DETECTION,SAM"
|
||||
data-version="v0.26.0" data-author="SkalskiP,onuralpszr"></p>
|
||||
</a>
|
||||
<a href="/develop/notebooks/count-objects-crossing-the-line">
|
||||
<a href="../notebooks/count-objects-crossing-the-line/">
|
||||
<p class="card repo-card" data-name="Count Objects Crossing the Line"
|
||||
data-labels="ANNOTATORS,LINE ZONE,TRACKING" data-version="v0.18.0" data-author="SkalskiP"></p>
|
||||
data-labels="ANNOTATORS,LINE ZONE,TRACKING" data-version="v0.26.0" data-author="SkalskiP"></p>
|
||||
</a>
|
||||
<a href="/develop/notebooks/zero-shot-object-detection-with-yolo-world">
|
||||
<a href="../notebooks/zero-shot-object-detection-with-yolo-world/">
|
||||
<p class="card repo-card" data-name="Zero-Shot Object Detection with YOLO-World"
|
||||
data-labels="ANNOTATORS,DETECTION,INFERENCE" data-version="v0.19.0" data-author="SkalskiP"></p>
|
||||
data-labels="ANNOTATORS,DETECTION,INFERENCE" data-version="v0.26.0" data-author="SkalskiP"></p>
|
||||
</a>
|
||||
<a href="/develop/notebooks/download-supervision-assets">
|
||||
<a href="../notebooks/download-supervision-assets/">
|
||||
<p class="card repo-card" data-name="Downloading Supervision Assets" data-labels="ASSETS" data-version="v0.18.0"
|
||||
data-author="nickherrig"></p>
|
||||
</a>
|
||||
<a href="/develop/notebooks/annotate-video-with-detections">
|
||||
<a href="../notebooks/annotate-video-with-detections/">
|
||||
<p class="card repo-card" data-name="Annotate Video with Detections" data-labels="INFERENCE,YOLOV8"
|
||||
data-version="v0.18.0" data-author="nickherrig"></p>
|
||||
data-version="v0.26.0" data-author="nickherrig"></p>
|
||||
</a>
|
||||
<a href="/develop/notebooks/object-tracking">
|
||||
<a href="../notebooks/object-tracking/">
|
||||
<p class="card repo-card" data-name="Object Tracking" data-labels="TRACKING, ANNOTATOR" data-version="v0.18.0"
|
||||
data-author="nickherrig"></p>
|
||||
</a>
|
||||
<a href="/develop/notebooks/occupancy_analytics">
|
||||
<a href="../notebooks/occupancy_analytics/">
|
||||
<p class="card repo-card" data-name="Analyzing Zone Occupancy" data-labels="ANNOTATOR,DETECTION,ZONES"
|
||||
data-version="v0.19.0" data-author="stellasphere"></p>
|
||||
data-version="v0.26.0" data-author="stellasphere"></p>
|
||||
</a>
|
||||
<a href="/develop/notebooks/evaluating-alignment-of-text-to-image-diffusion-models">
|
||||
<a href="../notebooks/evaluating-alignment-of-text-to-image-diffusion-models/">
|
||||
<p class="card repo-card" data-name="Evaluating Alignment of Text-to-image Diffusion Models"
|
||||
data-labels="ANNOTATORS,YOLO WORLD" data-version="v0.19.0rc5" data-author="iamhatesz"></p>
|
||||
data-labels="ANNOTATORS,YOLO WORLD" data-version="v0.26.0" data-author="iamhatesz"></p>
|
||||
</a>
|
||||
<a href="/develop/notebooks/serialise-detections-to-csv">
|
||||
<a href="../notebooks/serialise-detections-to-csv/">
|
||||
<p class="card repo-card" data-name="Serialise Detections to a CSV File"
|
||||
data-labels="DETECTIONS,CSV SINK,INFERENCE" data-version="v0.21.0" data-author="onuralpszr"></p>
|
||||
data-labels="DETECTIONS,CSV SINK,INFERENCE" data-version="v0.26.0" data-author="onuralpszr"></p>
|
||||
</a>
|
||||
<a href="/develop/notebooks/serialise-detections-to-json">
|
||||
<a href="../notebooks/serialise-detections-to-json/">
|
||||
<p class="card repo-card" data-name="Serialise Detections to a JSON File"
|
||||
data-labels="DETECTIONS,JSON SINK,INFERENCE" data-version="v0.21.0" data-author="onuralpszr"></p>
|
||||
data-labels="DETECTIONS,JSON SINK,INFERENCE" data-version="v0.26.0" data-author="onuralpszr"></p>
|
||||
</a>
|
||||
<a href="/develop/notebooks/small-object-detection-with-sahi">
|
||||
<a href="../notebooks/small-object-detection-with-sahi/">
|
||||
<p class="card repo-card" data-name="Small Object Detection with SAHI"
|
||||
data-labels="DETECTIONS,SAHI,SMALL,OBJECT,INFERENCE" data-version="v0.23.0" data-author="ediardo"></p>
|
||||
data-labels="DETECTIONS,SAHI,SMALL,OBJECT,INFERENCE" data-version="v0.26.0" data-author="ediardo"></p>
|
||||
</a>
|
||||
<a href="../notebooks/underestand-visitors-with-yolo-world/">
|
||||
<p class="card repo-card" data-name="Understand Visitors with YOLO-World"
|
||||
data-labels="ANNOTATORS,DETECTION,INFERENCE" data-version="v0.19.0" data-author="AdonaiVera"></p>
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
Vendored
+479
-1
@@ -12,6 +12,484 @@
|
||||
{% endblock content %}
|
||||
|
||||
{% block extrahead %}
|
||||
{{ super() }}
|
||||
{% if page.meta is defined and page.meta is not none and page.meta is not undefined %}
|
||||
{% set _meta = page.meta %}
|
||||
{% else %}
|
||||
{% set _meta = {} %}
|
||||
{% endif %}
|
||||
{% set page_description = _meta.description | d(config.site_description) %}
|
||||
{# ── GEO: JSON-LD + OG tags (page context required — skip for theme templates like 404) #}
|
||||
|
||||
{# ── GEO: JSON-LD structured data ──────────────────────────── #}
|
||||
<script type="application/ld+json">
|
||||
{
|
||||
"@context": "https://schema.org",
|
||||
"@type": "Organization",
|
||||
"name": "Roboflow",
|
||||
"url": "https://roboflow.com",
|
||||
"logo": {
|
||||
"@type": "ImageObject",
|
||||
"url": "https://media.roboflow.com/open-source/supervision/rf-supervision-banner.png",
|
||||
"width": 1200,
|
||||
"height": 630
|
||||
},
|
||||
"sameAs": [
|
||||
"https://github.com/roboflow/supervision",
|
||||
"https://pypi.org/project/supervision",
|
||||
"https://twitter.com/roboflow",
|
||||
"https://www.youtube.com/roboflow",
|
||||
"https://en.wikipedia.org/wiki/Roboflow",
|
||||
"https://www.linkedin.com/company/roboflow-ai"
|
||||
]
|
||||
}
|
||||
</script>
|
||||
|
||||
<script type="application/ld+json">
|
||||
{
|
||||
"@context": "https://schema.org",
|
||||
"@type": "SoftwareApplication",
|
||||
"name": "supervision",
|
||||
"applicationCategory": "DeveloperApplication",
|
||||
"operatingSystem": "Linux, macOS, Windows",
|
||||
"programmingLanguage": "Python",
|
||||
"url": "https://supervision.roboflow.com/",
|
||||
"downloadUrl": "https://pypi.org/project/supervision",
|
||||
"codeRepository": "https://github.com/roboflow/supervision",
|
||||
"license": "https://github.com/roboflow/supervision/blob/develop/LICENSE.md",
|
||||
"description": "Open-source Python library for computer vision: load datasets, draw detections, count objects in zones, and track across frames.",
|
||||
"offers": {
|
||||
"@type": "Offer",
|
||||
"price": "0",
|
||||
"priceCurrency": "USD"
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<script type="application/ld+json">
|
||||
{
|
||||
"@context": "https://schema.org",
|
||||
"@type": "WebSite",
|
||||
"name": "Supervision Documentation",
|
||||
"url": "https://supervision.roboflow.com/",
|
||||
"publisher": {
|
||||
"@type": "Organization",
|
||||
"name": "Roboflow",
|
||||
"url": "https://roboflow.com"
|
||||
},
|
||||
"potentialAction": {
|
||||
"@type": "SearchAction",
|
||||
"target": "{{ config.site_url }}search/?q={search_term_string}",
|
||||
"query-input": "required name=search_term_string"
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<script type="application/ld+json">
|
||||
{
|
||||
"@context": "https://schema.org",
|
||||
"@type": "SoftwareSourceCode",
|
||||
"name": "supervision",
|
||||
"codeRepository": "https://github.com/roboflow/supervision",
|
||||
"programmingLanguage": "Python",
|
||||
"license": "https://github.com/roboflow/supervision/blob/develop/LICENSE.md",
|
||||
"runtimePlatform": "Python 3",
|
||||
"targetProduct": {
|
||||
"@type": "SoftwareApplication",
|
||||
"name": "supervision"
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
{% for is_home in [page.is_homepage] %}{% if is_home %}
|
||||
<script type="application/ld+json">
|
||||
{
|
||||
"@context": "https://schema.org",
|
||||
"@type": "FAQPage",
|
||||
"mainEntity": [
|
||||
{
|
||||
"@type": "Question",
|
||||
"name": "What is supervision?",
|
||||
"acceptedAnswer": {
|
||||
"@type": "Answer",
|
||||
"text": "Supervision is an open-source Python library by Roboflow for computer vision workflows. It provides a unified Detections class with converters for supported detection, segmentation, and VLM outputs, plus tools for annotation, tracking, zone counting, dataset management, and model benchmarking."
|
||||
}
|
||||
},
|
||||
{
|
||||
"@type": "Question",
|
||||
"name": "How do I install supervision?",
|
||||
"acceptedAnswer": {
|
||||
"@type": "Answer",
|
||||
"text": "Install supervision with pip: pip install supervision. For optional metric dependencies use pip install supervision[metrics]. Sample asset utilities are included in the base package under supervision.assets. The current package metadata requires Python 3.9+."
|
||||
}
|
||||
},
|
||||
{
|
||||
"@type": "Question",
|
||||
"name": "What can I do with supervision?",
|
||||
"acceptedAnswer": {
|
||||
"@type": "Answer",
|
||||
"text": "With supervision you can annotate images and video with bounding boxes, masks, and labels; track objects across frames with persistent IDs; count detections inside polygon zones or line crossings with tracked detections; filter and query detection results; load, split, and convert detection datasets between YOLO, COCO, and Pascal VOC formats; manage classification datasets with folder structures; and benchmark model performance with mAP and confusion matrices."
|
||||
}
|
||||
},
|
||||
{
|
||||
"@type": "Question",
|
||||
"name": "Is supervision free to use?",
|
||||
"acceptedAnswer": {
|
||||
"@type": "Answer",
|
||||
"text": "Yes. Supervision is free and open-source under the MIT license. Source code is at https://github.com/roboflow/supervision."
|
||||
}
|
||||
},
|
||||
{
|
||||
"@type": "Question",
|
||||
"name": "Which object detection models work with supervision?",
|
||||
"acceptedAnswer": {
|
||||
"@type": "Answer",
|
||||
"text": "Supervision is model-agnostic and works with supported outputs from Ultralytics YOLO, Roboflow Inference, Hugging Face Transformers, SAM, Detectron2, MMDetection, YOLO-NAS, PaddleDet, NCNN, Azure AI Vision, and VLM parsers such as Florence-2, PaliGemma, Qwen VL, Gemini, DeepSeek VL 2, and Moondream. Keypoint outputs have separate converters, including MediaPipe."
|
||||
}
|
||||
},
|
||||
{
|
||||
"@type": "Question",
|
||||
"name": "How do I benchmark a model with supervision?",
|
||||
"acceptedAnswer": {
|
||||
"@type": "Answer",
|
||||
"text": "Use supervision.metrics.mean_average_precision.MeanAveragePrecision for mAP and sv.ConfusionMatrix for confusion matrices. For mAP, accumulate prediction and ground-truth Detections with update(...) and then call compute(). See the Benchmark a Model guide at https://supervision.roboflow.com/latest/how_to/benchmark_a_model/ for a complete walkthrough."
|
||||
}
|
||||
},
|
||||
{
|
||||
"@type": "Question",
|
||||
"name": "How do I track objects across video frames?",
|
||||
"acceptedAnswer": {
|
||||
"@type": "Answer",
|
||||
"text": "Use a tracker to assign persistent IDs before visualization. The built-in sv.ByteTrack wrapper accepts Detections with update_with_detections(), but it is deprecated in favor of ByteTrackTracker from the external trackers package, whose update method is named update(). Combine tracked Detections with sv.TraceAnnotator to visualize trajectories."
|
||||
}
|
||||
},
|
||||
{
|
||||
"@type": "Question",
|
||||
"name": "What dataset formats does supervision support?",
|
||||
"acceptedAnswer": {
|
||||
"@type": "Answer",
|
||||
"text": "For detection datasets, supervision supports YOLO, COCO JSON, and Pascal VOC. Use DetectionDataset.from_yolo(), from_coco(), or from_pascal_voc() to load, and as_yolo(), as_coco(), or as_pascal_voc() to save. ClassificationDataset supports folder-structure import and export."
|
||||
}
|
||||
},
|
||||
{
|
||||
"@type": "Question",
|
||||
"name": "How do I count objects in a zone?",
|
||||
"acceptedAnswer": {
|
||||
"@type": "Answer",
|
||||
"text": "Use sv.PolygonZone for arbitrary polygon zones. Use sv.LineZone for line-crossing counts after assigning tracker IDs, because LineZone needs detections.tracker_id to match objects across frames."
|
||||
}
|
||||
},
|
||||
{
|
||||
"@type": "Question",
|
||||
"name": "How do I detect small objects with supervision?",
|
||||
"acceptedAnswer": {
|
||||
"@type": "Answer",
|
||||
"text": "Use sv.InferenceSlicer to split high-resolution images into overlapping tiles, run detection on each tile, and merge results with non-maximum suppression. Configure overlap in pixels with overlap_wh. See the Detect Small Objects guide at https://supervision.roboflow.com/latest/how_to/detect_small_objects/."
|
||||
}
|
||||
},
|
||||
{
|
||||
"@type": "Question",
|
||||
"name": "How do I filter detections by class or confidence?",
|
||||
"acceptedAnswer": {
|
||||
"@type": "Answer",
|
||||
"text": "Detections supports NumPy-style boolean indexing. Filter by class: detections[detections.class_id == 0]. Filter by confidence: detections[detections.confidence > 0.5]. Filter by area: detections[detections.area > 1000]. Combine conditions with & or |."
|
||||
}
|
||||
},
|
||||
{
|
||||
"@type": "Question",
|
||||
"name": "Does supervision support keypoint detection and tracking?",
|
||||
"acceptedAnswer": {
|
||||
"@type": "Answer",
|
||||
"text": "Yes. Use sv.KeyPoints.from_ultralytics() or sv.KeyPoints.from_inference() to load keypoint predictions. Convert to detections via as_detections() for tracking. Annotate with sv.EdgeAnnotator and sv.VertexAnnotator."
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
</script>
|
||||
{% endif %}{% endfor %}
|
||||
|
||||
{% if page.url == 'faq/' %}
|
||||
<script type="application/ld+json">
|
||||
{
|
||||
"@context": "https://schema.org",
|
||||
"@type": "FAQPage",
|
||||
"mainEntity": [
|
||||
{
|
||||
"@type": "Question",
|
||||
"name": "What is Supervision?",
|
||||
"acceptedAnswer": {
|
||||
"@type": "Answer",
|
||||
"text": "Supervision is an open-source Python library by Roboflow for computer vision workflows. It provides a unified Detections class with converters for supported object detection, segmentation, and VLM outputs."
|
||||
}
|
||||
},
|
||||
{
|
||||
"@type": "Question",
|
||||
"name": "How do I install Supervision?",
|
||||
"acceptedAnswer": {
|
||||
"@type": "Answer",
|
||||
"text": "Install the base package with pip install supervision. Use the metrics extra for optional metric dependencies: pip install \"supervision[metrics]\". Sample asset utilities are included in the base package under supervision.assets."
|
||||
}
|
||||
},
|
||||
{
|
||||
"@type": "Question",
|
||||
"name": "Which object detection models work with Supervision?",
|
||||
"acceptedAnswer": {
|
||||
"@type": "Answer",
|
||||
"text": "Supervision is model-agnostic. sv.Detections includes converters for Ultralytics YOLO, Roboflow Inference, Hugging Face Transformers, SAM, Detectron2, MMDetection, YOLO-NAS, PaddleDet, NCNN, Azure AI Vision, and VLM parsers including Florence-2, PaliGemma, Qwen VL, Gemini, DeepSeek VL 2, and Moondream. Keypoint outputs have separate sv.KeyPoints converters, including MediaPipe."
|
||||
}
|
||||
},
|
||||
{
|
||||
"@type": "Question",
|
||||
"name": "What can I do with Supervision?",
|
||||
"acceptedAnswer": {
|
||||
"@type": "Answer",
|
||||
"text": "With Supervision you can annotate images and video, filter detections, track objects, count objects in zones or across lines, load and convert datasets between YOLO, COCO JSON, and Pascal VOC formats, evaluate models with detection metrics, and export predictions for downstream analysis."
|
||||
}
|
||||
},
|
||||
{
|
||||
"@type": "Question",
|
||||
"name": "How do I track objects across video frames?",
|
||||
"acceptedAnswer": {
|
||||
"@type": "Answer",
|
||||
"text": "Assign persistent tracker IDs before visualization. The built-in sv.ByteTrack wrapper accepts Detections through update_with_detections(). After tracking, combine the output with annotators such as sv.TraceAnnotator, sv.BoxAnnotator, and sv.LabelAnnotator."
|
||||
}
|
||||
},
|
||||
{
|
||||
"@type": "Question",
|
||||
"name": "What dataset formats does Supervision support?",
|
||||
"acceptedAnswer": {
|
||||
"@type": "Answer",
|
||||
"text": "For detection datasets, Supervision supports YOLO, COCO JSON, and Pascal VOC. Use DetectionDataset.from_yolo(), DetectionDataset.from_coco(), or DetectionDataset.from_pascal_voc() to load datasets, and the matching as_* methods to export them."
|
||||
}
|
||||
},
|
||||
{
|
||||
"@type": "Question",
|
||||
"name": "How do I count objects in a zone?",
|
||||
"acceptedAnswer": {
|
||||
"@type": "Answer",
|
||||
"text": "Use sv.PolygonZone for arbitrary polygon regions and sv.LineZone for line-crossing counts. Line crossing requires detections.tracker_id, so run a tracker before calling the line zone trigger."
|
||||
}
|
||||
},
|
||||
{
|
||||
"@type": "Question",
|
||||
"name": "How do I benchmark a model?",
|
||||
"acceptedAnswer": {
|
||||
"@type": "Answer",
|
||||
"text": "Use supervision.metrics.mean_average_precision.MeanAveragePrecision for mAP and sv.ConfusionMatrix for confusion matrices. Accumulate predictions and ground-truth Detections, then call compute() to calculate metrics."
|
||||
}
|
||||
},
|
||||
{
|
||||
"@type": "Question",
|
||||
"name": "Is Supervision free to use?",
|
||||
"acceptedAnswer": {
|
||||
"@type": "Answer",
|
||||
"text": "Yes. Supervision is free and open source under the MIT license."
|
||||
}
|
||||
},
|
||||
{
|
||||
"@type": "Question",
|
||||
"name": "Where is the source code?",
|
||||
"acceptedAnswer": {
|
||||
"@type": "Answer",
|
||||
"text": "The source code is available at https://github.com/roboflow/supervision."
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
</script>
|
||||
{% endif %}
|
||||
|
||||
{% if page.url == 'about/' or page.url == 'contact/' %}
|
||||
<script type="application/ld+json">
|
||||
{
|
||||
"@context": "https://schema.org",
|
||||
"@type": "{% if page.url == 'contact/' %}ContactPage{% else %}AboutPage{% endif %}",
|
||||
"name": {{ page.title | tojson }},
|
||||
"description": {{ page_description | tojson }},
|
||||
"url": {{ page.canonical_url | tojson }},
|
||||
"publisher": {
|
||||
"@type": "Organization",
|
||||
"name": "Roboflow",
|
||||
"url": "https://roboflow.com"
|
||||
}
|
||||
}
|
||||
</script>
|
||||
{% endif %}
|
||||
|
||||
{% if 'how_to' in page.url %}
|
||||
<script type="application/ld+json">
|
||||
{
|
||||
"@context": "https://schema.org",
|
||||
"@type": "TechArticle",
|
||||
"name": {{ page.title | tojson }},
|
||||
"description": {{ page_description | tojson }},
|
||||
"url": {{ page.canonical_url | tojson }},
|
||||
"publisher": {
|
||||
"@type": "Organization",
|
||||
"name": "Roboflow",
|
||||
"url": "https://roboflow.com"
|
||||
},
|
||||
"author": [
|
||||
{% if _meta.authors is defined %}
|
||||
{% for author in _meta.authors %}
|
||||
{
|
||||
"@type": "Person",
|
||||
"name": {{ author.name | tojson }},
|
||||
"jobTitle": {{ author.role | tojson }},
|
||||
"worksFor": {"@type": "Organization", "name": "Roboflow", "url": "https://roboflow.com"},
|
||||
"sameAs": [{{ author.github | tojson }}]
|
||||
}{% if not loop.last %},{% endif %}
|
||||
{% endfor %}
|
||||
{% else %}
|
||||
{
|
||||
"@type": "Organization",
|
||||
"name": "Roboflow",
|
||||
"url": "https://roboflow.com"
|
||||
}
|
||||
{% endif %}
|
||||
],
|
||||
"mainEntityOfPage": {{ page.canonical_url | tojson }},
|
||||
{% if _meta.date_modified %}
|
||||
"dateModified": {{ _meta.date_modified | string | tojson }},
|
||||
{% endif %}
|
||||
{% if _meta.date_published %}
|
||||
"datePublished": {{ _meta.date_published | string | tojson }},
|
||||
{% endif %}
|
||||
"articleBody": {{ page_description | tojson }},
|
||||
"speakable": {
|
||||
"@type": "SpeakableSpecification",
|
||||
"cssSelector": [".md-content h1", ".md-content h2", ".md-typeset > p"]
|
||||
}
|
||||
}
|
||||
</script>
|
||||
{% endif %}
|
||||
|
||||
{# ── How-to FAQ schema ─────────────────────────────────────── #}
|
||||
{% if 'how_to' in page.url %}
|
||||
<script type="application/ld+json">
|
||||
{
|
||||
"@context": "https://schema.org",
|
||||
"@type": "FAQPage",
|
||||
"mainEntity": [
|
||||
{
|
||||
"@type": "Question",
|
||||
"name": "How do I {{ page.title | striptags | lower }} with supervision?",
|
||||
"acceptedAnswer": {
|
||||
"@type": "Answer",
|
||||
"text": {{ page_description | tojson }}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
</script>
|
||||
{% endif %}
|
||||
|
||||
{% for is_not_home in [not page.is_homepage] %}{% if is_not_home %}
|
||||
<script type="application/ld+json">
|
||||
{
|
||||
"@context": "https://schema.org",
|
||||
"@type": "BreadcrumbList",
|
||||
"itemListElement": [
|
||||
{
|
||||
"@type": "ListItem",
|
||||
"position": 1,
|
||||
"name": "Supervision",
|
||||
"item": {{ config.site_url | d(config.site_url) | tojson }}
|
||||
},
|
||||
{
|
||||
"@type": "ListItem",
|
||||
"position": 2,
|
||||
"name": {{ (page.title | d('Supervision')) | tojson }},
|
||||
"item": {{ (page.canonical_url | d(config.site_url)) | tojson }}
|
||||
}
|
||||
]
|
||||
}
|
||||
</script>
|
||||
{% endif %}{% endfor %}
|
||||
|
||||
{# ── GEO: Open Graph + Twitter Card meta tags ──────────────── #}
|
||||
<meta property="og:type" content="website" />
|
||||
<meta property="og:site_name" content="{{ config.site_name }}" />
|
||||
<meta property="og:title" content="{{ page.title }}" />
|
||||
<meta property="og:description" content="{{ page_description }}" />
|
||||
<meta property="og:url" content="{{ page.canonical_url }}" />
|
||||
<meta property="og:image" content="https://media.roboflow.com/open-source/supervision/rf-supervision-banner.png" />
|
||||
<meta property="og:image:alt" content="Supervision computer vision Python library by Roboflow" />
|
||||
<meta property="og:image:width" content="1200" />
|
||||
<meta property="og:image:height" content="630" />
|
||||
<meta name="twitter:card" content="summary_large_image" />
|
||||
<meta name="twitter:site" content="@roboflow" />
|
||||
<meta name="twitter:creator" content="@roboflow" />
|
||||
<meta name="twitter:title" content="{{ page.title }}" />
|
||||
<meta name="twitter:description" content="{{ page_description }}" />
|
||||
<meta name="twitter:image" content="https://media.roboflow.com/open-source/supervision/rf-supervision-banner.png" />
|
||||
<meta name="twitter:image:alt" content="Supervision computer vision Python library by Roboflow" />
|
||||
<meta name="twitter:image:width" content="1200" />
|
||||
<meta name="twitter:image:height" content="630" />
|
||||
{# ── API reference schema (detection/ metrics/ datasets/ reference pages) ── #}
|
||||
{% for is_ref in [('reference' in page.url or 'detection/' in page.url or 'metrics/' in page.url or 'keypoint/' in page.url or 'classification/' in page.url) and 'how_to' not in page.url] %}{% if is_ref %}
|
||||
<script type="application/ld+json">
|
||||
{
|
||||
"@context": "https://schema.org",
|
||||
"@type": "TechArticle",
|
||||
"additionalType": "https://schema.org/DocumentationPage",
|
||||
"name": {{ page.title | tojson }},
|
||||
"description": {{ page_description | tojson }},
|
||||
"url": {{ page.canonical_url | tojson }},
|
||||
"mainEntityOfPage": {{ page.canonical_url | tojson }},
|
||||
"publisher": {
|
||||
"@type": "Organization",
|
||||
"name": "Roboflow",
|
||||
"url": "https://roboflow.com"
|
||||
},
|
||||
"codeRepository": "https://github.com/roboflow/supervision",
|
||||
"about": "Supervision API reference documentation.",
|
||||
"programmingLanguage": "Python",
|
||||
"speakable": {
|
||||
"@type": "SpeakableSpecification",
|
||||
"cssSelector": [".md-content h1", ".md-content h2", ".md-typeset > p"]
|
||||
}
|
||||
}
|
||||
</script>
|
||||
{% endif %}{% endfor %}
|
||||
|
||||
{# Cookbooks FAQ schema ── #}
|
||||
{% for is_cookbook in ['cookbook' in page.url] %}{% if is_cookbook %}
|
||||
<script type="application/ld+json">
|
||||
{
|
||||
"@context": "https://schema.org",
|
||||
"@type": "FAQPage",
|
||||
"mainEntity": [
|
||||
{
|
||||
"@type": "Question",
|
||||
"name": "What computer vision tutorials does supervision offer?",
|
||||
"acceptedAnswer": {
|
||||
"@type": "Answer",
|
||||
"text": "Supervision provides cookbooks for object tracking, zero-shot detection with YOLO-World, small object detection with SAHI-style slicing, occupancy analytics, and line-crossing counts."
|
||||
}
|
||||
},
|
||||
{
|
||||
"@type": "Question",
|
||||
"name": "How do I track objects in video with supervision?",
|
||||
"acceptedAnswer": {
|
||||
"@type": "Answer",
|
||||
"text": "Assign persistent tracker IDs before visualizing trajectories. The built-in sv.ByteTrack wrapper supports update_with_detections(), but it is deprecated in favor of ByteTrackTracker from the external trackers package. Combine tracked Detections with sv.TraceAnnotator. See the Object Tracking cookbook."
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
</script>
|
||||
{% endif %}{% endfor %}
|
||||
|
||||
{# IndexNow ownership key — do NOT change this value.
|
||||
The same key must exist in three places (all must stay in sync):
|
||||
1. This meta tag (docs/theme/main.html)
|
||||
2. The key file at docs/0d5d9799b1cc4a39825146388c6781eb.txt
|
||||
3. The CI step in .github/workflows/publish-docs.yml
|
||||
Bing/Yandex verify ownership by fetching https://supervision.roboflow.com/<key>.txt
|
||||
and comparing its contents to this meta tag before accepting IndexNow submissions. #}
|
||||
<meta name="indexnow-key" content="0d5d9799b1cc4a39825146388c6781eb" />
|
||||
|
||||
<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>
|
||||
<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 %}
|
||||
|
||||
Vendored
+181
@@ -0,0 +1,181 @@
|
||||
{% set class = "md-header" %}
|
||||
{% if "navigation.tabs.sticky" in features %}
|
||||
{% set class = class ~ " md-header--shadow md-header--lifted" %}
|
||||
{% elif "navigation.tabs" not in features %}
|
||||
{% set class = class ~ " md-header--shadow" %}
|
||||
{% endif %}
|
||||
|
||||
<!-- Header -->
|
||||
<header class="{{ class }}" data-md-component="header">
|
||||
<nav
|
||||
class="md-header__inner md-grid"
|
||||
aria-label="{{ lang.t('header') }}"
|
||||
>
|
||||
|
||||
<!-- Link to home -->
|
||||
<a
|
||||
href="{{ config.extra.homepage | d(nav.homepage.url, true) | url }}"
|
||||
title="{{ config.site_name | e }}"
|
||||
class="md-header__button md-logo"
|
||||
aria-label="{{ config.site_name }}"
|
||||
data-md-component="logo"
|
||||
>
|
||||
{% include "partials/logo.html" %}
|
||||
</a>
|
||||
|
||||
<!-- Button to open drawer -->
|
||||
<label class="md-header__button md-icon" for="__drawer">
|
||||
{% set icon = config.theme.icon.menu or "material/menu" %}
|
||||
{% include ".icons/" ~ icon ~ ".svg" %}
|
||||
</label>
|
||||
|
||||
<!-- Header title -->
|
||||
<div class="md-header__title" data-md-component="header-title">
|
||||
<div class="md-header__ellipsis">
|
||||
<div class="md-header__topic">
|
||||
<span class="md-ellipsis">
|
||||
{{ config.site_name }} Docs
|
||||
</span>
|
||||
</div>
|
||||
<div class="md-header__topic" data-md-component="header-topic">
|
||||
<span class="md-ellipsis" style="display: flex; align-items: center; gap: 0.5rem;">
|
||||
<a
|
||||
href="{{ config.extra.homepage | d(nav.homepage.url, true) | url }}"
|
||||
title="{{ config.site_name | e }}"
|
||||
class="md-header__button md-logo"
|
||||
aria-label="{{ config.site_name }}"
|
||||
data-md-component="logo"
|
||||
id="item-logo"
|
||||
>
|
||||
{% include "partials/logo.html" %}
|
||||
</a>
|
||||
{% if page.meta and page.meta.title %}
|
||||
{{ page.meta.title }}
|
||||
{% else %}
|
||||
{{ page.title }}
|
||||
{% endif %}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Button to open search modal -->
|
||||
{% if "material/search" in config.plugins %}
|
||||
{% set search = config.plugins["material/search"] | attr("config") %}
|
||||
|
||||
<!-- Check if search is actually enabled - see https://t.ly/DT_0V -->
|
||||
{% if search.enabled %}
|
||||
<label class="md-header__button md-icon" for="__search">
|
||||
{% set icon = config.theme.icon.search or "material/magnify" %}
|
||||
{% include ".icons/" ~ icon ~ ".svg" %}
|
||||
</label>
|
||||
|
||||
<!-- Search interface -->
|
||||
{% include "partials/search.html" %}
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
|
||||
|
||||
<ul class="header-list">
|
||||
<li style="align-items: center;" id="resources-list">
|
||||
<label for="dropdown-resources"><span>Resources <img src="https://ka-p.fontawesome.com/releases/v6.6.0/svgs/regular/chevron-down.svg?v=2&token=a463935e93" style="height: 0.5rem;" /></span></label>
|
||||
<input type="radio" name="dropdown" id="dropdown-resources" style="display: none;" />
|
||||
<ul class="resources-sublist sublist">
|
||||
<li><a href="https://blog.roboflow.com">Blog</a></li>
|
||||
<li><a href="https://discuss.roboflow.com">Community Forum</a></li>
|
||||
<li><a href="https://roboflow.com/sales">Contact Sales</a></li>
|
||||
<li><a href="https://universe.roboflow.com">Universe</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<li style="align-items: center;" id="products-list">
|
||||
<label for="dropdown-products"><span>Docs <img src="https://ka-p.fontawesome.com/releases/v6.6.0/svgs/regular/chevron-down.svg?v=2&token=a463935e93" style="height: 0.5rem;" /></span></label>
|
||||
<input type="radio" name="dropdown" id="dropdown-products" style="display: none;" />
|
||||
<ul class="products-sublist sublist">
|
||||
<li><a href="https://inference.roboflow.com">Inference</a></li>
|
||||
<li><a href="https://supervision.roboflow.com">Supervision</a></li>
|
||||
<li><a href="https://trackers.roboflow.com">Trackers</a></li>
|
||||
<li><a href="https://maestro.roboflow.com">Maestro</a></li>
|
||||
<li><a href="https://docs.roboflow.com">Roboflow</a></li>
|
||||
</ul>
|
||||
</li>
|
||||
<script>
|
||||
document.addEventListener('click', function(event) {
|
||||
const resourcesList = document.getElementById('resources-list');
|
||||
const productsList = document.getElementById('products-list');
|
||||
const dropdownResources = document.getElementById('dropdown-resources');
|
||||
const dropdownProducts = document.getElementById('dropdown-products');
|
||||
|
||||
if (!resourcesList.contains(event.target)) {
|
||||
dropdownResources.checked = false;
|
||||
}
|
||||
if (!productsList.contains(event.target)) {
|
||||
dropdownProducts.checked = false;
|
||||
}
|
||||
});
|
||||
// on mouse over
|
||||
document.getElementById('resources-list').addEventListener('mouseover', function() {
|
||||
document.getElementById('dropdown-resources').checked = true;
|
||||
});
|
||||
document.getElementById('products-list').addEventListener('mouseover', function() {
|
||||
document.getElementById('dropdown-products').checked = true;
|
||||
});
|
||||
// on mouse out
|
||||
document.getElementById('resources-list').addEventListener('mouseout', function() {
|
||||
// if not hovering over the sublist or the label, uncheck the dropdown
|
||||
// wait 1 sec
|
||||
setTimeout(function() {
|
||||
if (!document.querySelector('.resources-sublist:hover') && !document.querySelector('#resources-list:hover')) {
|
||||
document.getElementById('dropdown-resources').checked = false;
|
||||
}
|
||||
}, 350);
|
||||
});
|
||||
// if mouseout of sublist, uncheck immediately
|
||||
document.querySelector('.resources-sublist').addEventListener('mouseout', function() {
|
||||
setTimeout(function() {
|
||||
if (!document.querySelector('.resources-sublist:hover') && !document.querySelector('#resources-list:hover')) {
|
||||
document.getElementById('dropdown-resources').checked = false;
|
||||
}
|
||||
}, 450);
|
||||
});
|
||||
document.getElementById('products-list').addEventListener('mouseout', function() {
|
||||
// if not hovering over the sublist, uncheck the dropdown
|
||||
// wait 1 sec
|
||||
setTimeout(function() {
|
||||
if (!document.querySelector('.products-sublist:hover') && !document.querySelector('#products-list:hover')) {
|
||||
document.getElementById('dropdown-products').checked = false;
|
||||
}
|
||||
}, 500);
|
||||
});
|
||||
// if mouseout of sublist, uncheck immediately
|
||||
document.querySelector('.products-sublist').addEventListener('mouseout', function() {
|
||||
setTimeout(function() {
|
||||
if (!document.querySelector('.products-sublist:hover') && !document.querySelector('#products-list:hover')) {
|
||||
document.getElementById('dropdown-products').checked = false;
|
||||
}
|
||||
}, 500);
|
||||
});
|
||||
|
||||
</script>
|
||||
<style>
|
||||
#dropdown-resources:checked ~ .resources-sublist {
|
||||
display: block;
|
||||
}
|
||||
#dropdown-products:checked ~ .products-sublist {
|
||||
display: block;
|
||||
}
|
||||
/* Hide dropdown if clicking outside */
|
||||
body:not(:has(#dropdown-resources:checked)) .resources-sublist,
|
||||
body:not(:has(#dropdown-products:checked)) .products-sublist {
|
||||
display: none;
|
||||
}
|
||||
</style>
|
||||
<a href="https://github.com/roboflow/supervision"><li class="header-btn" style="border-radius: 5px; color: white; background: var(--md-typeset-a-color); padding-top: 0.25rem; padding-left: 0.5rem; padding-bottom: 0.25rem; padding-right: 0.5rem; border: 1px solid #8315F9;">Go to GitHub</li></a>
|
||||
</ul>
|
||||
</nav>
|
||||
|
||||
<!-- Navigation tabs (sticky) -->
|
||||
{% if "navigation.tabs.sticky" in features %}
|
||||
{% if "navigation.tabs" in features %}
|
||||
{% include "partials/tabs.html" %}
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
</header>
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
---
|
||||
comments: true
|
||||
status: new
|
||||
description: API reference for supervision's object trackers — ByteTrack and SORT implementations that assign persistent IDs across video frames.
|
||||
---
|
||||
|
||||
# ByteTrack
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user