Skip to content

Commit 396d218

Browse files
committed
Updated to DeepStream 5.0
1 parent 0a05923 commit 396d218

File tree

2 files changed

+64
-146
lines changed

2 files changed

+64
-146
lines changed

README.md

Lines changed: 35 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,17 @@
22

33
[pybind11](https://github.com/pybind/pybind11) wrapper to access Nvidia [DeepStream](https://developer.nvidia.com/deepstream-sdk) tracker meta info (`NvDsPastFrame...` classes) from Python.
44

5-
This library provides access to the `NvDsPastFrameObjBatch` type user metadata of DeepStream data streams. This metadata is generated by the object tracker of [nvtracker](https://docs.nvidia.com/metropolis/deepstream/dev-guide/#page/DeepStream%20Plugins%20Development%20Guide/deepstream_plugin_details.3.02.html#) plugin. The C API of these structures can be found in [nvds_tracker_meta.h](https://docs.nvidia.com/metropolis/deepstream/dev-guide/DeepStream_Development_Guide/baggage/nvds__tracker__meta_8h.html) header file of DeepStream SDK. The instances of these metadata structure contain information about the object tracking results in past frames.
5+
> The `master` branch of this repository is compatible with DeepStream SDK 5.0. If you are using an earlier version of the SDK (including DeepStrem SDK 5.0 Developer Preview), check out the `DeepStream-4.0` branch.
6+
7+
## Notes for DeepStreamer 5.0
8+
9+
Starting from DeepStream SDK 5.0 the python bindings for `NvDsPastFrame...` classes are included in the official SDK. However some vital functions are missing:
10+
- to cast a generic user metadata to `NvDsPastFrameObjBatch` object
11+
- to correctly iterate through the elements of `list` fields of `NvDsPastFrameObjBatch`, `NvDsPastFrameObjStream` and `NvDsPastFrameObjList`. These fields are standard C arrays in the native SDK, so simply exposing them in python will give access in the best case only the first element of the array. The pointer arithmetic to iterate over the elements is also included in this library.
12+
13+
## Introduction
14+
15+
This library provides utility functions to access to the `NvDsPastFrameObjBatch` type user metadata of DeepStream data streams. This metadata is generated by the object tracker of [nvtracker](https://docs.nvidia.com/metropolis/deepstream/dev-guide/#page/DeepStream%20Plugins%20Development%20Guide/deepstream_plugin_details.3.02.html#) plugin. The C API of these structures can be found in [nvds_tracker_meta.h](https://docs.nvidia.com/metropolis/deepstream/dev-guide/DeepStream_Development_Guide/baggage/nvds__tracker__meta_8h.html) header file of DeepStream SDK. The instances of these metadata structure contain information about the object tracking results in past frames.
616

717
Some trackers do not report the state of the tracked object if there are matching detection results in the current frame. When in a later frame a detection result confirms the state of the tracked object, the past history of the tracking is reported retroactively in `NvDsPastFrame...` metadata. This library provides Python access to this metadata. For more information refer to the [nvtracker](https://docs.nvidia.com/metropolis/deepstream/dev-guide/#page/DeepStream%20Plugins%20Development%20Guide/deepstream_plugin_details.3.02.html#) plugin documentation.
818

@@ -45,33 +55,34 @@ def osd_sink_pad_buffer_probe(pad, info, u_data):
4555
print('user_meta:', user_meta)
4656
print('user_meta.user_meta_data:', user_meta.user_meta_data)
4757
print('user_meta.base_meta:', user_meta.base_meta)
48-
if not pyds_tracker_meta.NvDsPastFrameObjBatch.is_in(user_meta):
58+
59+
if user_meta.base_meta.meta_type != pyds.NvDsMetaType.NVDS_TRACKER_PAST_FRAME_META:
4960
continue
50-
past_frame_object_batch = pyds_tracker_meta.NvDsPastFrameObjBatch.from_user_meta(user_meta)
51-
print('past_frame_object_batch:', past_frame_object_batch)
61+
62+
pfob = pyds_tracker_meta.NvDsPastFrameObjBatch_cast(user_meta.user_meta_data)
63+
print('past_frame_object_batch:', pfob)
5264
print(' list:')
53-
for past_frame_object_stream in past_frame_object_batch.list:
54-
print(' past_frame_object_stream:', past_frame_object_stream)
55-
print(' streamID:', past_frame_object_stream.streamID)
56-
print(' surfaceStreamID:', past_frame_object_stream.surfaceStreamID)
65+
for pfos in pyds_tracker_meta.NvDsPastFrameObjBatch_list(pfob):
66+
print(' past_frame_object_stream:', pfos)
67+
print(' streamID:', pfos.streamID)
68+
print(' surfaceStreamID:', pfos.surfaceStreamID)
5769
print(' list:')
58-
for past_frame_object_list in past_frame_object_stream.list:
59-
print(' past_frame_object_list:', past_frame_object_list)
60-
print(' numObj:', past_frame_object_list.numObj)
61-
print(' uniqueId:', past_frame_object_list.uniqueId)
62-
print(' classId:', past_frame_object_list.classId)
63-
print(' objLabel:', past_frame_object_list.objLabel)
70+
for pfol in pyds_tracker_meta.NvDsPastFrameObjStream_list(pfos):
71+
print(' past_frame_object_list:', pfol)
72+
print(' numObj:', pfol.numObj)
73+
print(' uniqueId:', pfol.uniqueId)
74+
print(' classId:', pfol.classId)
75+
print(' objLabel:', pfol.objLabel)
6476
print(' list:')
65-
for past_frame_object in past_frame_object_list:
66-
print(' past_frame_object:', past_frame_object)
67-
print(' frameNum:', past_frame_object.frameNum)
68-
print(' tBbox.left:', past_frame_object.tBbox.left)
69-
print(' tBbox.width:', past_frame_object.tBbox.width)
70-
print(' tBbox.top:', past_frame_object.tBbox.top)
71-
print(' tBbox.right:', past_frame_object.tBbox.height)
72-
print(' confidence:', past_frame_object.confidence)
73-
print(' age:', past_frame_object.age)
74-
77+
for pfo in pyds_tracker_meta.NvDsPastFrameObjList_list(pfol):
78+
print(' past_frame_object:', pfo)
79+
print(' frameNum:', pfo.frameNum)
80+
print(' tBbox.left:', pfo.tBbox.left)
81+
print(' tBbox.width:', pfo.tBbox.width)
82+
print(' tBbox.top:', pfo.tBbox.top)
83+
print(' tBbox.right:', pfo.tBbox.height)
84+
print(' confidence:', pfo.confidence)
85+
print(' age:', pfo.age)
7586
try:
7687
user_meta_list = user_meta_list.next
7788
except StopIteration:

pyds_tracker_meta.cpp

Lines changed: 29 additions & 122 deletions
Original file line numberDiff line numberDiff line change
@@ -6,128 +6,35 @@ namespace py = pybind11;
66

77
PYBIND11_MODULE(pyds_tracker_meta, m) {
88
m.doc() = "pybind11 wrapper to access Nvidia DeepStream NvDsPastFrame* classes";
9-
10-
py::class_<NvDsPastFrameObjBatch>(m, "NvDsPastFrameObjBatch", "Batch of lists of buffered objects")
11-
12-
// Casting and type check
13-
.def_static(
14-
"cast",
15-
[](void *obj) { return (NvDsPastFrameObjBatch*)(obj); },
16-
"Cast given object/data to pyds_pastframemeta.NvDsPastFrameObjBatch",
17-
py::arg("obj"),
18-
py::return_value_policy::reference)
19-
.def_static(
20-
"from_user_meta",
21-
[](NvDsUserMeta *user_meta) {
22-
NvDsPastFrameObjBatch* obj = nullptr;
23-
if (user_meta && user_meta->base_meta.meta_type == NVDS_TRACKER_PAST_FRAME_META) {
24-
obj = (NvDsPastFrameObjBatch *) (user_meta->user_meta_data);
25-
}
26-
return obj;
27-
},
28-
py::arg("user_meta"),
29-
"If the data contained in the user meta is a NvDsPastFrameObjBatch instance, "
30-
"casts the data and returns it. Otherwise returns NULL.",
31-
py::return_value_policy::reference)
32-
.def_static(
33-
"is_in",
34-
[](NvDsUserMeta *user_meta) {
35-
return (user_meta->base_meta.meta_type == NVDS_TRACKER_PAST_FRAME_META);
36-
},
37-
py::arg("user_meta"),
38-
"Returns true if the user_meta contains a NvDsPastFrameObjBatch instance.")
39-
40-
// Struct members
41-
.def_readonly("numAllocated", &NvDsPastFrameObjBatch::numAllocated, "Number of blocks allocated for the list.")
42-
.def_readonly("numFilled", &NvDsPastFrameObjBatch::numFilled, "Number of filled blocks in the list.")
43-
44-
// list is implemented as a real python iterator
45-
.def_property_readonly(
46-
"list",
47-
[](NvDsPastFrameObjBatch &self) {
48-
return py::make_iterator(self.list, self.list + self.numFilled);
49-
},
50-
py::keep_alive<0, 1>(),
51-
"Iterator of stream lists.")
529

53-
// convenience methods for subscription access, lenght, use the batch directly as an iterator
54-
.def(
55-
"__getitem__",
56-
[](const NvDsPastFrameObjBatch &self, size_t i) {
57-
if (i >= self.numFilled) throw py::index_error();
58-
return self.list[i];
59-
})
60-
.def("__len__", [](const NvDsPastFrameObjBatch &self) { return self.numFilled; })
61-
.def("__iter__",
62-
[](const NvDsPastFrameObjBatch &self) {
63-
return py::make_iterator(self.list, self.list + self.numFilled);
64-
},
65-
py::keep_alive<0, 1>());
66-
67-
68-
py::class_<NvDsPastFrameObjStream>(m, "NvDsPastFrameObjStream", "List of objects in each stream.")
69-
.def_readonly("streamID", &NvDsPastFrameObjStream::streamID, "Stream id the same as frame_meta->pad_index.")
70-
.def_readonly("surfaceStreamID", &NvDsPastFrameObjStream::surfaceStreamID, "Stream id used inside tracker plugin.")
71-
.def_readonly("numAllocated", &NvDsPastFrameObjStream::numAllocated, "Maximum number of objects allocated.")
72-
.def_readonly("numFilled", &NvDsPastFrameObjStream::numFilled, "Number of objects in this frame.")
73-
74-
// list is implemented as a real python iterator
75-
.def_property_readonly(
76-
"list",
77-
[](NvDsPastFrameObjStream &self) { return py::make_iterator(self.list, self.list + self.numFilled); },
78-
py::keep_alive<0, 1>(),
79-
"Iterator of objects inside this stream.")
80-
81-
// convenience methods for subscription access, lenght, use the frame object stream directly as an iterator
82-
.def("__getitem__",
83-
[](const NvDsPastFrameObjStream &self, size_t i) {
84-
if (i >= self.numFilled) throw py::index_error();
85-
return self.list[i];
86-
})
87-
.def("__len__", [](const NvDsPastFrameObjStream &self) { return self.numFilled; })
88-
.def("__iter__",
89-
[](const NvDsPastFrameObjStream &self) {
90-
return py::make_iterator(self.list, self.list + self.numFilled);
91-
},
92-
py::keep_alive<0, 1>());
93-
94-
95-
py::class_<NvDsPastFrameObjList>(m, "NvDsPastFrameObjList", "One object in several past frames")
96-
.def_readonly("uniqueId", &NvDsPastFrameObjList::uniqueId, "Object tracking id.")
97-
.def_readonly("classId", &NvDsPastFrameObjList::classId, "Object class id.")
98-
.def_property_readonly(
99-
"objLabel",
100-
[](NvDsPastFrameObjList *self) {
101-
return std::string(self->objLabel, MAX_LABEL_SIZE);
102-
},
103-
"An array of the string describing the object class.")
104-
.def_readonly("numObj", &NvDsPastFrameObjList::numObj, "Number of frames this object appreared in the past.")
105-
106-
// list is implemented as a real python iterator
107-
.def_property_readonly(
108-
"list",
109-
[](NvDsPastFrameObjList &self) { return py::make_iterator(self.list, self.list + self.numObj); },
110-
py::keep_alive<0, 1>(),
111-
"Iterator of past frame info of this object.")
112-
113-
// convenience methods for subscription access, lenght, use the frame object list directly as an iterator
114-
.def("__getitem__",
115-
[](const NvDsPastFrameObjList &self, size_t i) {
116-
if (i >= self.numObj) throw py::index_error();
117-
return self.list[i];
118-
})
119-
.def("__len__", [](const NvDsPastFrameObjList &self) { return self.numObj; })
120-
.def("__iter__",
121-
[](const NvDsPastFrameObjList &self) {
122-
return py::make_iterator(self.list, self.list + self.numObj);
123-
},
124-
py::keep_alive<0, 1>());
125-
126-
127-
py::class_<NvDsPastFrameObj>(m, "NvDsPastFrameObj")
128-
.def_readonly("frameNum", &NvDsPastFrameObj::frameNum)
129-
.def_readonly("tBbox", &NvDsPastFrameObj::tBbox)
130-
.def_readonly("confidence", &NvDsPastFrameObj::confidence)
131-
.def_readonly("age", &NvDsPastFrameObj::age);
10+
m.def("NvDsPastFrameObjBatch_cast",
11+
[](void *obj) { return (NvDsPastFrameObjBatch*)(obj); },
12+
"Cast given object/data to pyds_pastframemeta.NvDsPastFrameObjBatch",
13+
py::arg("obj"),
14+
py::return_value_policy::reference);
15+
16+
m.def("NvDsPastFrameObjBatch_list",
17+
[](NvDsPastFrameObjBatch &self) {
18+
return py::make_iterator(self.list, self.list + self.numFilled);
19+
},
20+
py::keep_alive<0, 1>(),
21+
"Extracts an iterator of stream lists from the object batch.",
22+
py::arg("obj_batch"));
23+
24+
m.def("NvDsPastFrameObjStream_list",
25+
[](NvDsPastFrameObjStream &self) {
26+
return py::make_iterator(self.list, self.list + self.numFilled);
27+
},
28+
py::keep_alive<0, 1>(),
29+
"Extracts an iterator of objects from an object stream.",
30+
py::arg("obj_stream"));
31+
32+
m.def("NvDsPastFrameObjList_list",
33+
[](NvDsPastFrameObjList &self) {
34+
return py::make_iterator(self.list, self.list + self.numObj);
35+
},
36+
py::keep_alive<0, 1>(),
37+
"Extracts an iterator of past frame objects from this object list.",
38+
py::arg("obj_list"));
13239

13340
}

0 commit comments

Comments
 (0)