Как получить Python возвращаемые значения в C? - PullRequest
0 голосов
/ 06 марта 2019

Я пытаюсь передать изображение из C в Python и передать массив обратно из Python в C и получить длину и данные внутри него.Вот мой код Python:

def detect(pI,col,row,channels):
    I_reshape = np.asarray(list(pI), dtype=np.ubyte)
    I_reshape = np.reshape(I_reshape,(row,col,channels))
    cv2.imshow("testWin",I_reshape)
    cv2.waitKey(0)

    a = np.arange(4).reshape((2, 2))
    return a;

, а это мой код C:

#include <python.h>
#include <direct.h>
#include <opencv2\opencv.hpp>
#include <opencv2\core\core.hpp>
#include <opencv2\highgui\highgui.hpp>
#include <stdio.h>

using namespace std;

int main(int argc, char *argv[])
{
    PyObject *pName, *pModule, *pFunc;
    PyObject *pArgs, *pArg, *pResult;

    Py_Initialize();
    pName = PyUnicode_DecodeFSDefault("getArray");
    pModule = PyImport_Import(pName);
    Py_DECREF(pName);
    pFunc = PyObject_GetAttrString(pModule, "returnArray");
    pArgs = PyTuple_New(4);
    pArg = PyByteArray_FromStringAndSize((char*)img.data, img.total() * img.elemSize());
    PyTuple_SetItem(pArgs, 0, pArg);
    PyTuple_SetItem(pArgs, 1, PyLong_FromLong(img.cols));
    PyTuple_SetItem(pArgs, 2, PyLong_FromLong(img.rows));
    PyTuple_SetItem(pArgs, 3, PyLong_FromLong(img.channels()));
    pResult = PyObject_CallObject(pFunc, pArgs);

    int SIZE = PyByteArray_Size(pResult);
    Py_XDECREF(pResult);
    uint *data = (uint *)PyByteArray_AsString(pResult);
    Py_XDECREF(pResult);

    printf("Return of call (size): %d\n", SIZE/sizeof(uint)); 
    printf("Return of call (data): %d\n", data[0]);

    Py_DECREF(pResult);
    return 0;
}

Проблема в том, что я получаю правильный размер, но я получаю только нулевые данные.Где я не прав?

1 Ответ

0 голосов
/ 07 марта 2019

Я решил свою проблему, используя списки в качестве аргумента возврата C. Если вы list() возвращаете значение, оно будет работать нормально:

a = np.array([[1.1,1.2],[2.1,2.2],[3.1,3.2],[4.1,4.2]]).reshape(8,1);
return list(a);

Тогда в C я делаю как:

int main(int argc, char *argv[])
{
    PyObject *pName, *pModule, *pFunc;
    PyObject *pArgs, *pArg, *pResult;
    int i = 0, j = 0;

    cv::Mat img;
    img = cv::imread("..\\..\\x64\\Release\\1.jpg",1);

    Py_Initialize();
    pName = PyUnicode_DecodeFSDefault("showImage");
    pModule = PyImport_Import(pName);
    Py_DECREF(pName);
    pFunc = PyObject_GetAttrString(pModule, "detect");

    pArgs = PyTuple_New(4);
    pArg = PyByteArray_FromStringAndSize((char*)img.data, img.total() * img.elemSize());
    PyTuple_SetItem(pArgs, 0, pArg);
    PyTuple_SetItem(pArgs, 1, PyLong_FromLong(img.cols));
    PyTuple_SetItem(pArgs, 2, PyLong_FromLong(img.rows));
    PyTuple_SetItem(pArgs, 3, PyLong_FromLong(img.channels()));

    pResult = PyObject_CallObject(pFunc, pArgs);
    Py_DECREF(pArgs);

    if (PyList_Check(pResult)) {
        int SIZE = PyList_Size(pResult);
        float *arr = new float(SIZE);
        for (i = 0; i < SIZE; i++) arr[i] = PyFloat_AsDouble(PyList_GetItem(pResult, i));

        for (i = 0; i < SIZE / 2; i++) {
            for (j = 0; j < 2; j++) {
                printf("%f, ", arr[i * 2 + j]);
            }
            printf("\n");
        }
    }

    return 0;
}

, в котором последние 14 строк получают возвращенный список и извлекают его элементы.

...