2012-08-07 82 views
5

的OpenCV可以與pythonbindings使用,它工作得很好。但是我想知道(希望真的)是否有可能在python中使用OpenCv's stitcher。我已經嘗試了幾件事,但無法讓它起作用。如果可能的話,我可能需要做額外的導入,但我無法弄清楚,谷歌也沒有給我答案。希望有一位能夠幫助我的opencv-python專家。使用OpenCV的拼接蟒蛇

+0

嘿,我知道這可能有點晚了你,但是我現在想要在python中使用opencv Stitcher。我已經想出瞭如何從opencv python API中「丟失」其他opencv類,並且我之前完成了它。如果我最終將拼接器指向python,我會在今天結束。 – 2012-12-20 15:57:34

回答

1

好了,所以,我想通了最後。到目前爲止,我只用兩個參數移植了針法,問我是否無法展示任何可能需要的東西。

構建它的最簡單方法是通過以位置無關的方式(gcc的-fPIC選項)編譯所有內容到動態庫中,同時鏈接opencv_core和opencv_stitching庫。你還必須添加包含你正在構建的任何版本的Python的include目錄,以便它可以找到正確的Python.h頭文件。

如果你建立正確的話,你就可以使用編譯庫相同的方式,你可以使用一個Python模塊。

不幸的是,因爲它們不提供訪問的構造,我已經滿足於做的事情的全局實例。如果還有另一種優雅的方式,我就是耳朵(眼睛)。 這意味着無論何時調用.Stitcher()構造函數,它都會返回相同的實例(在構建期間有一個單獨的實例試圖使用GPU,對此使用.Stitcher(True))。

這是我的pythonPort.h文件:

/* 
* File: pythonPort.h 
* Author: algomorph 
* 
* Created on December 5, 2012, 10:18 AM 
*/ 

#ifndef PYTHONPORT_H 
#define PYTHONPORT_H 

#define MODULESTR "mycv" 


#include "Python.h" 
#include "numpy/ndarrayobject.h" 
#include <opencv2/core/core.hpp> 
#include <opencv2/stitching/stitcher.hpp> 
/* 
//include your own custom extensions here 
#include "savgol.h" 
#include "filters.hpp" 
*/ 
#include "pythonPortAux.h" 

#endif 

MODULESTR應該是你希望把你的模塊什麼的。我保持它與它編譯的庫的名稱相同。

你必須複製你從cv2.cpp文件所需要的任何opencv_to和opencv_from程序並投入像我pythonPortAux.h。我有很多例程,你可以找到它at this link。 MKTYPE2宏也在那裏。

剩下的就是在這裏下pythonPort.cpp文件中(我有其他的東西存在,這只是縫合器相關的部分):

#include "pythonPort.h" 

struct pycvex_Stitcher_t 
{ 
    PyObject_HEAD 
    Ptr<cv::Stitcher> v; 
}; 

static PyTypeObject pycvex_Stitcher_Type = 
{ 
    PyObject_HEAD_INIT(&PyType_Type) 
    0, 
    MODULESTR".Stitcher", 
    sizeof(pycvex_Stitcher_t), 
}; 

static void pycvex_Stitcher_dealloc(PyObject* self) 
{ 
    //((pycvex_Stitcher_t*)self)->v.release(); 
    PyObject_Del(self); 
} 

static PyObject* pyopencv_from(const Ptr<cv::Stitcher>& r) 
{ 
    pycvex_Stitcher_t *m = PyObject_NEW(pycvex_Stitcher_t, &pycvex_Stitcher_Type); 
    new (&(m->v)) Ptr<cv::Stitcher>(); // init Ptr with placement new 
    m->v = r; 
    return (PyObject*)m; 
} 

static bool pyopencv_to(PyObject* src, Ptr<cv::Stitcher>& dst, const char* name="<unknown>") 
{ 
    if(src == NULL || src == Py_None) 
     return true; 
    if(!PyObject_TypeCheck(src, &pycvex_Stitcher_Type)) 
    { 
     failmsg("Expected cv::Stitcher for argument '%s'", name); 
     return false; 
    } 
    dst = ((pycvex_Stitcher_t*)src)->v; 
    return true; 
} 

static PyObject* pycvex_Stitcher_repr(PyObject* self) 
{ 
    char str[1000]; 
    sprintf(str, "<Stitcher %p>", self); 
    return PyString_FromString(str); 
} 

Stitcher gStitcher = cv::Stitcher::createDefault(false); 
Stitcher gStitcherGPU = cv::Stitcher::createDefault(true); 

static PyObject* pycvex_Stitcher_Stitcher(PyObject* , PyObject* args, PyObject* kw) 
{ 
    PyErr_Clear(); 
    { 
     pycvex_Stitcher_t* self = 0; 
     bool try_use_gpu = false; 

     const char* keywords[] = { "img", "pt1", "pt2","connectivity","leftToRight", NULL }; 
     if (PyArg_ParseTupleAndKeywords(args, kw, "|b:Stitcher", 
       (char**) keywords, &try_use_gpu)){ 
      self = PyObject_NEW(pycvex_Stitcher_t, &pycvex_Stitcher_Type); 
      if (self) 
       ERRWRAP2(
         if(try_use_gpu) 
          self->v = &gStitcherGPU; 
         else 
          self->v = &gStitcher; 
         ); 
      return (PyObject*) self; 
     } 
    } 
    return NULL; 
} 
static PyGetSetDef pycvex_Stitcher_getseters[] = 
{ 
    {NULL} /* Sentinel */ 
}; 

static PyObject* pycvex_Stitcher_stitch(PyObject* self, PyObject* args, PyObject* kw){ 
    if(!PyObject_TypeCheck(self, &pycvex_Stitcher_Type)) 
     return failmsgp("Incorrect type of self (must be 'Stitcher' or its derivative)"); 
    Stitcher* _self_ = ((pycvex_Stitcher_t*)self)->v; 
    //Stitcher::Status status; 
    int status; 

    PyObject* pyobj_images = NULL; 
    vector<Mat> images = vector<Mat>(); 
    Mat pano; 

    const char* keywords[] = { "images", NULL }; 
    if(PyArg_ParseTupleAndKeywords(args, kw, "O:Stitcher.stitch", (char**)keywords, &pyobj_images) && 
     pyopencv_to(pyobj_images, images, ArgInfo("images", false))) 
    { 
     ERRWRAP2(status = (int)_self_->stitch(images, pano)); 
     return Py_BuildValue("(NN)", pyopencv_from(status), pyopencv_from(pano)); 
    } 

    return NULL; 
} 

static PyMethodDef pycvex_Stitcher_methods[] = 
{ 
    {"stitch", (PyCFunction)pycvex_Stitcher_stitch, METH_KEYWORDS, "stitch(image) -> status, pano"}, 
    {NULL, NULL} 
}; 

static void pycvex_Stitcher_specials(void) 
{ 
    pycvex_Stitcher_Type.tp_base = NULL; 
    pycvex_Stitcher_Type.tp_dealloc = pycvex_Stitcher_dealloc; 
    pycvex_Stitcher_Type.tp_repr = pycvex_Stitcher_repr; 
    pycvex_Stitcher_Type.tp_getset = pycvex_Stitcher_getseters; 
    pycvex_Stitcher_Type.tp_methods = pycvex_Stitcher_methods; 
} 


static PyMethodDef methods[] = { 
    {"Stitcher",(PyCFunction)pycvex_Stitcher_Stitcher, METH_KEYWORDS, "Stitcher([tryUseGpu=False]) -> <Stitcher object>"}, 
    {NULL, NULL} 
}; 

extern "C"{ 
    #if defined WIN32 || defined _WIN32 
    __declspec(dllexport) 
    #endif 
    void initcvex() 
    { 
     MKTYPE2(Stitcher); 
     import_array(); 
     PyObject* m = Py_InitModule(MODULESTR, methods); 
     PyObject* d = PyModule_GetDict(m); 
     //PyDict_SetItemString(d, "__version__", PyString_FromString(CV_VERSION)) 
     opencv_error = PyErr_NewException((char*)MODULESTR".error", NULL, NULL); 
     PyDict_SetItemString(d, "error", opencv_error); 
    } 
} 
+0

看起來這可能是有用的,但我遇到了一些麻煩。 'filters.hpp'和'savgol.h'在哪裏?我也收到有關'python27_d.lib'的錯誤。有什麼建議麼? – speedplane 2013-02-25 03:13:00

+0

對不起,你不需要那些(filters.hpp和savgol.h)。這些僅僅是我爲opencv添加的擴展,用於Berkley邊緣檢測。我從上面的代碼中評論了他們。 – 2013-02-25 17:16:13

+0

至於python27_d.lib-當你試圖在Debug模式下編譯任何引用opencv的東西時,Windows平臺就會出現這個問題。對於典型的python windows安裝,不包括這個庫。您可以手動重新配置opencv的python綁定項目來使用python2.lib,或者嘗試引用發佈版本。如果你使用它真正的意圖,請查閱本SO帖子:http://stackoverflow.com/questions/10315662/how-to-obtain-pre-built-debug-version-of-python-library-eg-python27 -d-dll – 2013-02-25 17:20:40