Yolov8 Object Detection using Deepstream

Please provide complete information as applicable to your setup.

• Hardware Platform (Jetson / GPU) - Jetson
• DeepStream Version - 7
• JetPack Version (valid for Jetson only) - 6.0-b52
• TensorRT Version - 8.6.2.3

I am working on the deepstream python yolov8 (GitHub - marcoslucianops/DeepStream-Yolo-Face: NVIDIA DeepStream SDK 6.3 / 6.2 / 6.1.1 / 6.1 / 6.0.1 / 6.0 application for YOLO-Face models) code to detect moving object. i am using following model
(yolov8n-face.pt - Google Drive)

the problem is the code detect only persons. i also share my python scripts, config file & model (both .pt & onnx format
model.zip (56.0 MB)
).

i never edit the deepstream.py file. i want to know any change in python and config file.

deepstream.py

import gi
gi.require_version(‘Gst’, ‘1.0’)
from gi.repository import Gst, GLib

import os
import sys
import time
import argparse
import platform
from ctypes import *

sys.path.append(‘/opt/nvidia/deepstream/deepstream-7.0/lib’)
import pyds

MAX_ELEMENTS_IN_DISPLAY_META = 16

SOURCE = ‘’
CONFIG_INFER = ‘’
STREAMMUX_BATCH_SIZE = 1
STREAMMUX_WIDTH = 1920
STREAMMUX_HEIGHT = 1080
GPU_ID = 0
PERF_MEASUREMENT_INTERVAL_SEC = 5

skeleton = [[16, 14], [14, 12], [17, 15], [15, 13], [12, 13], [6, 12], [7, 13], [6, 7], [6, 8], [7, 9], [8, 10], [9, 11],
[2, 3], [1, 2], [1, 3], [2, 4], [3, 5], [4, 6], [5, 7]]

start_time = time.time()
fps_streams = {}

class GETFPS:
def init(self, stream_id):
global start_time
self.start_time = start_time
self.is_first = True
self.frame_count = 0
self.stream_id = stream_id
self.total_fps_time = 0
self.total_frame_count = 0

def get_fps(self):
    end_time = time.time()
    if self.is_first:
        self.start_time = end_time
        self.is_first = False
    current_time = end_time - self.start_time
    if current_time > PERF_MEASUREMENT_INTERVAL_SEC:
        self.total_fps_time = self.total_fps_time + current_time
        self.total_frame_count = self.total_frame_count + self.frame_count
        current_fps = float(self.frame_count) / current_time
        avg_fps = float(self.total_frame_count) / self.total_fps_time
        sys.stdout.write('DEBUG: FPS of stream %d: %.2f (%.2f)\n' % (self.stream_id + 1, current_fps, avg_fps))
        self.start_time = end_time
        self.frame_count = 0
    else:
        self.frame_count = self.frame_count + 1

def set_custom_bbox(obj_meta):
border_width = 6
font_size = 18
x_offset = int(min(STREAMMUX_WIDTH - 1, max(0, obj_meta.rect_params.left - (border_width / 2))))
y_offset = int(min(STREAMMUX_HEIGHT - 1, max(0, obj_meta.rect_params.top - (font_size * 2) + 1)))

obj_meta.rect_params.border_width = border_width
obj_meta.rect_params.border_color.red = 0.0
obj_meta.rect_params.border_color.green = 0.0
obj_meta.rect_params.border_color.blue = 1.0
obj_meta.rect_params.border_color.alpha = 1.0
obj_meta.text_params.font_params.font_name = 'Ubuntu'
obj_meta.text_params.font_params.font_size = font_size
obj_meta.text_params.x_offset = x_offset
obj_meta.text_params.y_offset = y_offset
obj_meta.text_params.font_params.font_color.red = 1.0
obj_meta.text_params.font_params.font_color.green = 1.0
obj_meta.text_params.font_params.font_color.blue = 1.0
obj_meta.text_params.font_params.font_color.alpha = 1.0
obj_meta.text_params.set_bg_clr = 1
obj_meta.text_params.text_bg_clr.red = 0.0
obj_meta.text_params.text_bg_clr.green = 0.0
obj_meta.text_params.text_bg_clr.blue = 1.0
obj_meta.text_params.text_bg_clr.alpha = 1.0

def parse_face_from_meta(frame_meta, obj_meta):
num_joints = int(obj_meta.mask_params.size / (sizeof(c_float) * 3))

gain = min(obj_meta.mask_params.width / STREAMMUX_WIDTH,
           obj_meta.mask_params.height / STREAMMUX_HEIGHT)
pad_x = (obj_meta.mask_params.width - STREAMMUX_WIDTH * gain) / 2.0
pad_y = (obj_meta.mask_params.height - STREAMMUX_HEIGHT * gain) / 2.0

batch_meta = frame_meta.base_meta.batch_meta
display_meta = pyds.nvds_acquire_display_meta_from_pool(batch_meta)
pyds.nvds_add_display_meta_to_frame(frame_meta, display_meta)

for i in range(num_joints):
    data = obj_meta.mask_params.get_mask_array()
    xc = int((data[i * 3 + 0] - pad_x) / gain)
    yc = int((data[i * 3 + 1] - pad_y) / gain)
    confidence = data[i * 3 + 2]

    if confidence < 0.5:
        continue

    if display_meta.num_circles == MAX_ELEMENTS_IN_DISPLAY_META:
        display_meta = pyds.nvds_acquire_display_meta_from_pool(batch_meta)
        pyds.nvds_add_display_meta_to_frame(frame_meta, display_meta)

    circle_params = display_meta.circle_params[display_meta.num_circles]
    circle_params.xc = xc
    circle_params.yc = yc
    circle_params.radius = 6
    circle_params.circle_color.red = 1.0
    circle_params.circle_color.green = 1.0
    circle_params.circle_color.blue = 1.0
    circle_params.circle_color.alpha = 1.0
    circle_params.has_bg_color = 1
    circle_params.bg_color.red = 0.0
    circle_params.bg_color.green = 0.0
    circle_params.bg_color.blue = 1.0
    circle_params.bg_color.alpha = 1.0
    display_meta.num_circles += 1

def tracker_src_pad_buffer_probe(pad, info, user_data):
buf = info.get_buffer()
batch_meta = pyds.gst_buffer_get_nvds_batch_meta(hash(buf))

l_frame = batch_meta.frame_meta_list
while l_frame:
    try:
        frame_meta = pyds.NvDsFrameMeta.cast(l_frame.data)
    except StopIteration:
        break

    current_index = frame_meta.source_id

    l_obj = frame_meta.obj_meta_list
    while l_obj:
        try:
            obj_meta = pyds.NvDsObjectMeta.cast(l_obj.data)
        except StopIteration:
            break

        parse_face_from_meta(frame_meta, obj_meta)
        set_custom_bbox(obj_meta)

        try:
            l_obj = l_obj.next
        except StopIteration:
            break

    fps_streams['stream{0}'.format(current_index)].get_fps()

    try:
        l_frame = l_frame.next
    except StopIteration:
        break

return Gst.PadProbeReturn.OK

def decodebin_child_added(child_proxy, Object, name, user_data):
if name.find(‘decodebin’) != -1:
Object.connect(‘child-added’, decodebin_child_added, user_data)
if name.find(‘nvv4l2decoder’) != -1:
Object.set_property(‘drop-frame-interval’, 0)
Object.set_property(‘num-extra-surfaces’, 1)
if is_aarch64():
Object.set_property(‘enable-max-performance’, 1)
else:
Object.set_property(‘cudadec-memtype’, 0)
Object.set_property(‘gpu-id’, GPU_ID)

def cb_newpad(decodebin, pad, user_data):
streammux_sink_pad = user_data
caps = pad.get_current_caps()
if not caps:
caps = pad.query_caps()
structure = caps.get_structure(0)
name = structure.get_name()
features = caps.get_features(0)
if name.find(‘video’) != -1:
if features.contains(‘memory:NVMM’):
if pad.link(streammux_sink_pad) != Gst.PadLinkReturn.OK:
sys.stderr.write(‘ERROR: Failed to link source to streammux sink pad\n’)
else:
sys.stderr.write(‘ERROR: decodebin did not pick NVIDIA decoder plugin’)

def create_uridecode_bin(stream_id, uri, streammux):
bin_name = ‘source-bin-%04d’ % stream_id
bin = Gst.ElementFactory.make(‘uridecodebin’, bin_name)
if ‘rtsp://’ in uri:
pyds.configure_source_for_ntp_sync(bin)
bin.set_property(‘uri’, uri)
pad_name = ‘sink_%u’ % stream_id
streammux_sink_pad = streammux.get_request_pad(pad_name)
bin.connect(‘pad-added’, cb_newpad, streammux_sink_pad)
bin.connect(‘child-added’, decodebin_child_added, 0)
fps_streams[‘stream{0}’.format(stream_id)] = GETFPS(stream_id)
return bin

def bus_call(bus, message, user_data):
loop = user_data
t = message.type
if t == Gst.MessageType.EOS:
sys.stdout.write(‘DEBUG: EOS\n’)
loop.quit()
elif t == Gst.MessageType.WARNING:
err, debug = message.parse_warning()
sys.stderr.write(‘WARNING: %s: %s\n’ % (err, debug))
elif t == Gst.MessageType.ERROR:
err, debug = message.parse_error()
sys.stderr.write(‘ERROR: %s: %s\n’ % (err, debug))
loop.quit()
return True

def is_aarch64():
return platform.uname()[4] == ‘aarch64’

def main():
Gst.init(None)

loop = GLib.MainLoop()

pipeline = Gst.Pipeline()
if not pipeline:
    sys.stderr.write('ERROR: Failed to create pipeline\n')
    sys.exit(1)

streammux = Gst.ElementFactory.make('nvstreammux', 'nvstreammux')
if not streammux:
    sys.stderr.write('ERROR: Failed to create nvstreammux\n')
    sys.exit(1)
pipeline.add(streammux)

source_bin = create_uridecode_bin(0, SOURCE, streammux)
if not source_bin:
    sys.stderr.write('ERROR: Failed to create source_bin\n')
    sys.exit(1)
pipeline.add(source_bin)

pgie = Gst.ElementFactory.make('nvinfer', 'pgie')
if not pgie:
    sys.stderr.write('ERROR: Failed to create nvinfer\n')
    sys.exit(1)

tracker = Gst.ElementFactory.make('nvtracker', 'nvtracker')
if not tracker:
    sys.stderr.write('ERROR: Failed to create nvtracker\n')
    sys.exit(1)

converter = Gst.ElementFactory.make('nvvideoconvert', 'nvvideoconvert')
if not converter:
    sys.stderr.write('ERROR: Failed to create nvvideoconvert\n')
    sys.exit(1)

osd = Gst.ElementFactory.make('nvdsosd', 'nvdsosd')
if not osd:
    sys.stderr.write('ERROR: Failed to create nvdsosd\n')
    sys.exit(1)

sink = None
if is_aarch64():
    sink = Gst.ElementFactory.make('nv3dsink', 'nv3dsink')
    if not sink:
        sys.stderr.write('ERROR: Failed to create nv3dsink\n')
        sys.exit(1)
else:
    sink = Gst.ElementFactory.make('nveglglessink', 'nveglglessink')
    if not sink:
        sys.stderr.write('ERROR: Failed to create nveglglessink\n')
        sys.exit(1)

sys.stdout.write('\n')
sys.stdout.write('SOURCE: %s\n' % SOURCE)
sys.stdout.write('CONFIG_INFER: %s\n' % CONFIG_INFER)
sys.stdout.write('STREAMMUX_BATCH_SIZE: %d\n' % STREAMMUX_BATCH_SIZE)
sys.stdout.write('STREAMMUX_WIDTH: %d\n' % STREAMMUX_WIDTH)
sys.stdout.write('STREAMMUX_HEIGHT: %d\n' % STREAMMUX_HEIGHT)
sys.stdout.write('GPU_ID: %d\n' % GPU_ID)
sys.stdout.write('PERF_MEASUREMENT_INTERVAL_SEC: %d\n' % PERF_MEASUREMENT_INTERVAL_SEC)
sys.stdout.write('JETSON: %s\n' % ('TRUE' if is_aarch64() else 'FALSE'))
sys.stdout.write('\n')

streammux.set_property('batch-size', STREAMMUX_BATCH_SIZE)
streammux.set_property('batched-push-timeout', 25000)
streammux.set_property('width', STREAMMUX_WIDTH)
streammux.set_property('height', STREAMMUX_HEIGHT)
streammux.set_property('enable-padding', 0)
streammux.set_property('live-source', 1)
streammux.set_property('attach-sys-ts', 1)
pgie.set_property('config-file-path', CONFIG_INFER)
pgie.set_property('qos', 0)
tracker.set_property('tracker-width', 640)
tracker.set_property('tracker-height', 384)
tracker.set_property('ll-lib-file', '/opt/nvidia/deepstream/deepstream-7.0/lib/libnvds_nvmultiobjecttracker.so')
tracker.set_property('ll-config-file',
                     '/opt/nvidia/deepstream/deepstream-7.0/samples/configs/deepstream-app/config_tracker_NvDCF_perf.yml')
tracker.set_property('display-tracking-id', 1)
tracker.set_property('qos', 0)
osd.set_property('process-mode', int(pyds.MODE_GPU))
osd.set_property('qos', 0)
sink.set_property('async', 0)
sink.set_property('sync', 0)
sink.set_property('qos', 0)

if 'file://' in SOURCE:
    streammux.set_property('live-source', 0)

if tracker.find_property('enable_batch_process') is not None:
    tracker.set_property('enable_batch_process', 1)

if tracker.find_property('enable_past_frame') is not None:
    tracker.set_property('enable_past_frame', 1)

if not is_aarch64():
    streammux.set_property('nvbuf-memory-type', 0)
    streammux.set_property('gpu_id', GPU_ID)
    pgie.set_property('gpu_id', GPU_ID)
    tracker.set_property('gpu_id', GPU_ID)
    converter.set_property('nvbuf-memory-type', 0)
    converter.set_property('gpu_id', GPU_ID)
    osd.set_property('gpu_id', GPU_ID)

pipeline.add(pgie)
pipeline.add(tracker)
pipeline.add(converter)
pipeline.add(osd)
pipeline.add(sink)

streammux.link(pgie)
pgie.link(tracker)
tracker.link(converter)
converter.link(osd)
osd.link(sink)

bus = pipeline.get_bus()
bus.add_signal_watch()
bus.connect('message', bus_call, loop)

tracker_src_pad = tracker.get_static_pad('src')
if not tracker_src_pad:
    sys.stderr.write('ERROR: Failed to get tracker src pad\n')
    sys.exit(1)
else:
    tracker_src_pad.add_probe(Gst.PadProbeType.BUFFER, tracker_src_pad_buffer_probe, 0)

pipeline.set_state(Gst.State.PLAYING)

sys.stdout.write('\n')

try:
    loop.run()
except:
    pass

pipeline.set_state(Gst.State.NULL)

sys.stdout.write('\n')

def parse_args():
global SOURCE, CONFIG_INFER, STREAMMUX_BATCH_SIZE, STREAMMUX_WIDTH, STREAMMUX_HEIGHT, GPU_ID,
PERF_MEASUREMENT_INTERVAL_SEC

parser = argparse.ArgumentParser(description='DeepStream')
parser.add_argument('-s', '--source', required=True, help='Source stream/file')
parser.add_argument('-c', '--config-infer', required=True, help='Config infer file')
parser.add_argument('-b', '--streammux-batch-size', type=int, default=1, help='Streammux batch-size (default: 1)')
parser.add_argument('-w', '--streammux-width', type=int, default=1920, help='Streammux width (default: 1920)')
parser.add_argument('-e', '--streammux-height', type=int, default=1080, help='Streammux height (default: 1080)')
parser.add_argument('-g', '--gpu-id', type=int, default=0, help='GPU id (default: 0)')
parser.add_argument('-f', '--fps-interval', type=int, default=5, help='FPS measurement interval (default: 5)')
args = parser.parse_args()
if args.source == '':
    sys.stderr.write('ERROR: Source not found\n')
    sys.exit(1)
if args.config_infer == '' or not os.path.isfile(args.config_infer):
    sys.stderr.write('ERROR: Config infer not found\n')
    sys.exit(1)

SOURCE = args.source
CONFIG_INFER = args.config_infer
STREAMMUX_BATCH_SIZE = args.streammux_batch_size
STREAMMUX_WIDTH = args.streammux_width
STREAMMUX_HEIGHT = args.streammux_height
GPU_ID = args.gpu_id
PERF_MEASUREMENT_INTERVAL_SEC = args.fps_interval

if name == ‘main’:
parse_args()
sys.exit(main())
config_infer_primary_yoloV8_face.txt (793 Bytes)

It depends on the model and corresponding labels.txt.

What is your purpose? If you want to detect more types, I think you need this, they correspond to their respective models.

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