diff --git a/csrc/deepstream/config_yoloV8.txt b/csrc/deepstream/config_yoloV8.txt new file mode 100644 index 0000000..d8e6509 --- /dev/null +++ b/csrc/deepstream/config_yoloV8.txt @@ -0,0 +1,75 @@ +################################################################################ +# Copyright (c) 2019, NVIDIA CORPORATION. All rights reserved. +# +# Permission is hereby granted, free of charge, to any person obtaining a +# copy of this software and associated documentation files (the "Software"), +# to deal in the Software without restriction, including without limitation +# the rights to use, copy, modify, merge, publish, distribute, sublicense, +# and/or sell copies of the Software, and to permit persons to whom the +# Software is furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice shall be included in +# all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER +# DEALINGS IN THE SOFTWARE. +################################################################################ + +# Following properties are mandatory when engine files are not specified: +# int8-calib-file(Only in INT8), model-file-format +# Caffemodel mandatory properties: model-file, proto-file, output-blob-names +# UFF: uff-file, input-dims, uff-input-blob-name, output-blob-names +# ONNX: onnx-file +# +# Mandatory properties for detectors: +# num-detected-classes +# +# Optional properties for detectors: +# enable-dbscan(Default=false), interval(Primary mode only, Default=0) +# custom-lib-path +# parse-bbox-func-name +# +# Mandatory properties for classifiers: +# classifier-threshold, is-classifier +# +# Optional properties for classifiers: +# classifier-async-mode(Secondary mode only, Default=false) +# +# Optional properties in secondary mode: +# operate-on-gie-id(Default=0), operate-on-class-ids(Defaults to all classes), +# input-object-min-width, input-object-min-height, input-object-max-width, +# input-object-max-height +# +# Following properties are always recommended: +# batch-size(Default=1) +# +# Other optional properties: +# net-scale-factor(Default=1), network-mode(Default=0 i.e FP32), +# model-color-format(Default=0 i.e. RGB) model-engine-file, labelfile-path, +# mean-file, gie-unique-id(Default=0), offsets, gie-mode (Default=1 i.e. primary), +# custom-lib-path, network-mode(Default=0 i.e FP32) +# +# The values in the config file are overridden by values set through GObject +# properties. + +[property] +net-scale-factor=0.0039215697906911373 +gpu-id=0 +#0=RGB, 1=BGR +model-color-format=0 +model-engine-file=./yolov8s.engine +labelfile-path=./labels.txt +## 0=FP32, 1=INT8, 2=FP16 mode +network-mode=2 +num-detected-classes=80 +gie-unique-id=1 +is-classifier=0 +maintain-aspect-ratio=1 +output-blob-names=num_dets;bboxes;scores;labels +parse-bbox-func-name=NvDsInferParseCustomYoloV8 +custom-lib-path=./build/libnvdsinfer_custom_bbox_yoloV8.so diff --git a/csrc/deepstream/custom_bbox_parser/nvdsparsebbox_yoloV8.cpp b/csrc/deepstream/custom_bbox_parser/nvdsparsebbox_yoloV8.cpp new file mode 100644 index 0000000..80b0fc5 --- /dev/null +++ b/csrc/deepstream/custom_bbox_parser/nvdsparsebbox_yoloV8.cpp @@ -0,0 +1,113 @@ +#include "nvdsinfer_custom_impl.h" +#include +#include + +/** + * Function expected by DeepStream for decoding the TinyYOLOv2 output. + * + * C-linkage [extern "C"] was written to prevent name-mangling. This function must return true after + * adding all bounding boxes to the objectList vector. + * + * @param [outputLayersInfo] std::vector of NvDsInferLayerInfo objects with information about the output layer. + * @param [networkInfo] NvDsInferNetworkInfo object with information about the TinyYOLOv2 network. + * @param [detectionParams] NvDsInferParseDetectionParams with information about some config params. + * @param [objectList] std::vector of NvDsInferParseObjectInfo objects to which bounding box information must + * be stored. + * + * @return true + */ + +// This is just the function prototype. The definition is written at the end of the file. +extern "C" bool NvDsInferParseCustomYoloV8( + std::vector const& outputLayersInfo, + NvDsInferNetworkInfo const& networkInfo, + NvDsInferParseDetectionParams const& detectionParams, + std::vector& objectList); + +static __inline__ float bbox_clip(const float& val, const float& minVal = 0.f, const float& maxVal = 1280.f) +{ + assert(minVal <= maxVal); + return std::max(std::min(val, (maxVal - 1)), minVal); +} + +static std::vector decodeYoloV8Tensor( + const int* num_dets, + const float* bboxes, + const float* scores, + const int* labels, + const unsigned int& img_w, + const unsigned int& img_h +) +{ + std::vector bboxInfo; + size_t nums = num_dets[0]; + for (size_t i = 0; i < nums; i++) + { + float x0 = (bboxes[i * 4]); + float y0 = (bboxes[i * 4 + 1]); + float x1 = (bboxes[i * 4 + 2]); + float y1 = (bboxes[i * 4 + 3]); + x0 = bbox_clip(x0, 0.f, img_w); + y0 = bbox_clip(y0, 0.f, img_h); + x1 = bbox_clip(x1, 0.f, img_w); + y1 = bbox_clip(y1, 0.f, img_h); + NvDsInferParseObjectInfo obj; + obj.left = x0; + obj.top = y0; + obj.width = x1 - x0; + obj.height = y1 - y0; + obj.detectionConfidence = scores[i]; + obj.classId = labels[i]; + bboxInfo.push_back(obj); + } + + return bboxInfo; +} + +/* C-linkage to prevent name-mangling */ +extern "C" bool NvDsInferParseCustomYoloV8( + std::vector const& outputLayersInfo, + NvDsInferNetworkInfo const& networkInfo, + NvDsInferParseDetectionParams const& detectionParams, + std::vector& objectList) +{ + + // Some assertions and error checking. + + if (outputLayersInfo.empty() || outputLayersInfo.size() != 4) + { + std::cerr << "Could not find output layer in bbox parsing" << std::endl; + return false; + } + + // Obtaining the output layer. + const NvDsInferLayerInfo& num_dets = outputLayersInfo[0]; + const NvDsInferLayerInfo& bboxes = outputLayersInfo[1]; + const NvDsInferLayerInfo& scores = outputLayersInfo[2]; + const NvDsInferLayerInfo& labels = outputLayersInfo[3]; + + // num_dets(int) bboxes(float) scores(float) labels(int) + assert (num_dets.dims.numDims == 2); + assert (bboxes.dims.numDims == 3); + assert (scores.dims.numDims == 2); + assert (labels.dims.numDims == 2); + + + // Decoding the output tensor of YOLOv8 to the NvDsInferParseObjectInfo format. + std::vector objects = + decodeYoloV8Tensor( + (const int*)(num_dets.buffer), + (const float*)(bboxes.buffer), + (const float*)(scores.buffer), + (const int*)(labels.buffer), + networkInfo.width, + networkInfo.height + ); + + objectList.clear(); + objectList = objects; + return true; +} + +/* Check that the custom function has been defined correctly */ +CHECK_CUSTOM_PARSE_FUNC_PROTOTYPE(NvDsInferParseCustomYoloV8); diff --git a/csrc/deepstream/deepstream_app_config.txt b/csrc/deepstream/deepstream_app_config.txt new file mode 100644 index 0000000..089bab1 --- /dev/null +++ b/csrc/deepstream/deepstream_app_config.txt @@ -0,0 +1,116 @@ +[application] +enable-perf-measurement=1 +perf-measurement-interval-sec=5 +#gie-kitti-output-dir=streamscl + +[tiled-display] +enable=1 +rows=1 +columns=1 +# show +width=1920 +height=1080 +gpu-id=0 +#(0): nvbuf-mem-default - Default memory allocated, specific to particular platform +#(1): nvbuf-mem-cuda-pinned - Allocate Pinned/Host cuda memory, applicable for Tesla +#(2): nvbuf-mem-cuda-device - Allocate Device cuda memory, applicable for Tesla +#(3): nvbuf-mem-cuda-unified - Allocate Unified cuda memory, applicable for Tesla +#(4): nvbuf-mem-surface-array - Allocate Surface Array memory, applicable for Jetson +nvbuf-memory-type=0 + +[source0] +enable=1 +#Type - 1=CameraV4L2 2=URI 3=MultiURI +type=3 +uri=file://./sample_1080p_h264.mp4 +num-sources=1 +drop-frame-interval=1 +gpu-id=0 +# (0): memtype_device - Memory type Device +# (1): memtype_pinned - Memory type Host Pinned +# (2): memtype_unified - Memory type Unified +cudadec-memtype=0 + +[sink0] +enable=1 +#Type - 1=FakeSink 2=EglSink 3=File +type=2 +sync=0 +source-id=0 +gpu-id=0 +nvbuf-memory-type=0 + +#[sink1] +#enable=1 +#Type - 1=FakeSink 2=EglSink 3=File 4=RTSPStreaming +#type=4 +##1=h264 2=h265 +#codec=1 +#sync=0 +#bitrate=4000000 +## set below properties in case of RTSPStreaming +#rtsp-port=8554 +#udp-port=5400 + +#[sink2] +#enable=1 +##Type - 1=FakeSink 2=EglSink 3=File 4=RTSPStreaming +#type=3 +##1=h264 2=h265 +#codec=1 +#sync=0 +#bitrate=4000000 +#container=1 +#output-file=./output.mp4 + +[osd] +enable=1 +gpu-id=0 +border-width=1 +text-size=15 +text-color=1;1;1;1; +text-bg-color=0.3;0.3;0.3;1 +font=Serif +show-clock=0 +clock-x-offset=800 +clock-y-offset=820 +clock-text-size=12 +clock-color=1;0;0;1 +nvbuf-memory-type=0 + +[streammux] +gpu-id=0 +##Boolean property to inform muxer that sources are live +live-source=0 +batch-size=1 +##time out in usec, to wait after the first buffer is available +##to push the batch even if the complete batch is not formed +batched-push-timeout=40000 +## Set muxer output width and height +width=1920 +height=1080 +##Enable to maintain aspect ratio wrt source, and allow black borders, works +##along with width, height properties +enable-padding=0 +nvbuf-memory-type=0 + +# config-file property is mandatory for any gie section. +# Other properties are optional and if set will override the properties set in +# the infer config file. +[primary-gie] +enable=1 +gpu-id=0 +model-engine-file=yolov8s.engine +labelfile-path=./labels.txt +batch-size=1 +#Required by the app for OSD, not a plugin property +bbox-border-color0=1;0;0;1 +bbox-border-color1=0;1;1;1 +bbox-border-color2=0;0;1;1 +bbox-border-color3=0;1;0;1 +gie-unique-id=1 +nvbuf-memory-type=0 +config-file=config_yoloV8.txt + +[tests] +file-loop=0 diff --git a/csrc/deepstream/labels.txt b/csrc/deepstream/labels.txt new file mode 100644 index 0000000..ca76c80 --- /dev/null +++ b/csrc/deepstream/labels.txt @@ -0,0 +1,80 @@ +person +bicycle +car +motorbike +aeroplane +bus +train +truck +boat +traffic light +fire hydrant +stop sign +parking meter +bench +bird +cat +dog +horse +sheep +cow +elephant +bear +zebra +giraffe +backpack +umbrella +handbag +tie +suitcase +frisbee +skis +snowboard +sports ball +kite +baseball bat +baseball glove +skateboard +surfboard +tennis racket +bottle +wine glass +cup +fork +knife +spoon +bowl +banana +apple +sandwich +orange +broccoli +carrot +hot dog +pizza +donut +cake +chair +sofa +pottedplant +bed +diningtable +toilet +tvmonitor +laptop +mouse +remote +keyboard +cell phone +microwave +oven +toaster +sink +refrigerator +book +clock +vase +scissors +teddy bear +hair drier +toothbrush