Converting objects detected by gst-darknet model to NvDsObjectMeta

Please provide complete information as applicable to your setup.

• Hardware Platform (Jetson / GPU) :- dGPU
• DeepStream Version :- 6.4

I have a pipeline that looks like this
streammux -> nvvideoconv2 -> caps_filter -> darknet_infer -> nvvidconv -> caps_filter2 ->nvosd -> queue6 -> sink

Darknet infer is the gst-darknet model link.

I refered to deepstream infer meta test sample.

What I want to do is, I want to take the objects detected by gst-darknet and convert them to NvDsObjectMeta.

I have attached following probe function at nvvidconv sink pad.

static GstPadProbeReturn converter_probe(GstPad *pad,
                                         GstPadProbeInfo *info,
                                         gpointer u_data) {
    GstBuffer *buf = (GstBuffer *)info->data;
    
    NvDsBatchMeta *batch_meta =
        gst_buffer_get_nvds_batch_meta(GST_BUFFER(info->data));
    // nvds_acquire_meta_lock(batch_meta);
    g_print("[Attacher Probe]Batch meta : num frames %d \n",
            batch_meta->num_frames_in_batch);

    static const GstMetaInfo *metainfo = NULL;
    if (metainfo == NULL) {
        metainfo = gst_meta_get_info("GstDarknetMetaDetections");
    }
    GstDarknetMetaDetections *meta =
        (GstDarknetMetaDetections *)gst_buffer_get_meta(buf, metainfo->api);

    // detection count is available in the detection_count variable
    // g_print("detections: %d\n", meta->detection_count);
   
    for (NvDsMetaList *l_frame = batch_meta->frame_meta_list; l_frame != NULL;
         l_frame = l_frame->next) {
        NvDsFrameMeta *frame_meta = (NvDsFrameMeta *)l_frame->data;
        //  detections are available in the detections variable
        for (guint i = 0; i < meta->detection_count; i++) {
            GstDarknetMetaDetection *det = &meta->detections[i];
            NvDsObjectMeta *obj_meta =
                nvds_acquire_obj_meta_from_pool(batch_meta);

            obj_meta->unique_component_id =
                0;  // TODO : Figure out a better way to fill this field
            obj_meta->confidence = det->probability;
            obj_meta->object_id =
                UNTRACKED_OBJECT_ID;  
            obj_meta->class_id = det->classid;

            NvOSD_RectParams &rect_params = obj_meta->rect_params;
            NvOSD_TextParams &text_params = obj_meta->text_params;

            /* Assign bounding box coordinates. These can be overwritten if
             * tracker component is present in the pipeline */
            g_print("[Darknet Detection ] [%d %d %d %d ] \n", det->xmin,
                    det->ymin, det->xmax, det->ymax);
            rect_params.left = det->xmin;
            rect_params.top = det->ymin;
            rect_params.width = det->xmax - det->xmin;
            rect_params.height = det->ymax - det->ymin;

            /* Border of width 3. */
            rect_params.border_width = 3;
            rect_params.has_bg_color = 0;
            rect_params.border_color = (NvOSD_ColorParams){1, 0, 0, 1};

            /* display_text requires heap allocated memory. */
            // text_params.display_text;
            /* Display text above the left top corner of the object. */
            text_params.x_offset = rect_params.left;
            text_params.y_offset = rect_params.top - 10;
            /* Set black background for the text. */
            text_params.set_bg_clr = 1;
            text_params.text_bg_clr = (NvOSD_ColorParams){0, 0, 0, 1};
            /* Font face, size and color. */
            text_params.font_params.font_name = (gchar *)"Serif";
            text_params.font_params.font_size = 11;
            text_params.font_params.font_color =
                (NvOSD_ColorParams){1, 1, 1, 1};

            /* Preserve original positional bounding box coordinates of detector
             * in the frame so that those can be accessed after tracker */
            obj_meta->detector_bbox_info.org_bbox_coords.left =
                rect_params.left;
            obj_meta->detector_bbox_info.org_bbox_coords.top = rect_params.top;
            obj_meta->detector_bbox_info.org_bbox_coords.width =
                rect_params.width;
            obj_meta->detector_bbox_info.org_bbox_coords.height =
                rect_params.height;

            nvds_add_obj_meta_to_frame(frame_meta, obj_meta, NULL);
        }
        // nvds_add_frame_meta_to_batch(batch_meta, frame_meta);
    }
    // nvds_release_meta_lock(batch_meta);
    return GST_PAD_PROBE_OK;
}

My problem :- This pipeline streammux -> nvvideoconv2 -> caps_filter -> darknet_infer -> nvvidconv -> caps_filter2 ->nvosd -> queue6 -> sink works fine, I can see bounding boxes being drawn by osd element.

But when I add tracker in the pipeline, streammux -> nvvideoconv2 -> caps_filter -> darknet_infer -> nvvidconv -> caps_filter2 ->nvtracker-> nvosd -> queue6 -> sink , I am not able to convert the gst-darknet detections to NvDsObjectMeta type.

Not using nvinfer may have issues, this has not been tested.

Is there an error log? You can check the code related to nvtracker element first

/opt/nvidia/deepstream/deepstream/sources/gst-plugins/gst-nvtracker

I will share logs with you, there was no “ERROR” as such.

Hey, one more thing, When I add tracker, the object_meta_list becomes empty right after tracker. that is at tracker_src_pad.

Some logs.
I logged the NvDsFrameMeta structure with tracker enabled (post tracker src pad) and tracker disabled.
Without Tracker

===== NvDsFrameMeta Details Without Tracker=====
Base Meta: 0x7a333a291820
Pad Index: 0
Batch ID: 0
Frame Number: 1
Buffer PTS: 33333333
NTP Timestamp: 1733740505059718000
Source ID: 0
Number of Surfaces Per Frame: 1
Source Frame Width: 1280
Source Frame Height: 720
Surface Type: 0
Surface Index: 0
Number of Object Meta: 9
Inference Done: No
Object Meta List: 0x7a333a8a74e0
Display Meta List: 0
Frame User Meta List: 0
Misc Frame Info: 0 0 0 0 
Pipeline Width: 0
Pipeline Height: 0
Reserved: 0 0 0 0 

WIth Tracker

===== NvDsFrameMeta Details with tracker =====
Base Meta: 0x77542c01f440
Pad Index: 0
Batch ID: 0
Frame Number: 1
Buffer PTS: 33333333
NTP Timestamp: 1733740560538723000
Source ID: 0
Number of Surfaces Per Frame: 1
Source Frame Width: 1280
Source Frame Height: 720
Surface Type: 0
Surface Index: 0
Number of Object Meta: 0
Inference Done: No
Object Meta List: 0
Display Meta List: 0
Frame User Meta List: 0
Misc Frame Info: 0 0 0 0 
Pipeline Width: 0
Pipeline Height: 0
Reserved: 0 0 0 0 
Base Meta: 0x733d80ac2c40
Parent Object Meta: 0
Unique Component ID: 1
Class ID: 0
Object ID: 18446744073709551615
Detector BBox Info: 
  x: 282, y: 326, width: 23, height: 63
Tracker BBox Info: 
  x: 0, y: 0, width: 0, height: 0
Confidence: 0.893628
Tracker Confidence: 0
Rectangle Params:
  Top: 326, Left: 282, Width: 23, Height: 63
Mask Params: 0
Text Params: Person
Object Label: 
Classifier Meta List: 0
Object User Meta List: 0
Misc Object Info: 0 0 0 0 
Reserved: 0 0 0 0 ```

This is to show that gst-darknet detected objects were converted to NvDsStructures. 


what other log can I give you?

logs generated wiht GST_DEBUG=5 gst_debug_level_5_logs.txt (22.6 MB)

from the above gst-debug logs, I can see that, tracker is generating a lot of GST_QOS_TYPE_OVERFLOW events.

GST_QOS_TYPE_OVERFLOW (0) –

The QoS event type that is produced when upstream elements are producing data too quickly 
and the element can't keep up processing the data.
Upstream should reduce their production rate. 
This type is also used when buffers arrive early or in time. 

This may be related to the way of adding metadata, refer to the attach_metadata_detector function in /opt/nvidia/deepstream/deepstream/sources/gst-plugins/gst-nvinfer/gstnvinfer_meta_utils.cpp .

Try setting frame_meta->bInferDone = TRUE;

There is no update from you for a period, assuming this is not an issue anymore. Hence we are closing this topic. If need further support, please open a new one. Thanks

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.