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 になっています。2 つの 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メソッドは、リストにパックされたピクセルを1行ずつ返します。(実行しているように)列優先の順序でそれらが必要な場合は、.transpose最初に適切な引数を指定して適用します。結果は、すべてのピクセルを反復処理するよりも大幅に高速で単純です。

于 2012-09-08T01:17:35.753 に答える
0

この問題は、私のコンピューターのPythonバージョン2.7が原因である可能性があります。私はPython3.2に変更しましたが、すべてのコードが理想的なリターンを得ることができます。

于 2012-09-13T10:21:52.257 に答える
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

からの戻り値をチェックしていませんPyObject_CallObjectNULL(Python 例外)が返された可能性があり、その結果、dataリストの変更に失敗しました。

インタープリターを正しく動作させるには例外処理が非常に重要であるため、実行するすべてのPython API 呼び出しを確認する必要があります。

を取得した場合はNULL、 を呼び出しPyErr_Print()てトレースバックをstderr( cerr) に出力できます。

于 2012-09-08T03:23:04.163 に答える