NvDsUserMeta acess from python

Please provide complete information as applicable to your setup.
• Hardware Platform (Jetson / GPU) GPU
• DeepStream Version 6.3
• NVIDIA GPU Driver Version (valid for GPU only) 535
• Issue Type( questions, new requirements, bugs) question

i am trying extract usermeta of type “NVIDIA.NVINFER.USER_META” uisng python. I implemented face recognition using retinaface and arcface following this repo . This implementation do some modification in nvinfer and also do some alignment process.
I would like to extract the landmarks from retinaface in the python code
The C++ code in the author’s repository is as follows:

#define NVDS_USER_OBJECT_META_EXAMPLE (nvds_get_user_meta_type("NVIDIA.NVINFER.USER_META"))
if (nvinfer->alignment_type){
        NvDsMetaList * l_user_meta = NULL;
        NvDsUserMeta *user_meta = NULL;
        gint *user_meta_data = NULL;
        for (l_user_meta = object_meta->obj_user_meta_list; l_user_meta != NULL; l_user_meta = l_user_meta->next) {
          user_meta = (NvDsUserMeta *) (l_user_meta->data);
          user_meta_data = (gint *)user_meta->user_meta_data;
          lmk_flag = true;
          if(user_meta->base_meta.meta_type == NVDS_USER_OBJECT_META_EXAMPLE){
            // std::cout<<"in get usermeta"<<std::endl;
            for (unsigned int i=0; i < 10; i++) {
              // std::cout<<user_meta_data[i]<<" ";
              if (user_meta_data[i]) {
                landmarks[i] = (float)user_meta_data[i];
                // std::cout<<landmarks[i]<<" ";
              }
            }
            // std::cout<<std::endl;                      
          }
        }
      }

now in my python code:

while l_user_meta:
    try:
        user_meta = pyds.NvDsUserMeta.cast(l_user_meta.data)
    except StopIteration:
        break
    if user_meta and user_meta.base_meta.meta_type == pyds.NvDsMetaType.NVDSINFER_TENSOR_OUTPUT_META:
        try:
            tensor_meta = pyds.NvDsInferTensorMeta.cast(user_meta.user_meta_data)
        except StopIteration:
            break
        layer = pyds.get_nvds_LayerInfo(tensor_meta, 0)
        output = []
        for i in range(512):
            output.append(pyds.get_detections(layer.buffer, i))
        res = np.array(output)

    elif user_meta.base_meta.meta_type == pyds.nvds_get_user_meta_type("NVIDIA.NVINFER.USER_META"):
        user_meta_data = user_meta.user_meta_data
        #### TODO 
       # CAST THE LANDMARK LIST TO PYTHON


    try:
        l_user_meta = l_user_meta.next
    except StopIteration:
        break

i am not sure how to cast the data of type ""NVIDIA.NVINFER.USER_META". can this be casted using ctype?

Generally speaking, it is possible.

Also you can refer to this FAQ and add the corresponding python bindings, which is a simpler option.

1 Like

This worked for me

if user_meta.base_meta.meta_type == pyds.nvds_get_user_meta_type("NVIDIA.NVINFER.USER_META"):
        user_meta_data = user_meta.user_meta_data
        ctypes.pythonapi.PyCapsule_GetPointer.restype = ctypes.c_void_p
        ctypes.pythonapi.PyCapsule_GetPointer.argtypes = [ctypes.py_object, ctypes.c_char_p]
        pointer = ctypes.pythonapi.PyCapsule_GetPointer(user_meta_data, None)
        pointer = ctypes.cast(pointer, ctypes.POINTER(ctypes.c_int))
        for i in range(10):
             print(pointer[i])