Comments (14)
... which reminds me, it'd be nice to have an
export
method forDetections
. Particularly for mergedDetections
for a video, I'd like to export the detection data to a text file in the usual YOLO format. I have an "unauthorised" one for my own needs, but I'm sure it'd be useful for things like model-assisted labelling etc.
That one is definitely something I'd like to add. Could you create a separate issue (feature request) for that? 🙏🏻
from supervision.
@zburq Would it be possible that you to create a reproducible example resulting in that ValueError: tracker_id must be None or 1d np.ndarray with (n,) shape
error? I would like to understand what is happening here. I think it is a bug.
from supervision.
Yes - this works too. But feels slightly counterintuitive to me. Ideally, I'd expect empty to conform to any non-empty thing that merges with it, no?
First of all. In my mind, there is a difference between empty detection - where we expect, for example, masks, but we didn't find any and cases where we don't expect masks at all. But I know that complicates things... The alternative is that Detections.merge
and other methods that take Detections
as an argument handle that internally. That will be harder to implement but easier for users.
As for extending Detections
with your own fields, you can do it like with any other Python class, but I personally hate inheritance. And I think creating separate Detections
objects is a cleaner solution.
from supervision.
@zburq I assume that other Detections
have tracker_id
that is not None
. And that information is lost after merge
?
from supervision.
@SkalskiP , yes have a tracker_id is not None
condition in the loop, and can print each tracker_id
.
from supervision.
@SkalskiP , I tried adding an empty np.ndarray
to my det_initial = Detections.empty()
:
det_initial = Detections.empty()
det_initial.tracker_id = np.empty(shape, dtype=np.int64)
but this failed a validation.
For now I have a hacky workaround:
dets_all = None
for det in ...:
if dets_all is None:
dets_all = det
else:
dets_all = Detections.merge([dets_all, det])
from supervision.
What do you mean by but this failed a validation
? Could you share the error?
from supervision.
Yes certainly.
I instantiate an empty Detections
object with the intention of appending other detection objects to it using Detections.merge
.
dets_all = Detections.empty()
dets_all.tracker_id = np.ndarray([])
I also tried dets_all.tracker_id = np.empty_like([0])
.
Next, I generate a sequence of detections from a YOLO V8
output object:
results = volo_v8_model.track(source=my_vid.mp4,
tracker='bytetrack.yaml',
stream=True,
classes=
for result in results:
dets = Detections.from_yolov8(result)
if result.boxes.id is not None:
dets.tracker_id = result.boxes.id.cpu().numpy().astype(int)
dets_all = Detections.merge([dets_all, dets])
At the first call of merge
, i.e., Detections.merge([empty_det, non_empty_det])
, I get this error from merge
:
---> 33 dets_all = Detections.merge([dets_all, det])
34 print(dets_all.tracker_id)
35
/tmp/ipykernel_32267/3054824891.py in concat_detections(detections_list)
36 tracker_id = np.hstack(tracker_id) if all_not_none(tracker_id) else None
37
---> 38 return Detections(
39 xyxy=xyxy,
40 mask=mask,
~/anaconda3/envs/cvc_env/lib/python3.9/site-packages/supervision/detection/core.py in __init__(self, xyxy, mask, confidence, class_id, tracker_id)
~/anaconda3/envs/cvc_env/lib/python3.9/site-packages/supervision/detection/core.py in __post_init__(self)
72 _validate_class_id(class_id=self.class_id, n=n)
73 _validate_confidence(confidence=self.confidence, n=n)
---> 74 _validate_tracker_id(tracker_id=self.tracker_id, n=n)
75
76 def __len__(self):
~/anaconda3/envs/cvc_env/lib/python3.9/site-packages/supervision/detection/core.py in _validate_tracker_id(tracker_id, n)
45 )
46 if not is_valid:
---> 47 raise ValueError("tracker_id must be None or 1d np.ndarray with (n,) shape")
48
49
ValueError: tracker_id must be None or 1d np.ndarray with (n,) shape
from supervision.
Hi @SkalskiP - apologies, I got preoccupied with another aspect of the project. I made a fix to my local copy of supervision and got it working. The bug is in Detections.empty()
:
Here's a working example:
det = Detections(xyxy=np.array([[146.8, 69.878, 198.65, 107.57],
[652.06, 81.007, 710.15, 122.01]], dtype=np.float32),
mask=None,
confidence=np.array([0.83976, 0.82391], dtype=np.float32),
class_id=np.array([2, 2]),
tracker_id=np.array([1, 2]))
e = Detections.empty()
e
prints out like this:
Detections(xyxy=array([], shape=(0, 4), dtype=float32),
mask=None, confidence=array([], dtype=float32),
class_id=array([], dtype=int64),
tracker_id=None)
Detections.merge([e, det])
returns
Detections(xyxy=array([[146.8, 69.878, 198.65, 107.57],
[652.06, 81.007, 710.15, 122.01]], dtype=float32),
mask=None,
confidence=array([0.83976, 0.82391], dtype=float32),
class_id=array([2, 2]),
tracker_id=None)
tracker_id
has gone missing.
But if I modify e
as:
e = Detections.empty()
e.tracker_id = np.array([], dtype=np.int64)
then Detections.merge([e, det])
keeps the tracker_id
:
from supervision.
I made a temporary fix for immediate needs:
from supervision.
Hi, @zburq 👋🏻! That's what I suspected. The problem was the interaction between Detections.empty
and Detections.merge
. My proposed solution would be to introduce additional arguments Detections.empty
. This way, you could create an empty class according to your needs. Does it look reasonable?
@classmethod
def empty(
cls,
with_confidence: bool = False,
with_class_id: bool = False,
with_tracker_id: bool = False,
with_mask_wh: Optional[Tuple[int, int]] = None
) -> Detections:
xyxy = np.empty((0, 4), dtype=np.float32)
confidence = np.array([], dtype=np.float32) if with_confidence else None
class_id = np.array([], dtype=int) if with_class_id else None
tracker_id = np.array([], dtype=int) if with_tracker_id else None
mask = None
if with_mask_wh:
w, h = with_mask_wh
mask = np.empty((0, w, h), dtype=bool)
return cls(
xyxy=xyxy,
confidence=confidence,
class_id=class_id,
tracker_id=tracker_id,
mask=mask
)
from supervision.
Yes - this works too. But feels slightly counterintuitive to me. Ideally, I'd expect empty
to conform to any non-empty thing that merges with it, no?
The reason this would be desirable for me is that sometimes I want to extend Detections
and add some more attributes on the fly. For example, if I call two models simultaneously (champion vs challenger), and want to store two class_id
and confidence
values for each box, (eg. YOLO_class_id
& CLIP_class_id
etc).
For now, I'm creating two seperate Detection
objects, YOLO_det = sv.Detections()
and CLIP_det = sv.Detections()
. I'm running YOLO V8 on a video, storing results in YOLO_det
, then calling CLIP on the cropped bounding boxes, and storing CLIP's output in aCLIP_det
.
But would still like to add frame_id
. This is so that I can save the bounding boxes and classes in text files like this: YOLO export , and then open it in CVAT and have someone manually check/correct the model's work (I'm starting with an unlabelled video).
Again, this is a patch based on my immediate needs. For optimal general design, I trust your judgement.
🖖
from supervision.
... which reminds me, it'd be nice to have an export
method for Detections
. Particularly for merged Detections
for a video, I'd like to export the detection data to a text file in the usual YOLO format. I have an "unauthorised" one for my own needs, but I'm sure it'd be useful for things like model-assisted labelling etc.
from supervision.
Makes sense. Thank you.
from supervision.
Related Issues (20)
- [Detections] extend `from_transformers` with segmentation models support HOT 8
- [Detections] extend `from_transformers` with `class_names` support HOT 4
- [ByteTrack] add `minimum_consecutive_frames` to limit the number of falsely assigned tracker IDs HOT 3
- How can I improve the visibility and behavior of the heatmap color changes in the HeatMapAnnotator class when dealing with a narrow range of heat values? HOT 1
- DetectionDataset.from_yolo bad conversion with autodistill_grounded_sam DetectionDataset object HOT 7
- sv.Detections.from_transformers expects different dict-properties HOT 1
- Detections _get_item_() does not handle index arrays of booleans correctly for data dictionary in Detections object. HOT 3
- Where does the processed video gets saved? HOT 1
- Add support for limiting the number of instances in a video HOT 3
- The line is not being displayed HOT 1
- Bug during `as_coco()` conversion for segmentation (+ solution)
- Hi @s-madhavan001 👋🏻 All you need is here: https://github.com/roboflow/supervision/tree/develop/examples/time_in_zone HOT 2
- How to add class filter in yolov8 tracker and zone counting HOT 10
- sv.Detections has exactly N of each member, except for `tracker_id`. HOT 3
- [DetectionDataset] - expand `from_yolo` to include support for OBB (Oriented Bounding Boxes) HOT 11
- [PolygonZone] - drop `frame_resolution_wh` requirement HOT 5
- Interpolation error on computing average precision HOT 3
- Update to support new `from_transformers` methods HOT 1
- [DetectionDataset] - extend `from_coco` and `as_coco` with support for masks in RLE format HOT 10
- the result.mp4 cannot be played on the browser HOT 4
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from supervision.