0

Here a description of my application :
I get images from a camera which have a C++ library and want to analyse these images in Python with AI algorithm (easier to develop in Python).

I wrote a wrapper with boost::Python to do so and it's working. It can send images to the Python part to train an algorithm and then test an image with this algorithm. (See the functions below)

Problem:
When I want to do it in real time connected with the camera (4 fps), the program freeze when I call my test function. After debugging, I can say that it appends probably because the Py_Initialize and the train functions are not executed in the same thread as the call of the test function.

Initialization :

Py_Initialize();
import_array();

Train function :

PyObject* pName, * pModule, * pDict, * pFunc, * pArgs;

// Build the name object
pName = PyUnicode_FromString("model");

// Load the module object
pModule = PyImport_Import(pName);

// Check if it's loaded 
if (pModule == nullptr) {
    cout << "Python file not loaded !" << endl;
    PyErr_Print();
    return;
}

// pDict is a borrowed reference 
pDict = PyModule_GetDict(pModule);

// pFunc is also a borrowed reference 
pFunc = PyDict_GetItemString(pDict, "train");


if (PyCallable_Check(pFunc))
{
    // Transform images to a vector
    std::vector<uint8_t> data;
    int nb_imgs = _data->trainRate * _data->nbGoodImages;

    for (int i = 0; i < nb_imgs; i++) {
        cv::Mat mat = _data->images[i];

        std::vector<uint8_t> img = matToVec(mat);
        data.insert(data.end(), img.begin(), img.end());
    }


    PyObject* arr = stdvectorToNumpy(data);
    PyObject* cols = PyLong_FromLong(640);
    PyObject* rows = PyLong_FromLong(120);
    PyObject* ch = PyLong_FromLong(3);
    PyObject* nbImgs = PyLong_FromLong(nb_imgs);

    PyObject* size = PyTuple_Pack(4, nbImgs, rows, cols, ch);


    // Train
    pArgs = PyTuple_Pack(2, arr, size);
    _data->algo= PyObject_CallObject(pFunc, pArgs);


    if (pArgs != NULL)
        Py_DECREF(pArgs);

    if (!_data->algo)
        cout << "Failed !" << endl;
}

Test function :

// Build the name object
pName = PyUnicode_FromString("model");

// Load the module object
pModule = PyImport_Import(pName);

if (pModule == nullptr) {
    cout << "Python file not loaded !" << endl;
    PyErr_Print();
    return false;
}    

// pDict is a borrowed reference 
pDict = PyModule_GetDict(pModule);

pFunc = PyDict_GetItemString(pDict, "test");

if (PyCallable_Check(_data->pFunc))
{
    // Transform image to vector
    std::vector<uint8_t> vec = matToVec(img);

    PyObject* arr = ImageProcessing::stdvectorToNumpy(vec);
    PyObject* cols = PyLong_FromLong(640);
    PyObject* rows = PyLong_FromLong(120);
    PyObject* ch = PyLong_FromLong(3);

    PyObject* size = PyTuple_Pack(3, rows, cols, ch);

    // Test
    PyObject* pArgs = PyTuple_Pack(3, _data->algo, arr, size);
    PyObject* pValue = PyObject_CallObject(pFunc, pArgs);

    int pred = -1;
    if (pArgs != NULL)
        Py_DECREF(pArgs);
    if (!pValue)
        PyErr_Print();
    else {
        pred = PyLong_AsLong(pValue);
        Py_DECREF(pValue);
    }

    // 0 : inlier / 1 : outlier
    result = pred == 0 ? true : false;
}
Jvre
  • 11
  • 2
  • 1
    For sure many people encountered similar issue, including me. However, it is not possible to give any concrete answer from your description. Try to show some example so we can reproduce it. https://stackoverflow.com/help/how-to-ask – pptaszni Nov 13 '20 at 15:55
  • 1
    In any case, you might want to take a look at [GIL](https://wiki.python.org/moin/GlobalInterpreterLock) – pptaszni Nov 13 '20 at 15:56
  • 1
    The solution I found : https://stackoverflow.com/questions/10625584/embedding-python-in-multithreaded-c-application Thanks. – Jvre Nov 20 '20 at 12:31

0 Answers0