deepstream meta应用

deepstream_user_metadata_app

osd_sink_pad_buffer_probe
{
  //访问帧级usermeta,比如访问推理加的随机数字。
}
nvinfer_src_pad_buffer_probe{
   //添加帧级usermeta, 比如加个随机数字。
}
 

deepstream-test1
对osd的sink加了一个probe函数osd_sink_pad_buffer_probe,如下代码, NvDsFrameMeta下有NvDsFrameMetaList,NvDsFrameMeta下有NvDsObjectMetaList,统计NvDsFrameMeta下人和车的个数,并创建NvDsDisplayMeta,将文本信息挂在NvDsDisplayMeta的NvOSD_TextParams,再将NvDsDisplayMeta挂到NvDsFrameMeta。

osd_sink_pad_buffer_probe{
   for (l_frame = batch_meta->frame_meta_list; l_frame != NULL; l_frame = l_frame->next) {
      NvDsFrameMeta *frame_meta = (NvDsFrameMeta *) (l_frame->data);
      for (l_obj = frame_meta->obj_meta_list; l_obj != NULL; l_obj = l_obj->next){
         //统计人和车个数。
     }
        。。。。。。
     display_meta = nvds_acquire_display_meta_from_pool(batch_meta);
     NvOSD_TextParams *txt_params  = &display_meta->text_params[0];
     nvds_add_display_meta_to_frame(frame_meta, display_meta); 

  }
}


deepstream-gst-metadata-test

这个例子是在streammux之前加的user meta, 在streamnux之后,会被转为NvDsFrameMeta级别的user meta.  有三个probe函数,从函数名就能看出函数挂在什么地方。
h264parse_src_pad_buffer_probe   
{
 /* Attach decoder metadata to gst buffer using gst_buffer_add_nvds_meta() */
  meta = gst_buffer_add_nvds_meta (buf, h264parse_meta.....
  /* Set metadata type */
  meta->meta_type = (GstNvDsMetaType)NVDS_GST_META_BEFORE_DECODER_EXAMPLE;
}
nvdecoder_src_pad_buffer_probe   
{
  /* Attach decoder metadata to gst buffer using gst_buffer_add_nvds_meta() */
  meta = gst_buffer_add_nvds_meta (buf, decoder_meta.....
  /* Set metadata type */
  meta->meta_type = (GstNvDsMetaType)NVDS_DECODER_GST_META_EXAMPLE;
}
nvinfer_src_pad_buffer_probe     
{
    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);
        for (l_user_meta = frame_meta->frame_user_meta_list; l_user_meta != NULL; l_user_meta = l_user_meta->next) {
              if(user_meta->base_meta.meta_type == NVDS_DECODER_GST_META_EXAMPLE)
              {...... }

             if(user_meta->base_meta.meta_type == NVDS_GST_META_BEFORE_DECODER_EXAMPLE)
             {...... }
        }
    }
}

deepstream_image_meta_test
有两个probe函数,在这个pgie_src_pad_buffer_probe中,将检测到的object进行jpg编码,挂到object的usermeta,在osd_sink_pad_buffer_probe中可以保存jpg到本地。
osd_sink_pad_buffer_probe{
      snprintf (fileNameString, FILE_NAME_SIZE, "%s_%d_%d_%d_%s_%dx%d.jpg",
          osd_string, frame_number, frame_meta->source_id, num_rects,
          obj_meta->obj_label, obj_res_width, obj_res_height);
   while (usrMetaList != NULL) {
          NvDsUserMeta *usrMetaData = (NvDsUserMeta *) usrMetaList->data;
          if (usrMetaData->base_meta.meta_type == NVDS_CROP_IMAGE_META) {
            NvDsObjEncOutParams *enc_jpeg_image =
                (NvDsObjEncOutParams *) usrMetaData->user_meta_data;
            fwrite (enc_jpeg_image->outBuffer, sizeof (uint8_t),
                enc_jpeg_image->outLen, file);
  }

pgie_src_pad_buffer_probe   
{

       //obj_meta存有位置信息
        nvds_obj_enc_process (ctx, &userData, ip_surf, obj_meta, frame_meta);
}

deepstream_infer_tensor_meta_test

有4级别推理,分别是识别人车,车类型,车颜色,车制造商。 sgi的network_mode是100,那就要自己实现后处理,比如解析tensor data以获取分类置信度和标签,如果置信度大于阀值,就创建classifier_meta,并添加到object_meta。

 启动命令: ./deepstream-infer-tensor-meta-app -t infer /home/nvidia/videos/sample_720p.h264

osd_sink_pad_buffer_probe     //挂在osd

{

   //跟其他例子一样,往帧级meta加个display meta.

    nvds_add_display_meta_to_frame (frame_meta, display_meta);

}

配置:output-blob-names=conv2d_bbox;conv2d_cov/Sigmoid

output-tensor-meta=1
从配置可看出,输出层有两个,分别是conv2d_bbox和conv2d_cov/Sigmoid,output-tensor-meta等于1表明,用户可以在meta获取NvDsInferTensorMeta,这个数据包含推理输出,可以参考NvDsInferParseCustomResnet的处理。
pgie_pad_buffer_probe   // 挂在一级推理之后
{
    PGIE会把推理得到NvDsInferTensorMeta挂到帧级meta,在这个函数中,先获取到NvDsInferTensorMeta数据,再调NvDsInferParseCustomResnet进行解析,存到      std::vector < NvDsInferObjectDetectionInfo > objectList;最后将所有矩形信息,添加到帧级meta,如下:

      for (const auto & rect:objlist) {

          NvDsObjectMeta *obj_meta =

              nvds_acquire_obj_meta_from_pool (batch_meta);

          nvds_add_obj_meta_to_frame (frame_meta, obj_meta, NULL);

      }
}

配置:output-blob-names=predictions/Softmax
          output-tensor-meta=1

sgie_pad_buffer_probe   //挂在二级推理之后
{
   SGIE会把推理得到NvDsInferTensorMeta挂到object级meta,在这个函数中,也是先获取NvDsInferTensorMeta数据,再解析tensor,得到置信度和标签,最后创建NvDsClassifierMeta,添加到object级别meta,如下:

          nvds_add_label_info_meta_to_classifier (classifier_meta, label_info);

          nvds_add_classifier_meta_to_object (obj_meta, classifier_meta);

         比如,第一个模型检测是个车,创建object,第二个模型检测是大轿车,修改object的显示名称,第三个模型检测是个日产车,再修改object的显示名称,的四个模型检测是个黑色车,再修改object的显示名称,最终的显示名车可以是display_text:Vehicle sedan Nissan black。

}

nvds_remove_obj_meta_from_frame

此函数用于从framemeta上删除objectmeta,比如检测出有人和车的meta,只想留下人的meta,可以应用此函数,如下修改deepstream-test1的例子:

for (l_frame = batch_meta->frame_meta_list; l_frame != NULL;
      l_frame = l_frame->next) {
        NvDsFrameMeta *frame_meta = (NvDsFrameMeta *) (l_frame->data);
          printf("loop\n");
        //nvds_remove_frame_meta_from_batch(batch_meta, frame_meta);
        int offset = 0;
        for (l_obj = frame_meta->obj_meta_list; l_obj != NULL;
                ) {
            obj_meta = (NvDsObjectMeta *) (l_obj->data);
            NvDsMetaList *obj_next = l_obj->next;
            if (obj_meta->class_id == PGIE_CLASS_ID_VEHICLE) {
                vehicle_count++;
                num_rects++;
                printf("remove\n");
                nvds_remove_obj_meta_from_frame(frame_meta, obj_meta);
            }
            if (obj_meta->class_id == PGIE_CLASS_ID_PERSON) {
                person_count++;
                num_rects++;
                 printf("have person\n");

            }

            l_obj = obj_next;

        } 
    }

 如果有什么deepstream问题,可以发到deepstream论坛,有专人回复DeepStream SDK - NVIDIA Developer Forums

你可能感兴趣的:(deepstream,人工智能)