Скрипт Python застрял при достижении функций CV2 - PullRequest
4 голосов
/ 16 мая 2019

Я пытаюсь вызвать сценарий Python из C ++ с использованием boost: python.

вызывается модуль и класс, и все работает нормально, пока сценарий не достигнет функции, которая использует opencv

C ++ код для вызова Python является частью класса, который запускается через поток.кодовая часть для вызова python:

#include <boost/python.hpp>
#include "boost/python/stl_iterator.hpp"

#include <opencv2/opencv.hpp>

...

imencode(".jpg", image, imageBuffer);

namespace python = boost::python;

vector<unsigned char>::iterator iter;
python::list list;
for (iter = imageBuffer.begin(); iter != imageBuffer.end(); ++iter) {
    list.append(*iter);
}


python::object python_module = python::import("file");
python::object klass = python_module.attr("klass")(this->modelPath.c_str());
python::object res =  klass.attr("fun")(list);

file.py выглядит следующим образом:

import numpy as np
import cv2
class klass:

    def __init__(self, model_path):

        self.model = model_path

    def fun(self, image):

        image = np.asarray(image, dtype=np.uint8)
        print("b4")
        image = cv2.imdecode(image, 1)
        print("after")
        return 1

Строка "print (" b4 ")" печатается, но как только imdecode достигнуткод застрял и ничего не происходит

opencv-python установлен с использованием

sudo pip3 install opencv-python

версия opencv-python 4.1.0, версия numpy - 1.16.3

IЯ использую Python 3,5

, почему код приходит на паузу и как решить, что

РЕДАКТИРОВАТЬ

Мне просто нужно упомянуть, что вызовсделано из потока.Если вызов сделан из Main, код работает.Этот код вызывается через pthread_create ()

Похоже, мне что-то не хватает в потоке

РЕДАКТИРОВАТЬ 2

Так что это действительно проблема с потоками иЯ разобрался с «решением», который выложу в качестве ответа.Я не знаю, правильный ли это способ решения этой проблемы, но он работает

1 Ответ

1 голос
/ 20 мая 2019

Чтобы решить эту проблему, я добавил следующее после py_initialize

Py_Initialize();
PyEval_InitThreads();
PyEval_ReleaseLock();

затем, когда начинается поток, я сделал:

PyGILState_STATE gstate;
gstate = PyGILState_Ensure();

тогда сделайте все вызовы Python ....

в конце разговора

PyGILState_Release(gstate);

Обратите внимание, что любые вызовы Python (даже вызовы DECREF) после PyGILState_Release () не будут работать и вызывать сбой кода, поэтому я поместил этот вызов в свой деструктор класса с резьбой как последнюю вещь для вызова.

...