0

添加嵌入python的c/c++代码。所有问题都在c代码中,我不知道如何获取像素值。

蟒蛇代码:

import Image

format = ""
mode = ""
size = ""
data = list()

def getImage(file):
    im = Image.open(file)
    global format
    global mode
    global size
    global data
    format = im.format
    mode = im.mode
    size = im.size

    width, height = im.size

    for x in range(0, height):
        for y in range(0, width):
            data.append(im.getpixel((x,y)))
    return None

在 C/C++ 代码中我得到的数据长度是 0。这两个 for 循环有什么问题吗?

void loadImage(char *file) {
    Image* img = NULL;
    Py_Initialize();
    if ( !Py_IsInitialized() ) {
        std::cerr<<"Python initalize failed.\n";
        return NULL;
    }
    PyRun_SimpleString("import sys");
    PyRun_SimpleString("sys.path.append('./')");

    PyObject *pName, *pModule, *pFunc, *pArgs;
    pName = PyString_FromString("loadImage");
    pModule = PyImport_Import(pName);
    Py_DECREF(pName);
    if ( !pModule ) {
        PyErr_Print();
        std::cerr<<"import loadImage module faild, please confirm where the file     'loadImage.py' is.\n";
        return NULL;
    }
    pFunc = PyObject_GetAttrString(pModule, "getImage");
    if ( !pFunc ) {
        PyErr_Print();
        std::cerr<<"Can't find method getImage in loadImage module.\n";
        return NULL;
    }

    pArgs = PyTuple_New(1);
    PyTuple_SetItem(pArgs, 0, Py_BuildValue("s", file));
    PyObject_CallObject(pFunc, pArgs);

    PyObject *pFormat, *pMode, *pSize, *pData, *pSeq, *pPixel;

    pFormat = PyObject_GetAttrString(pModule, "format"); 

    pMode = PyObject_GetAttrString(pModule, "mode");

    pSize = PyObject_GetAttrString(pModule, "size");

    if ( !PyTuple_Check(pSize) ) {
        std::cerr<<"pSize is not tupple object.\n";
        return NULL;
    }

    pData = PyObject_GetAttrString(pModule, "data");
    if ( !pData ) {
        std::cerr<<"pData is null.\n";
        return NULL;
    }
    if ( !PyList_Check(pData) ) {
        std::cerr<<"pData is not list object.\n";
        return NULL;
    }

    int n = PyList_GET_SIZE(pData);
    std::cerr<<n<<"\n";

    Py_DECREF(pData);
    Py_DECREF(pFunc);
    Py_DECREF(pModule);
    Py_DECREF(pArgs);

    std::cerr<<"Py_DECREF over.\n";
}

我得到 pData(is n) 的长度为 0。

4

4 回答 4

1

好吧,您的代码实际上可以用一行替换:

data = list(Image.open(file).getdata())

Image 对象的getdata方法逐行返回打包到列表中的像素。如果您需要它们以列优先顺序(正如您所做的那样),请先应用.transpose适当的参数。结果仍然比遍历所有像素要快得多,也更简单。

于 2012-09-08T01:17:35.753 回答
0

您没有检查PyObject_CallObject. 它可能已返回NULL(Python 异常),因此无法修改data列表。

您应该检查您进行的每个Python API 调用,因为异常处理对于使解释器正常工作至关重要。

如果你确实得到一个NULL,你可以调用PyErr_Print()将回溯打印到stderr( cerr)。

于 2012-09-08T03:23:04.163 回答
0

您通过调用运行的 Python 代码PyObject_CallObject可能会引发异常。

NULL 表示抛出异常。您可以使用各种 python api 函数来获取实际错误:http ://docs.python.org/c-api/exceptions.html 。这可能是最简单的。

if( PyObject_CallObject(pFunc, pArgs ) == NULL )
{
    // Print the exception (a traceback may or may not be available)
    PyErr_Print();

    // Do any cleanup...

    // Always return NULL after a python api function returns NULL.
    return NULL;
}
于 2012-09-08T04:40:45.007 回答
0

这个问题可能是我电脑中的python 2.7版本引起的。我改用python 3.2,所有代码都能得到理想的回报。

于 2012-09-13T10:21:52.257 回答