I am working on running a segmentation model (YOLOv8-seg ONNX) with DeepStream 7.1 on Jetson Orin Nano.
I am able to see bounding boxes from the parser output, but segmentation masks are not rendered on the display, even though nvdsosd is configured with display-mask=1.
NvDsInferInstanceMaskInfo maskInfo;
maskInfo.width = mask_resized_w;
maskInfo.height = mask_resized_h;
maskInfo.mask = new float[mask_resized_w * mask_resized_h];
// Copy resized mask into maskInfo
for (int y = 0; y < mask_resized_h; y++) {
for (int x = 0; x < mask_resized_w; x++) {
float val = maskResized.at<float>(y, x);
// tried both soft float [0,1] and thresholded binary {0,1}
maskInfo.mask[y * mask_resized_w + x] = (val > 0.5f ? 1.0f : 0.0f);
}
}
object.mask_info = maskInfo;
Issue
Bounding boxes appear as expected.
Segmentation masks are not displayed (even with nvdsosd display-mask=1).
Tried both soft masks (float [0,1]) and binary masks (0/1).
No error logs from nvinferserver or nvdsosd.
Could you please clarify:
Does nvdsosd / nvinferserver in DeepStream 7.1 require additional config to render segmentation masks along with bboxes?
Should the masks provided in NvDsInferInstanceMaskInfo.mask be strictly binary, or are probability maps (floating-point values), since the field is defined as float?
Is there a reference segmentation parser for nvinferserver along with config.txt that we can align with?
Could you attach your command to run our Mask2Former? Theoretically, you don’t need to modify any code. Just run the sample follow the instructions in our Readme.
With nvinfer inside that app config, I get proper masks. But when I change it to nvinferserver, only bounding boxes are shown.
Question:
Am I missing something in the nvinferserver config to enable mask visualization? It looks like the custom parser is working with nvinfer but not with nvinferserver.
Sorry, our current nvinferserver does not support the instance segment mask function. We suggest that you follow the steps below to implement this feature yourself.
By running the Mask2Former with nvinfer, you can get familiar with the code processing related to nvinfer.
Implement your yolo-seg model with nvinfer first.
Since our nvinfer and nvinferserver are all open source, you can implement it in the nvinferserver based on the process in nvinfer.
Yes, my understanding is that the custom parser is the same in both cases — whether I use nvinfer or nvinferserver, and bboxes and masks are then applied by nvdsosd
Both nvinfer and nvinferserver are mainly doing inference:
They call the backend (TensorRT for nvinfer, Triton for nvinferserver)
They get back raw tensors
Then the custom parser interprets those tensors into DeepStream objects.
In my case, in both plugins, my parser is appending results into
So if the vector has the same mask data in both cases, what is the missing piece?
In nvinfer, the masks appear on screen.
In nvinferserver, the masks don’t show up.
Is the difference only in the way the mask metadata gets attached to NvDsObjectMeta or propagated downstream to nvdsosd?
Or does nvinferserver currently drop/ignore the mask metadata, even though the parser fills objectList correctly?
Basically: If the parser populates the same structure, why do masks get drawn in nvinfer but not in nvinferserver?
It’s only in the way the mask metadata gets attached to NvDsObjectMeta. The post-processing of nvinferserver does not attach the NvDsInferInstanceMaskInfo to the object.
You can refer to our source code deepstream\sources\libs\nvdsinferserver\infer_postprocess.cpp. This part did not implement the NvDsInferInstanceMaskInfo attached. You can follow the source code form the nvinfer to implement this function.
Thank you for the response. One option is to customize nvinferserver for instance segmentation, but another possible approach is to use the nvdspostprocess plugin.
I’d like to clarify:
Can we implement only instance segmentation within a custom nvdspostprocess library, without having to define additional parsers such as classification or detection?
Does nvdspostprocess support truly generic post-processing, where the buffer itself can be modified by a custom algorithm and a new buffer injected back into the pipeline?
If not, what would be the best method to achieve this?
Yes. It can support truly generic post-processing. We don’t have many samples at present. You can only refer to the source code deepstream\sources\gst-plugins\gst-nvdspostprocess. And we will provide an example in the next version soon.
I am trying to use the nvdspostprocess plugin for classification. Unlike nvinfer or nvinferserver, I don’t see an explicit config option to provide a path to a custom parser library.
In nvinfer/nvinferserver, we can pass a separate .so implementing a custom parser.
In nvdspostprocess, the only thing I see is that we pass:
Inside the implementation, I only see the default parser defined in: sources/gst-plugins/gst-nvdspostprocess/postprocesslib_impl/post_processor_classify.cpp
But it’s not clear where such functions are expected to be loaded from.
My questions:
Am I expected to directly modify post_processor_classify.cpp and define my function there?
Is there a way to define this function in a separate file / .so and load it without rebuilding the whole postprocesslib_impl?
For complex pipelines, I would prefer defining custom parser libraries per inference instance, rather than combining everything into one big shared library. Is this supported, and how should it be configured?
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.