2012-12-06 121 views
3

我遇到了一個問題,試圖公開與OpenCV鏈接並使用OpenCV的數據類型OpenCV的動態C++庫函數,使用Numpy ndarray將基於OpenCV的C++函數與Mat/Numpy轉換爲Python

我拿出類似lightalchemist's solution here一個解決方案,我已經使用boost ::蟒蛇和boost :: numpy的(也與Python 2.7版)described in this SO question.

現在我有堅持也嘗試前者。我已經到了可以在iPython中加載模塊的地步,並且我看到了一個函數,我試圖使用檢查模塊進行移植,我甚至可以調用它並執行。但是,特別是當我嘗試使用NumpyAllocatorsee lightalchemist's solution)類將對象轉換回到ndarray時,會發生此問題。 首先,當我嘗試從外部C++可執行調用pyopencv_from功能,它採用了NumpyAllocator,因爲它的編碼,它出現segfaults在

PyEnsureGIL gil; 

,沒有消息,每一次。 Lightalchemist的解決方案不使用它在pyopencv_to(編輯:如果ndarray傳入已被分配),它似乎工作。然而,官方OpenCV cv2.cpp也使用allocator,所以如果我嘗試使用該函數甚至不能將輸入的ndarray轉換爲Mat。

當我嘗試使用iPython中的模塊時,它會看到該函數。再次,它正確地執行它(打印進程到控制檯),但是當它到達pyopencv_from時,它會發生段錯誤並殺死iPython shell。

編輯:我使用exaclty相同源lightalchemist,除了我露出一個功能單一,方式與官方OpenCV的端口相同的作用:

static PyMethodDef methods[] = { 
{"findEdgesCGTG", (PyCFunction)pycvex_findEdgesCGTG, METH_KEYWORDS, "findEdgesCGTG(source) -> edgeGradient, edgeOrientations"}, 
    {NULL, NULL} 
}; 
extern "C" 
#if defined WIN32 || defined _WIN32 
__declspec(dllexport) 
#endif 
void initcvex() 
{ 
    import_array(); 
    PyObject* m = Py_InitModule(MODULESTR, methods); 
    PyObject* d = PyModule_GetDict(m); 
    opencv_error = PyErr_NewException((char*)MODULESTR".error", NULL, NULL); 
    PyDict_SetItemString(d, "error", opencv_error); 
} 

有沒有人對如何任何線索解決這個轉換問題?

回答

2

問題是不是

PyEnsureGIL gil; 

聲明。這隻有在我嘗試使用外部C++函數時才起作用。這個問題實際上發生了,當我環顧了兩個輸出值到一個位置:

return Py_BuildValue("(NN)", pyopencv_from(edgeGrad), pyopencv_from(edgeOri)); 

的臨時解決只是使用下面的語句:

return pyopencv_from(edgeGrad); 

編輯: 對不起,我搞砸再起。 Py_BuildValue工作得很好。只是再次測試我的功能,它完美的作品。上一次我測試它時,我一定忘記了使用return關鍵字,所以它給了我「錯誤返回無例外設置。「

下面是完整的功能代碼(我希望這是任何人都移植OpenCV的東西蟒蛇有用)

static PyObject* pycvex_findEdgesCGTG(PyObject* , PyObject* args, PyObject* kw) 
{ 
    PyObject* pyobj_source = NULL; 
    Mat source; 
    Mat edgeGrad; 
    Mat edgeOri; 
    const char* keywords[] = { "src", NULL }; 
    if(PyArg_ParseTupleAndKeywords(args, kw, "O:findEdgesCGTG", (char**)keywords, &pyobj_source) && 
     pyopencv_to(pyobj_source, source)); 
    { 
     ERRWRAP2(findEdgesCGTG(source,edgeGrad,edgeOri)); 
     return Py_BuildValue("(NN)", pyopencv_from(edgeGrad), pyopencv_from(edgeOri)); 
    } 
    return NULL; 
} 

UPDATE:

這裏是github repo與開放的C++代碼,我寫的使用OpenCV的Mat類暴露代碼儘可能少的痛苦。這是爲OpenCV 3.X

對於OpenCV 2.X,您可以使用Yati Sagade的示例this code。如果您想使用opencv Mat類而不使用,並且擔心顯式轉換,可以很容易地將我的代碼中的Booost轉換器與Yati代碼中的轉換函數相匹配。

+0

嗨。也許你可以提供更多的語境你的構建參數,調用代碼等等。你提到在iPython中運行代碼時會崩潰。將它作爲獨立運行,即使用普通的Python解釋器怎麼樣?在這種情況下它也會崩潰嗎? – lightalchemist

+0

@lightalchemist,我會在問題中發佈構建參數和代碼。謝謝你回到我身旁。它並不真正崩潰在ipython(只是外部測試可執行文件),只是給我「沒有例外設置的錯誤返回。」 –