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