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;
}