Getting Detections in Python Pipeline for deepstream-tracker-3d-multi-view

Please provide complete information as applicable to your setup.

• Hardware Platform (Jetson / GPU)
• DeepStream Version
• JetPack Version (valid for Jetson only)
• TensorRT Version
• NVIDIA GPU Driver Version (valid for GPU only)
• Issue Type( questions, new requirements, bugs)
• How to reproduce the issue ? (This is for bugs. Including which sample app is using, the configuration files content, the command line used and other details for reproducing)
**• Requirement details( This is for new requirement. Including the module name-for which plugin or for which sample application, the function description)

**
working with the deepstream-tracker-3d-multi-view reference application and need to migrate from the existing C++ MQTT-based approach to a Python pipeline.

Currently, the reference application sends detection data via MQTT using C++ implementation. However, I want to:

  1. Create a Python-based DeepStream pipeline using the Python bindings (pyds)

  2. Extract detection/tracking data using probe functions

Access the 3D tracking metadata (3D bounding boxes, world coordinatesCurrent Issue

What I’m Currently Getting:

  • 2D bounding box coordinates (obj_meta.rect_params) - ✅ Working

  • Object IDs (obj_meta.object_id) - ✅ Working per camera

  • Class IDs and confidence scores - ✅ Working

The Problem:

  • Different Object IDs for the same person across different cameras

    • Camera 0: Person tracked with ID 5

    • Camera 1: Same person tracked with ID 12

    • Camera 2: Same person tracked with ID 8

    • These should be the same cross-camera ID for multi-view tracking

What I Need:

  • Cross-camera associated IDs - Same ID for same person across all camera views

  • How to access the multi-view tracking metadata that links objects across cameras

def tracker_src_pad_probe(pad, info, u_data):
gst_buffer = info.get_buffer()
if not gst_buffer:
return Gst.PadProbeReturn.OK

batch_meta = pyds.gst_buffer_get_nvds_batch_meta(hash(gst_buffer))
l_frame = batch_meta.frame_meta_list

while l_frame is not None:
    try:
        frame_meta = pyds.NvDsFrameMeta.cast(l_frame.data)
    except StopIteration:
        break
    
    source_id = frame_meta.source_id
    l_obj = frame_meta.obj_meta_list
    
    while l_obj is not None:
        try:
            obj_meta = pyds.NvDsObjectMeta.cast(l_obj.data)
            
            # Extract object parameters
            obj_id = obj_meta.object_id
            class_id = obj_meta.class_id
            confidence = obj_meta.confidence
            
            # Extract bounding box
            x = obj_meta.rect_params.left
            y = obj_meta.rect_params.top
            w = obj_meta.rect_params.width
            h = obj_meta.rect_params.height
            
            print(f"Camera {source_id}: ID={obj_id}, Class={class_id}, "
                  f"Bbox=({x:.0f},{y:.0f},{w:.0f},{h:.0f})")
            
            # ❓ PROBLEM: obj_id is different for same person in different cameras
            # How to get cross-camera associated ID for multi-view tracking?
            
        except StopIteration:
            break
        try:
            l_obj = l_obj.next
        except StopIteration:
            break
    
    try:
        l_frame = l_frame.next
    except StopIteration:
        break

return Gst.PadProbeReturn.OK

To access the 3D bounding box, you need to add a Python binding for NvDsObj3DBbox. Then access the usermeta of type NVDS_OBJ_3D_META.

Please refer to this guide.

I tested the 3D tracker using Python and it ran successfully. My pipeline is…

... nvstreammux --> nvinfer (with PeopleNetTransformer model) --> nvtracker (with BodyPose3DNet model) --> nvdsosd --> ....

Some directions for debugging

  1. Ensure that the source and camera calibration data match. Such as Warehouse_Synthetic_Cam00x.yml in config_tracker.yml match with nvstreammux source id
    2.Ensure the Communicator is configured correctly. The tracker will use MQTT to exchange data from different cameras to achieve MTMC.
Communicator:
  communicatorType: 2
  pubSubInfoConfigPath: xxxxx/experiments/deepstream/4cam/pub_sub_info_config_0.yml
  mqttProtoAdaptorConfigPath: xxxx/experiments/deepstream/4cam/config_mqtt.txt

Refer to this documentation.

Can you share a working sample code for reading 3D bounding box metadata (NVDS_OBJ_3D_META) in a Python probe? I want to use it as a reference…

diff --git a/bindings/src/bindnvdsmeta.cpp b/bindings/src/bindnvdsmeta.cpp
index a69be03..5c0da3f 100644
--- a/bindings/src/bindnvdsmeta.cpp
+++ b/bindings/src/bindnvdsmeta.cpp
@@ -71,6 +71,7 @@ namespace pydeepstream {
                 .value("NVDS_TRACKER_OBJ_REID_META",
                        NVDS_TRACKER_OBJ_REID_META,
                        pydsdoc::nvmeta::MetaTypeDoc::NVDS_TRACKER_OBJ_REID_META)
+                .value("NVDS_OBJ_3D_META", NVDS_OBJ_3D_META)
                 .value("NVDS_AUDIO_BATCH_META", NVDS_AUDIO_BATCH_META,
                        pydsdoc::nvmeta::MetaTypeDoc::NVDS_AUDIO_BATCH_META)
                 .value("NVDS_AUDIO_FRAME_META", NVDS_AUDIO_FRAME_META,
diff --git a/bindings/src/bindtrackermeta.cpp b/bindings/src/bindtrackermeta.cpp
index 3c0f990..1745376 100644
--- a/bindings/src/bindtrackermeta.cpp
+++ b/bindings/src/bindtrackermeta.cpp
@@ -134,6 +134,29 @@ namespace pydeepstream {
                      },
                      py::return_value_policy::reference,
                      pydsdoc::trackerdoc::NvDsObjReidDoc::cast);
+
+       py::class_<NvDsObj3DBbox>(m, "NvDsObj3DBbox")
+                .def(py::init<>())
+                .def_readwrite("xCentre", &NvDsObj3DBbox::xCentre)
+                .def_readwrite("yCentre", &NvDsObj3DBbox::yCentre)
+                .def_readwrite("zCentre", &NvDsObj3DBbox::zCentre)
+                /* 3D bbox dimensions */
+                .def_readwrite("xLen", &NvDsObj3DBbox::xLen)
+                .def_readwrite("yLen", &NvDsObj3DBbox::yLen)
+                .def_readwrite("zLen", &NvDsObj3DBbox::zLen)
+                /* 3D bbox rotation */
+                .def_readwrite("xRot", &NvDsObj3DBbox::xRot)
+                .def_readwrite("yRot", &NvDsObj3DBbox::yRot)
+                .def_readwrite("zRot", &NvDsObj3DBbox::zRot)
+                /* 3D bbox velocity */
+                .def_readwrite("xVel", &NvDsObj3DBbox::xVel)
+                .def_readwrite("yVel", &NvDsObj3DBbox::yVel)
+                .def_readwrite("zVel", &NvDsObj3DBbox::zVel)
+                .def("cast",
+                     [](void *data) {
+                         return (NvDsObj3DBbox *) data;
+                     },
+                     py::return_value_policy::reference);
     }
 
 }
cd deepstream_python_apps/bindings
 python -m build

For application

while l_obj is not None:
            try: 
                # Casting l_obj.data to pyds.NvDsObjectMeta
                obj_meta=pyds.NvDsObjectMeta.cast(l_obj.data)
            except StopIteration:
                break
            l_user_meta = obj_meta.obj_user_meta_list
            while l_user_meta is not None:
                try:
                    user_meta = pyds.NvDsUserMeta.cast(l_user_meta.data)
                except StopIteration:
                    break
                if user_meta.base_meta.meta_type == pyds.NvDsMetaType.NVDS_OBJ_3D_META:
                    three_d_bbox = pyds.NvDsObj3DBbox.cast(user_meta.user_meta_data)
                    print(f"3D BBox for {frame_meta.source_id} frame number {frame_number} object id {obj_meta.object_id} : {three_d_bbox.xCentre}, {three_d_bbox.yCentre}, {three_d_bbox.zCentre}, {three_d_bbox.xLen}, {three_d_bbox.yLen}, {three_d_bbox.zLen}")
                try:
                    l_user_meta=l_user_meta.next
                except StopIteration:
                    break
            try:
                l_obj=l_obj.next
            except StopIteration:
                break

I was able to extract the 3D bounding boxes successfully after adding the Python bindings for NvDsObj3DBbox as suggested.

Now I’m facing one issue:

The tracking IDs are not consistent across multiple camera streams.
The same object (e.g., a person or vehicle) is visible in two cameras, but DeepStream assigns different IDs in each stream. I expected the same object to have a unified ID across all cameras, especially since the 3D world coordinates are available.

Please refer to the above prompts for debugging. This is a issue with your configuration or code, and I can only offer limited assistance.

test-pipeline.txt (13.9 KB)

I attached my DeepStream pipeline code — I’m creating all source bins normally but inside Docker the MQTT broker on port 1884 shows continuous rapid connect/disconnect loops. Can someone help identify what might be causing these repeated disconnects?

This issue is related to your device. Try adding the following parameter when recreate container, or restart the host.

--network host --privileged

I am using MV3DTracker with 2 input streams and I want to understand the behaviour of the ReID model.

is MV3DTracker use a ReID network to improve identity consistency. I enabled the ReID section in the tracker config and added the ReID model (as per the sample config). The tracker runs correctly, but I am not observing any visible difference in tracking or ID consistency after enabling ReID.

My questions:

  1. Does MV3DTracker actually use the ReID model for ID reassignment, or does it primarily use global 3D coordinates and trajectory smoothing for multi-stream association?

  2. If ReID is enabled, does MV3DTracker combine:

    • appearance similarity (ReID embedding),

    • global coordinates,

    • velocity/trajectory,
      for ID matching?
      Or is the ReID module optional and only used in specific pipeline configurations?

  3. I attached my tracker config file below.
    Could you please tell me if any parameters need to be changed for the ReID model to actually be used?

    config_tracker.txt (5.5 KB)

This deployment question has been closed. Please open a new topic about MV3DTracker algorithm. @koti067