2012-10-18 7 views
17

का उपयोग करता है, मैं कुछ सी ++ कोड के लिए एक पायथन रैपर लिखने की कोशिश कर रहा हूं जो ओपनसीवी का उपयोग करता है लेकिन मुझे परिणाम लौटने में कठिनाइयों का सामना करना पड़ रहा है, जो ओपनसीवी सी ++ मैट ऑब्जेक्ट है, पायथन दुभाषिया।सी ++ कोड के लिए पायथन बाइंडिंग लिखना जो OpenCV

मैंने ओपनसीवी के स्रोत को देखा है और फ़ाइल cv2.cpp पाया है जिसमें रूपांतरणों को PyObject * और OpenCV's Mat के बीच रूपांतरण करने के लिए रूपांतरण किया गया है। मैंने उन रूपांतरण कार्यों का उपयोग किया लेकिन जब मैंने उनका उपयोग करने की कोशिश की तो एक सेगमेंटेशन गलती मिली।

मुझे मूल रूप से ओपनसीवी का उपयोग करने वाले पाइथन और सी ++ कोड को इंटरफ़ेस करने के तरीके पर कुछ सुझाव/नमूना कोड/ऑनलाइन संदर्भों की आवश्यकता होती है, विशेष रूप से ओपनसीवी के सी ++ मैट को पायथन दुभाषिया में वापस करने की क्षमता या शायद कैसे/कहां पर सुझाव सेगमेंटेशन गलती के कारण की जांच शुरू करें।

वर्तमान में मैं कोड को लपेटने के लिए बूस्ट पायथन का उपयोग कर रहा हूं।

किसी भी उत्तर के लिए अग्रिम धन्यवाद।

प्रासंगिक कोड:

// This is the function that is giving the segmentation fault. 
PyObject* ABC::doSomething(PyObject* image) 
{ 
    Mat m; 
    pyopencv_to(image, m); // This line gives segmentation fault. 

    // Some code to create cppObj from CPP library that uses OpenCV 
    cv::Mat processedImage = cppObj->align(m); 

    return pyopencv_from(processedImage); 
} 

रूपांतरण कार्यों OpenCV के स्रोत से लिया इस प्रकार है। रूपांतरण कोड "अगर (! PyArray_Check (o)) ..." के साथ टिप्पणी लाइन पर सेगमेंटेशन गलती देता है।

static int pyopencv_to(const PyObject* o, Mat& m, const char* name = "<unknown>", bool allowND=true) 
{ 
    if(!o || o == Py_None) 
    { 
     if(!m.data) 
      m.allocator = &g_numpyAllocator; 
     return true; 
    } 

    if(!PyArray_Check(o)) // Segmentation fault inside PyArray_Check(o) 
    { 
     failmsg("%s is not a numpy array", name); 
     return false; 
    } 

    int typenum = PyArray_TYPE(o); 
    int type = typenum == NPY_UBYTE ? CV_8U : typenum == NPY_BYTE ? CV_8S : 
       typenum == NPY_USHORT ? CV_16U : typenum == NPY_SHORT ? CV_16S : 
       typenum == NPY_INT || typenum == NPY_LONG ? CV_32S : 
       typenum == NPY_FLOAT ? CV_32F : 
       typenum == NPY_DOUBLE ? CV_64F : -1; 

    if(type < 0) 
    { 
     failmsg("%s data type = %d is not supported", name, typenum); 
     return false; 
    } 

    int ndims = PyArray_NDIM(o); 
    if(ndims >= CV_MAX_DIM) 
    { 
     failmsg("%s dimensionality (=%d) is too high", name, ndims); 
     return false; 
    } 

    int size[CV_MAX_DIM+1]; 
    size_t step[CV_MAX_DIM+1], elemsize = CV_ELEM_SIZE1(type); 
    const npy_intp* _sizes = PyArray_DIMS(o); 
    const npy_intp* _strides = PyArray_STRIDES(o); 
    bool transposed = false; 

    for(int i = 0; i < ndims; i++) 
    { 
     size[i] = (int)_sizes[i]; 
     step[i] = (size_t)_strides[i]; 
    } 

    if(ndims == 0 || step[ndims-1] > elemsize) { 
     size[ndims] = 1; 
     step[ndims] = elemsize; 
     ndims++; 
    } 

    if(ndims >= 2 && step[0] < step[1]) 
    { 
     std::swap(size[0], size[1]); 
     std::swap(step[0], step[1]); 
     transposed = true; 
    } 

    if(ndims == 3 && size[2] <= CV_CN_MAX && step[1] == elemsize*size[2]) 
    { 
     ndims--; 
     type |= CV_MAKETYPE(0, size[2]); 
    } 

    if(ndims > 2 && !allowND) 
    { 
     failmsg("%s has more than 2 dimensions", name); 
     return false; 
    } 

    m = Mat(ndims, size, type, PyArray_DATA(o), step); 

    if(m.data) 
    { 
     m.refcount = refcountFromPyObject(o); 
     m.addref(); // protect the original numpy array from deallocation 
        // (since Mat destructor will decrement the reference counter) 
    }; 
    m.allocator = &g_numpyAllocator; 

    if(transposed) 
    { 
     Mat tmp; 
     tmp.allocator = &g_numpyAllocator; 
     transpose(m, tmp); 
     m = tmp; 
    } 
    return true; 
} 

static PyObject* pyopencv_from(const Mat& m) 
{ 
    if(!m.data) 
     Py_RETURN_NONE; 
    Mat temp, *p = (Mat*)&m; 
    if(!p->refcount || p->allocator != &g_numpyAllocator) 
    { 
     temp.allocator = &g_numpyAllocator; 
     m.copyTo(temp); 
     p = &temp; 
    } 
    p->addref(); 
    return pyObjectFromRefcount(p->refcount); 
} 

मेरे अजगर परीक्षण कार्यक्रम:

import pysomemodule # My python wrapped library. 
import cv2 

def main(): 
    myobj = pysomemodule.ABC("faces.train") # Create python object. This works. 
    image = cv2.imread('61.jpg') 
    processedImage = myobj.doSomething(image) 
    cv2.imshow("test", processedImage) 
    cv2.waitKey() 

if __name__ == "__main__": 
    main() 

उत्तर

29

इसलिए मैंने सोचा कि मैं दूसरों जो एक ही समस्या हो सकती है के साथ यहाँ यह साझा करेंगे मैं समस्या हल हो।

असल में, सेगमेंटेशन गलती से छुटकारा पाने के लिए, मुझे numpy's import_array() फ़ंक्शन को कॉल करने की आवश्यकता है।

"उच्च स्तर" अजगर से सी ++ कोड को चलाने के लिए दृश्य यह है:

मान लीजिए आप अजगर में एक समारोह foo(arg) है कि कुछ सी ++ समारोह के लिए एक बाध्यकारी है। जब आप foo(myObj) पर कॉल करते हैं, तो पाइथन ऑब्जेक्ट "myObj" को आपके सी ++ कोड पर कार्य करने के लिए कुछ कोड होना चाहिए। यह कोड आमतौर पर SWIG या बूस्ट :: पायथन जैसे टूल का उपयोग करके अर्द्ध स्वचालित रूप से बनाया जाता है। (मैं नीचे दिए गए उदाहरणों में बूस्ट :: पायथन का उपयोग करता हूं।)

अब, foo(arg) कुछ सी ++ फ़ंक्शन के लिए एक पायथन बाध्यकारी है। यह सी ++ फ़ंक्शन एक तर्क के रूप में एक सामान्य PyObject पॉइंटर प्राप्त करेगा। आपको PyObject पॉइंटर को "समतुल्य" C++ ऑब्जेक्ट में कनवर्ट करने के लिए C++ कोड होना होगा। मेरे मामले में, मेरा पायथन कोड ओपनसीवी छवि के लिए ओपनसीवी छवि के लिए एक तर्क के रूप में एक ओपनसीवी numpy सरणी पास करता है। सी ++ में "समतुल्य" रूप ओपनसीवी सी ++ मैट ऑब्जेक्ट है। ओपनसीवी PyObject पॉइंटर (numpy सरणी का प्रतिनिधित्व) को C++ Mat में कनवर्ट करने के लिए cv2.cpp (नीचे पुन: उत्पादित) में कुछ कोड प्रदान करता है। इंट और स्ट्रिंग जैसे सरल डेटा प्रकारों को उपयोगकर्ता को इन रूपांतरण कार्यों को लिखने की आवश्यकता नहीं होती क्योंकि वे स्वचालित रूप से बूस्ट :: पायथन द्वारा परिवर्तित होते हैं।

PyObject पॉइंटर के बाद एक उपयुक्त सी ++ रूप में परिवर्तित किया गया है, सी ++ कोड उस पर कार्य कर सकता है। जब डेटा को सी ++ से पायथन तक वापस किया जाना है, तो एक समान स्थिति उत्पन्न होती है जहां सी ++ कोड को डेटा के सी ++ प्रतिनिधित्व को PyObject के रूप में परिवर्तित करने के लिए आवश्यक है। बूस्ट :: पायथन PyObject को एक संबंधित पायथन रूप में परिवर्तित करने के लिए बाकी का ख्याल रखेगा। जब foo(arg) पाइथन में परिणाम देता है, तो यह एक प्रकार के रूप में अजगर द्वारा प्रयोग योग्य है। बस।

नीचे दिया गया कोड दिखाता है कि सी ++ कक्षा "एबीसी" को कैसे लपेटें और अपनी विधि "डूसमिंग" का पर्दाफाश करें जो पाइथन से एक अंजीर सरणी (छवि के लिए) में ले जाता है, इसे ओपनसीवी के सी ++ मैट में परिवर्तित करें, कुछ प्रोसेसिंग करें, कन्वर्ट करें परिणाम PyObject * के लिए, और इसे अजगर दुभाषिया में वापस कर दें। आप जितनी चाहें उतनी फ़ंक्शंस/विधि का पर्दाफाश कर सकते हैं (नीचे दिए गए कोड में टिप्पणियां देखें)।

abc.hpp:

#ifndef ABC_HPP 
#define ABC_HPP 

#include <Python.h> 
#include <string> 

class ABC 
{ 
    // Other declarations 
    ABC(); 
    ABC(const std::string& someConfigFile); 
    virtual ~ABC(); 
    PyObject* doSomething(PyObject* image); // We want our python code to be able to call this function to do some processing using OpenCV and return the result. 
    // Other declarations 
}; 

#endif 

abc.cpp:

#include "abc.hpp" 
#include "my_cpp_library.h" // This is what we want to make available in python. It uses OpenCV to perform some processing. 

#include "numpy/ndarrayobject.h" 
#include "opencv2/core/core.hpp" 

// The following conversion functions are taken from OpenCV's cv2.cpp file inside modules/python/src2 folder. 
static PyObject* opencv_error = 0; 

static int failmsg(const char *fmt, ...) 
{ 
    char str[1000]; 

    va_list ap; 
    va_start(ap, fmt); 
    vsnprintf(str, sizeof(str), fmt, ap); 
    va_end(ap); 

    PyErr_SetString(PyExc_TypeError, str); 
    return 0; 
} 

class PyAllowThreads 
{ 
public: 
    PyAllowThreads() : _state(PyEval_SaveThread()) {} 
    ~PyAllowThreads() 
    { 
     PyEval_RestoreThread(_state); 
    } 
private: 
    PyThreadState* _state; 
}; 

class PyEnsureGIL 
{ 
public: 
    PyEnsureGIL() : _state(PyGILState_Ensure()) {} 
    ~PyEnsureGIL() 
    { 
     PyGILState_Release(_state); 
    } 
private: 
    PyGILState_STATE _state; 
}; 

#define ERRWRAP2(expr) \ 
try \ 
{ \ 
    PyAllowThreads allowThreads; \ 
    expr; \ 
} \ 
catch (const cv::Exception &e) \ 
{ \ 
    PyErr_SetString(opencv_error, e.what()); \ 
    return 0; \ 
} 

using namespace cv; 

static PyObject* failmsgp(const char *fmt, ...) 
{ 
    char str[1000]; 

    va_list ap; 
    va_start(ap, fmt); 
    vsnprintf(str, sizeof(str), fmt, ap); 
    va_end(ap); 

    PyErr_SetString(PyExc_TypeError, str); 
    return 0; 
} 

static size_t REFCOUNT_OFFSET = (size_t)&(((PyObject*)0)->ob_refcnt) + 
    (0x12345678 != *(const size_t*)"\x78\x56\x34\x12\0\0\0\0\0")*sizeof(int); 

static inline PyObject* pyObjectFromRefcount(const int* refcount) 
{ 
    return (PyObject*)((size_t)refcount - REFCOUNT_OFFSET); 
} 

static inline int* refcountFromPyObject(const PyObject* obj) 
{ 
    return (int*)((size_t)obj + REFCOUNT_OFFSET); 
} 

class NumpyAllocator : public MatAllocator 
{ 
public: 
    NumpyAllocator() {} 
    ~NumpyAllocator() {} 

    void allocate(int dims, const int* sizes, int type, int*& refcount, 
        uchar*& datastart, uchar*& data, size_t* step) 
    { 
     PyEnsureGIL gil; 

     int depth = CV_MAT_DEPTH(type); 
     int cn = CV_MAT_CN(type); 
     const int f = (int)(sizeof(size_t)/8); 
     int typenum = depth == CV_8U ? NPY_UBYTE : depth == CV_8S ? NPY_BYTE : 
         depth == CV_16U ? NPY_USHORT : depth == CV_16S ? NPY_SHORT : 
         depth == CV_32S ? NPY_INT : depth == CV_32F ? NPY_FLOAT : 
         depth == CV_64F ? NPY_DOUBLE : f*NPY_ULONGLONG + (f^1)*NPY_UINT; 
     int i; 
     npy_intp _sizes[CV_MAX_DIM+1]; 
     for(i = 0; i < dims; i++) 
     { 
      _sizes[i] = sizes[i]; 
     } 

     if(cn > 1) 
     { 
      /*if(_sizes[dims-1] == 1) 
       _sizes[dims-1] = cn; 
      else*/ 
       _sizes[dims++] = cn; 
     } 

     PyObject* o = PyArray_SimpleNew(dims, _sizes, typenum); 

     if(!o) 
     { 
      CV_Error_(CV_StsError, ("The numpy array of typenum=%d, ndims=%d can not be created", typenum, dims)); 
     } 
     refcount = refcountFromPyObject(o); 

     npy_intp* _strides = PyArray_STRIDES(o); 
     for(i = 0; i < dims - (cn > 1); i++) 
      step[i] = (size_t)_strides[i]; 
     datastart = data = (uchar*)PyArray_DATA(o); 
    } 

    void deallocate(int* refcount, uchar*, uchar*) 
    { 
     PyEnsureGIL gil; 
     if(!refcount) 
      return; 
     PyObject* o = pyObjectFromRefcount(refcount); 
     Py_INCREF(o); 
     Py_DECREF(o); 
    } 
}; 

NumpyAllocator g_numpyAllocator; 

enum { ARG_NONE = 0, ARG_MAT = 1, ARG_SCALAR = 2 }; 

static int pyopencv_to(const PyObject* o, Mat& m, const char* name = "<unknown>", bool allowND=true) 
{ 
    //NumpyAllocator g_numpyAllocator; 
    if(!o || o == Py_None) 
    { 
     if(!m.data) 
      m.allocator = &g_numpyAllocator; 
     return true; 
    } 

    if(!PyArray_Check(o)) 
    { 
     failmsg("%s is not a numpy array", name); 
     return false; 
    } 

    int typenum = PyArray_TYPE(o); 
    int type = typenum == NPY_UBYTE ? CV_8U : typenum == NPY_BYTE ? CV_8S : 
       typenum == NPY_USHORT ? CV_16U : typenum == NPY_SHORT ? CV_16S : 
       typenum == NPY_INT || typenum == NPY_LONG ? CV_32S : 
       typenum == NPY_FLOAT ? CV_32F : 
       typenum == NPY_DOUBLE ? CV_64F : -1; 

    if(type < 0) 
    { 
     failmsg("%s data type = %d is not supported", name, typenum); 
     return false; 
    } 

    int ndims = PyArray_NDIM(o); 
    if(ndims >= CV_MAX_DIM) 
    { 
     failmsg("%s dimensionality (=%d) is too high", name, ndims); 
     return false; 
    } 

    int size[CV_MAX_DIM+1]; 
    size_t step[CV_MAX_DIM+1], elemsize = CV_ELEM_SIZE1(type); 
    const npy_intp* _sizes = PyArray_DIMS(o); 
    const npy_intp* _strides = PyArray_STRIDES(o); 
    bool transposed = false; 

    for(int i = 0; i < ndims; i++) 
    { 
     size[i] = (int)_sizes[i]; 
     step[i] = (size_t)_strides[i]; 
    } 

    if(ndims == 0 || step[ndims-1] > elemsize) { 
     size[ndims] = 1; 
     step[ndims] = elemsize; 
     ndims++; 
    } 

    if(ndims >= 2 && step[0] < step[1]) 
    { 
     std::swap(size[0], size[1]); 
     std::swap(step[0], step[1]); 
     transposed = true; 
    } 

    if(ndims == 3 && size[2] <= CV_CN_MAX && step[1] == elemsize*size[2]) 
    { 
     ndims--; 
     type |= CV_MAKETYPE(0, size[2]); 
    } 

    if(ndims > 2 && !allowND) 
    { 
     failmsg("%s has more than 2 dimensions", name); 
     return false; 
    } 

    m = Mat(ndims, size, type, PyArray_DATA(o), step); 

    if(m.data) 
    { 
     m.refcount = refcountFromPyObject(o); 
     m.addref(); // protect the original numpy array from deallocation 
        // (since Mat destructor will decrement the reference counter) 
    }; 
    m.allocator = &g_numpyAllocator; 

    if(transposed) 
    { 
     Mat tmp; 
     tmp.allocator = &g_numpyAllocator; 
     transpose(m, tmp); 
     m = tmp; 
    } 
    return true; 
} 

static PyObject* pyopencv_from(const Mat& m) 
{ 
    if(!m.data) 
     Py_RETURN_NONE; 
    Mat temp, *p = (Mat*)&m; 
    if(!p->refcount || p->allocator != &g_numpyAllocator) 
    { 
     temp.allocator = &g_numpyAllocator; 
     m.copyTo(temp); 
     p = &temp; 
    } 
    p->addref(); 
    return pyObjectFromRefcount(p->refcount); 
} 

ABC::ABC() {} 
ABC::~ABC() {} 
// Note the import_array() from NumPy must be called else you will experience segmentation faults. 
ABC::ABC(const std::string &someConfigFile) 
{ 
    // Initialization code. Possibly store someConfigFile etc. 
    import_array(); // This is a function from NumPy that MUST be called. 
    // Do other stuff 
} 

// The conversions functions above are taken from OpenCV. The following function is 
// what we define to access the C++ code we are interested in. 
PyObject* ABC::doSomething(PyObject* image) 
{ 
    cv::Mat cvImage; 
    pyopencv_to(image, cvImage); // From OpenCV's source 

    MyCPPClass obj; // Some object from the C++ library. 
    cv::Mat processedImage = obj.process(cvImage); 

    return pyopencv_from(processedImage); // From OpenCV's source 
} 

कोड बूस्ट अजगर का उपयोग करने के अजगर मॉड्यूल बनाने के लिए। मैं इस ले लिया और http://jayrambhia.wordpress.com/tag/boost/ से निम्नलिखित Makefile:

pysomemodule.cpp:

#include <string>  
#include<boost/python.hpp> 
#include "abc.hpp" 

using namespace boost::python; 

BOOST_PYTHON_MODULE(pysomemodule) 
{ 
    class_<ABC>("ABC", init<const std::string &>()) 
     .def(init<const std::string &>()) 
     .def("doSomething", &ABC::doSomething) // doSomething is the method in class ABC you wish to expose. One line for each method (or function depending on how you structure your code). Note: You don't have to expose everything in the library, just the ones you wish to make available to python. 
    ; 
} 

और अंत में, Makefile (सफलतापूर्वक Ubuntu पर संकलित लेकिन कम से कम समायोजन के साथ कहीं और संभवतः काम करना चाहिए)।

PYTHON_VERSION = 2.7 
PYTHON_INCLUDE = /usr/include/python$(PYTHON_VERSION) 

# location of the Boost Python include files and library 
BOOST_INC = /usr/local/include/boost 
BOOST_LIB = /usr/local/lib 

OPENCV_LIB = `pkg-config --libs opencv` 
OPENCV_CFLAGS = `pkg-config --cflags opencv` 

MY_CPP_LIB = lib_my_cpp_library.so 

TARGET = pysomemodule 
SRC = pysomemodule.cpp abc.cpp 
OBJ = pysomemodule.o abc.o 

$(TARGET).so: $(OBJ) 
    g++ -shared $(OBJ) -L$(BOOST_LIB) -lboost_python -L/usr/lib/python$(PYTHON_VERSION)/config -lpython$(PYTHON_VERSION) -o $(TARGET).so $(OPENCV_LIB) $(MY_CPP_LIB) 

$(OBJ): $(SRC) 
    g++ -I$(PYTHON_INCLUDE) -I$(BOOST_INC) $(OPENCV_CFLAGS) -fPIC -c $(SRC) 

clean: 
    rm -f $(OBJ) 
    rm -f $(TARGET).so 

के बाद आप सफलतापूर्वक पुस्तकालय संकलित किया है, तो आप एक फ़ाइल "pysomemodule.so" निर्देशिका में होना चाहिए। इस lib फ़ाइल को अपने पायथन दुभाषिया द्वारा सुलभ जगह पर रखें। इसके बाद आप इस मॉड्यूल आयात और वर्ग "एबीसी" का एक उदाहरण बना सकते हैं इसके बाद के संस्करण इस प्रकार है:

import pysomemodule 

foo = pysomemodule.ABC("config.txt") # This will create an instance of ABC 

अब, एक OpenCV numpy सरणी छवि को देखते हुए, हम सी ++ फ़ंक्शन का उपयोग कर कॉल कर सकते हैं:

processedImage = foo.doSomething(image) # Where the argument "image" is a OpenCV numpy image. 

ध्यान दें कि आप बूस्ट अजगर, Numpy देव, साथ ही अजगर देव पुस्तकालय की जरूरत बाइंडिंग बनाने के लिए होगा।

निम्नलिखित दो लिंक म NumPy डॉक्स एक तरीकों कि रूपांतरण कोड में इस्तेमाल किया गया समझने में सहायता मिलती है और क्यों import_array() बुलाया जाना चाहिए में विशेष रूप से उपयोगी होते हैं। विशेष रूप से, आधिकारिक numpy दस्तावेज़ ओपनसीवी के पायथन बाध्यकारी कोड की भावना बनाने में मददगार है।

http://dsnra.jpl.nasa.gov/software/Python/numpydoc/numpy-13.html http://docs.scipy.org/doc/numpy/user/c-info.how-to-extend.html

आशा इस मदद करता है।

+0

हाय, lightalchemist, अपने समाधान पोस्टिंग के लिए धन्यवाद।मैं ओपनसीवी 2.4.3 के साथ एक ही प्रोबम के समान समाधान पर पहुंचा हूं (pyopencv_to और pvopencv_from से cv2.cpp से फ़ंक्शन ले रहा है), और एक फ़ंक्शन को उजागर कर रहा हूं। मॉड्यूल ipython में ठीक है, फ़ंक्शन वहां दिखाई देता है, यह तर्कों को ठीक से विश्लेषण करता है, लेकिन जैसे ही यह PyEnsureGIL तक पहुंचता है क्रैश हो जाता है। मैंने आपके समाधान की कोशिश की है, और पुराना pyopencv_to फ़ंक्शन काम करता है (यह निष्पादित करता है), लेकिन आउटपुट आउटपुट पर क्रैश होता है। मैं एक अलग सवाल पोस्ट करने जा रहा हूं और एक सेकंड में आपके लिए एक लिंक डालूंगा यदि आपको लगता है कि आप देख सकते हैं कि समस्या क्या है। –

+0

यहां मेरे प्रश्न का लिंक दिया गया है: http://stackoverflow.com/questions/13745265/exposing-opencv-based-c-function-with-mat-numpy-conversion-to-python –

5

मुझे आशा है कि यह लोगों को मदद मिलती एक तेज और आसान तरीका की तलाश में।

यहां खुले सी ++ कोड के साथ github repo है जिसे मैंने ओपनसीवी के मैट क्लास का उपयोग करके कोड को उजागर करने के लिए लिखा था, जितना संभव हो उतना दर्द।

[अपडेट] यह कोड अब OpenCV 2.X और OpenCV 3.X के लिए काम करता है। पायथन 3.X के लिए सीएमके और प्रयोगात्मक समर्थन अब भी उपलब्ध हैं।

+1

आप 3.x संस्करण के लिए कोड है महान! शुरुआत में मैंने सोचा कि इसमें memleak है, लेकिन अंत में यह पता चला कि बग मेरे कोड में था;) और संस्करण 2.xi के लिए इस https://github.com/spillai/numpy-opencv-converter - अच्छा कन्वर्टर्स के साथ कई प्रकार के लिए कोड (जैसे मैट, मैट 3 एफ, प्वाइंट 2 डी आदि - भगवान टेम्पलेट्स आशीर्वाद दें :))। – cyriel

+0

मुझे आपके कोड का उपयोग करके सेगमेंटेशन गलती का भी सामना करना पड़ा। मेरे पायथन कोड _before_ में एक 'आयात pbcvt' जोड़ना मेरे स्वयं के लाइब्रेरी आयात ने आखिरकार इसे ठीक कर दिया। (यह मेरे लिए सहज नहीं है, यह आवश्यक क्यों है, हालांकि, यह है।) –

+0

@ManuCJ, आप सही हैं, यह वास्तव में अजीब है। pbcvt वास्तव में आपकी अपनी लाइब्रेरी के लिए कोड टेम्पलेट के रूप में डिज़ाइन किया गया है। इसलिए, मैं देखता हूं कि पीबीसीवीटी के पास क्या है कि आपके कोड में नहीं है (उनमें से कुछ हेडर और सीपीपी फाइलों में परिभाषित हैं, शायद?)। यदि आप अभी भी उस समस्या से प्रभावित हैं, तो मैं इसे कम से कम कोड उदाहरण के साथ गिटहब पर सबमिट करने की अनुशंसा करता हूं। –

0

एक विकल्प सीधे मॉड्यूल/अजगर/src2/अजगर बाइंडिंग के एक कस्टम शाखा के रूप में cv2.cpp अपने कोड लागू करने के लिए है।

'OpenCV निर्माण प्रणाली एकल "CV2" में यह बंडल होगा। योगदान मॉड्यूल के उदाहरण here हैं। ' https://github.com/opencv/opencv/issues/8872#issuecomment-307136942

संबंधित मुद्दे