Cannot link python libraries in deepstream makefile while embedding python in deepstream_app.c

Unable to import modules such as numpy, pandas etc. while embedding python code in C. I am using Jetson TX2 NX as development board with ubuntu18.04, deepstream sdk 6.0.1 and Jetpack 4.6.2. I have python 3.6.9 (python3 -V). Numpy is installed in /usr/lib/python3/dist-packages and also I have provided python library path in Makefile. I am attaching the snippet of Makefile below.

And below is the deepstream_app.c embedded code snippet
path - path where the python file is located
calculate_values - function in python file
f_num, l,w,t,h - parameters

Py_Initialize()
char* path = “/home/jetsontx2/script”;
wchar_t* wpath = charToWChar(path);
PySys_SetPath(wpath);
free(wpath);
PyObject* module = PyImport_ImportModule(“pyth”);
PyObject* function = PyObject_GetAttrString(module, “calculate_values”);
PyObject* args = PyTuple_New(5);
PyTuple_SetItem(args, 0, Py_BuildValue(“i”, f_num));
PyTuple_SetItem(args, 1, Py_BuildValue(“i”, l));
PyTuple_SetItem(args, 2, Py_BuildValue(“i”, t));
PyTuple_SetItem(args, 3, Py_BuildValue(“i”, w));
PyTuple_SetItem(args, 4, Py_BuildValue(“i”, h));
PyObject* result = PyObject_CallObject(function, args);
int value1, value2;
if (PyArg_ParseTuple(result, “ii”, &value1, &value2)) {
printf(“(l + t): %d\n”,value1);
printf(“(w + h): %d\n”, value2);
} else {
printf(“Failed to parse the result tuple.\n”);
}
Py_DECREF(module);
Py_DECREF(function);
Py_DECREF(args);
Py_DECREF(result);

Py_Finalize()

  • I was able to run the same file using gcc but I am not able to run in deepstream using make.

Could you confirm the correct method to call python in c? As you say, the c++ is OK. But the deepstream_app.c is written by c.
Or you can try to modify the Makefile :

%.o: %.c $(INCS) Makefile
	$(CXX) -c -o $@ $(CFLAGS) $<

Above embedded code snippet is inside the for loop of the write_kitti_track_output() function of deepstream_app.c file. This is not in c++, whole thing is in C and I want to embedd python to that.
Basically I want to pass the bounding box coordinates to that python file and get some output from that python file in this c code itself.I have taken care of Py_initilize() and Py_finilize() outside the function. below is the code implementation

static void
write_kitti_track_output (AppCtx * appCtx, NvDsBatchMeta * batch_meta)
{
if (!appCtx->config.kitti_track_dir_path)
return;

char* path = "/home/jetsontx2/script";    
wchar_t* wpath = charToWChar(path);   
PySys_SetPath(wpath); 
free(wpath);


for (NvDsMetaList *l_frame = batch_meta->frame_meta_list; l_frame != NULL; l_frame = l_frame->next)
{
    NvDsFrameMeta *frame_meta = (NvDsFrameMeta *)l_frame->data;
    guint stream_id = frame_meta->pad_index;

    for (NvDsMetaList *l_obj = frame_meta->obj_meta_list; l_obj != NULL; l_obj = l_obj->next)
    {
        NvDsObjectMeta *obj = (NvDsObjectMeta *)l_obj->data;
        float left = obj->tracker_bbox_info.org_bbox_coords.left;
        float top = obj->tracker_bbox_info.org_bbox_coords.top;
        float width = obj->tracker_bbox_info.org_bbox_coords.width;
        float height = obj->tracker_bbox_info.org_bbox_coords.height;
        float confidence = obj->tracker_confidence;
        int l = (int)left;
        int t = (int)top;
        int w = (int)width;
        int h = (int)height;
        int id = obj->object_id;
        int f_num = frame_meta->frame_num;
        printf("f_num: %d, id: %d, left: %d, top: %d, width: %d, height: %d\n",
               f_num, id, l, t, w, h);

           PyObject* module = PyImport_ImportModule("pyth");
           PyObject* function = PyObject_GetAttrString(module, "calculate_values");
           PyObject* args = PyTuple_New(5);
           PyTuple_SetItem(args, 0, Py_BuildValue("i", f_num));
           PyTuple_SetItem(args, 1, Py_BuildValue("i", l));
           PyTuple_SetItem(args, 2, Py_BuildValue("i", t));
           PyTuple_SetItem(args, 3, Py_BuildValue("i", w));
           PyTuple_SetItem(args, 4, Py_BuildValue("i", h));
           PyObject* result = PyObject_CallObject(function, args);
           int value1, value2;
           if (PyArg_ParseTuple(result, "ii", &value1, &value2)) {
           printf("(l + t): %d\n",value1);
           printf("(w + h): %d\n", value2);
           } 
           else {
           printf("Failed to parse the result tuple.\n");
           }
           Py_DECREF(module);
           Py_DECREF(function);
           Py_DECREF(args);
           Py_DECREF(result);
    }

}
}
}

Have you try the method that I attached above to change the Makefile? Also, you can get the file with our source code and write another Python script to handle it.

I tried your solution but it did not work. I am not getting file from the source code which handles python, Can you explain briefly how to do and which file is that.
If possible can you send me example if anyone implemented.

Yes. You can add the kitti-track-output-dir in the config file. Please make sure the path is real, like

[application]
enable-perf-measurement=1
perf-measurement-interval-sec=5
kitti-track-output-dir=/tmp

You can find a txt file in the path after run the deepstream.

I did these things, it works fine to run simple embedd python code but it wont run if we want to import basic libraries of python. It will show module not found error eventhough libraries are present.

As you said it works with gcc, could you attach your gcc commands and the source file?
Please attach the error when use Makefile. Thanks

gcc prd.c -I /usr/include/python3.6m -L/usr/lib/python3/dist-packages -lpython3.6m
./a.out

This is the prd.c file

In the c file we first call test4.py file which import all the libraries, Without test4.py we cannot run python function which has libraries in gcc too. test4.py is called only to import libraries, after this scr.py is called which has necessary python function.

test4.py file has :

import numpy
import pandas

scr.py fille has :

import numpy
import pandas

def calculate_values(f_num, l, t, w, h):
print(numpy.array([1,2,3]))
sum1 = l + t
sum2 = w + h
return int(sum1), int(sum2)

Error shown by deepstream is :

File “/home/summoner/py_files/test4.py”, line 2, in
import pandas
ModuleNotFoundError: No module named ‘pandas’
Segmentation fault (core dumped)

Above python functions are not the actual one, I need libraries to write those function, I wrote above function for testing purpose

In my enviroment, I just install the pandas module. It’s works well.

pip3 install pandas

did it work with deepstream?
if so, will you send what all changes you made in Makefile and others changes you made.

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

I just add your demo code to the write_kitti_track_output() and change the Makefile like below:

CFLAGS+= -I./ -I../../apps-common/includes \
                 -I../../../includes -DDS_VERSION_MINOR=1 -DDS_VERSION_MAJOR=5 \
                 -I /usr/local/cuda-$(CUDA_VER)/include \
                 -I /usr/include/python3.8/

LIBS:= -L/usr/local/cuda-$(CUDA_VER)/lib64/ -lcudart -L/usr/lib/python3.8/ -lpython3.8

But I use the latest version with python3.8, deepstream 6.2.

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.