How to get result_label from custom classification parser

GeForce RTX 2080 Ti 2
Deepstream 4.0
TensorRT 6.0.1
Driver Version: 440.64.00

I have a cascade of neural networks. Detection and two parallel classifiers. One classifier works with the standard post-processing function, and the second - text recognition (the output in my case is a batch, 1, 1, 8x36). To process this output, I upgraded the post processing function for the network:

extern "C" bool NvDsInferParsetextRecognize(
        std::vector<NvDsInferLayerInfo> const &outputLayersInfo,
        NvDsInferNetworkInfo  const &networkInfo,
        float classifierThreshold,
        std::vector<NvDsInferAttribute> &attrList,
        std::string &attrString)
{
    
    unsigned int numAttributes = outputLayersInfo.size();

    static const std::string labels = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
    for (unsigned int l = 0; l < numAttributes; l++)
    {
        
        NvDsInferDimsCHW dims;

        getDimsCHWFromDims(dims, outputLayersInfo[l].dims);
        unsigned int numClasses = 36;
        float *outputCoverageBuffer =
            (float *)outputLayersInfo[l].buffer;
        
        bool attrFound = false;
        NvDsInferAttribute attr;
        std::string text;
        
        for (unsigned int k = 0; k<8; k++)
        {
            float maxProbability = -254;
            unsigned int index;
            for (unsigned int c = k*numClasses; c < (k+1)*numClasses; c++)
            {
                float probability = outputCoverageBuffer[c];
                if (probability > maxProbability)
                {
                    maxProbability = probability;
                    attrFound = true;
                    attr.attributeIndex = l;
                    attr.attributeValue = 0;
                    attr.attributeConfidence = 1.0;
                    index = c-(k*numClasses);
                }
            }
            text.append(1,labels.at(index));
        }
        if (attrFound)
        {
            attr.attributeLabel = text.c_str();
            
            attrList.push_back(attr);
            if (attr.attributeLabel)
                attrString.append(attr.attributeLabel).append(" ");
        }
    }

    return true;
}

I see result_label on the video after processing after the second classifier, but I can’t print it in the console:

gchar text[128] = "";
snprintf(text, 128, "%s", label->result_label);
if (triger) {
    g_print("class:%s\n", label->result_label);
    printf("text: %s\n",  text);
}

with result:

class:
text: 

I’m not sure this is not a deepstream problem. Can someone advise something how to solve my problem.

Hi,

Suppose the label should be accessed like this:

NvDsLabelInfo *label = (NvDsLabelInfo *) l_label->data;
if (label->result_label[0] != '\0') {
    sprintf (str_ins_pos, " %s", label->result_label);
}

If you still cannot get the correct output, please share your source with us.
Thanks.

I changed the code according to your recommendations and in the console I get:

CA8450BP
[Invalid UTF-8] class:\x10\xaf\xbe\xdea\x7f
text: ���a

First row - printf("%s\n", text.c_str()) from parser function NvDsInferParsetextRecognize
second row - g_print(“class:%s\n”, label->result_label); from tiler_src_pad_buffer_probe
third row - printf(“text: %s\n”, text); from tiler_src_pad_buffer_probe

Hi,

This is related to the character used in your label file.

Is your label file supported by the UTF-8 format?
Do you have any character that not be included in the UTF-8?

Thanks.

I do not use a labels file for a network. All labels are listed as characters in this variable inside the post-processing function from the first message:

static const std::string labels = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";

Hi,

Would you mind to share the change you have made so we can check it further?
Thanks.

custom_parser.cpp:

#include <cstring>
#include <iostream>
#include "nvdsinfer_custom_impl.h"

/* This is a sample classifier output parsing function from softmax layers for
 * the vehicle type classifier model provided with the SDK. */

/* C-linkage to prevent name-mangling */
extern "C" bool NvDsInferParsetextRecognize(
        std::vector<NvDsInferLayerInfo> const &outputLayersInfo,
        NvDsInferNetworkInfo  const &networkInfo,
        float classifierThreshold,
        std::vector<NvDsInferAttribute> &attrList,
        std::string &attrString);

extern "C" bool NvDsInferParsetextRecognize(
        std::vector<NvDsInferLayerInfo> const &outputLayersInfo,
        NvDsInferNetworkInfo  const &networkInfo,
        float classifierThreshold,
        std::vector<NvDsInferAttribute> &attrList,
        std::string &attrString)
{
    
    unsigned int numAttributes = outputLayersInfo.size();

    //static const std::string labels = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
    static const std::string labels = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
    for (unsigned int l = 0; l < numAttributes; l++)
    {
        
        NvDsInferDimsCHW dims;

        getDimsCHWFromDims(dims, outputLayersInfo[l].dims);
        unsigned int numClasses = 36;
        float *outputCoverageBuffer =
            (float *)outputLayersInfo[l].buffer;
        
        bool attrFound = false;
        NvDsInferAttribute attr;
        std::string text;
        
        for (unsigned int k = 0; k<8; k++)
        {
            float maxProbability = -254;
            unsigned int index;
            for (unsigned int c = k*numClasses; c < (k+1)*numClasses; c++)
            {
                float probability = outputCoverageBuffer[c];
                if (probability > maxProbability)
                {
                    maxProbability = probability;
                    attrFound = true;
                    attr.attributeIndex = l;
                    attr.attributeValue = 0;
                    attr.attributeConfidence = 1.0;
                    index = c-(k*numClasses);
                }
            }
            text.append(1,labels.at(index));
        }
        printf("%s\n", text.c_str());
        if (attrFound)
        {
            attr.attributeLabel = text.c_str();
            
            attrList.push_back(attr);
            if (attr.attributeLabel)
                attrString.append(attr.attributeLabel).append(" ");
        }
    }

    return true;
}

/* Check that the custom function has been defined correctly */
CHECK_CUSTOM_CLASSIFIER_PARSE_FUNC_PROTOTYPE(NvDsInferParsetextRecognize);

from deepstream_test3_app.cpp:

static GstPadProbeReturn
tiler_src_pad_buffer_probe (GstPad * pad, GstPadProbeInfo * info, gpointer u_data){
    
    GstBuffer *buf = (GstBuffer *) info->data;
    guint num_rects = 0; 
    NvDsObjectMeta *obj_meta = NULL;
    guint vehicle_count = 0;
    guint person_count = 0;
    NvDsMetaList * l_frame = NULL;
    NvDsMetaList * l_obj = NULL;

    NvDsBatchMeta *batch_meta = gst_buffer_get_nvds_batch_meta (buf);
    
    for (l_frame = batch_meta->frame_meta_list; l_frame != NULL; l_frame = l_frame->next) {
        NvDsFrameMeta *frame_meta = (NvDsFrameMeta *) (l_frame->data);
        guint batch_id = frame_meta->batch_id;
        int  surface_id = frame_meta->source_id;
        
        for (l_obj = frame_meta->obj_meta_list; l_obj != NULL; l_obj = l_obj->next) {
            guint class_id = 2555;
            gfloat model_prob = 0;
            obj_meta = (NvDsObjectMeta *) (l_obj->data);
            guint64 track_id = obj_meta->object_id;
            NvOSD_RectParams rect = obj_meta->rect_params;
            gint color_id = obj_meta->class_id;
            gfloat color_prob = obj_meta->confidence;
            gchar text[128] = "";
            
            for (NvDsMetaList * l_class = obj_meta->classifier_meta_list; l_class != NULL; l_class = l_class->next) {
                NvDsClassifierMeta *cmeta = (NvDsClassifierMeta *) l_class->data;
                for (NvDsMetaList * l_label = cmeta->label_info_list; l_label != NULL; l_label = l_label->next) {
                    NvDsLabelInfo *label = (NvDsLabelInfo *) l_label->data;
                    class_id = label->result_class_id;
                    model_prob = label->result_prob;
                    if (color_id==12 && label->result_label[0] != '\0' ){ 
                        g_print("class:%s\n", label->result_label);
                        sprintf(text, "text: %s", label->result_label);
                        printf("text: %s\n", text);
                    }
                }
            }
        }
            
    }
    frame_number++;
    return GST_PAD_PROBE_OK;
}
1 Like

I understood my mistake.
I apologize for the stupidity, but I can’t understand how to save class numbers from multi label classifications in NvDsLabelInfo

Hi,

Please check if this sample helps:
/opt/nvidia/deepstream/deepstream-5.0/sources/apps/sample_apps/deepstream-infer-tensor-meta-test/deepstream_infer_tensor_meta_test.cpp

NvDsLabelInfo *label_info =
    nvds_acquire_label_info_meta_from_pool (batch_meta);
label_info->result_class_id = attr.attributeValue;
label_info->result_prob = attr.attributeConfidence;

Thanks.

1 Like

Super