-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
70 changed files
with
8,874 additions
and
72 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,231 @@ | ||
# include "conversion.h" | ||
/* | ||
* The following conversion functions are taken/adapted from OpenCV's cv2.cpp file | ||
* inside modules/python/src2 folder. | ||
*/ | ||
|
||
static void init() | ||
{ | ||
import_array(); | ||
} | ||
|
||
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; | ||
}; | ||
|
||
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; | ||
} | ||
|
||
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 ) | ||
{ | ||
_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; | ||
|
||
NDArrayConverter::NDArrayConverter() { init(); } | ||
|
||
void NDArrayConverter::init() | ||
{ | ||
import_array(); | ||
} | ||
|
||
cv::Mat NDArrayConverter::toMat(const PyObject *o) | ||
{ | ||
cv::Mat m; | ||
|
||
if(!o || o == Py_None) | ||
{ | ||
if( !m.data ) | ||
m.allocator = &g_numpyAllocator; | ||
} | ||
|
||
if( !PyArray_Check(o) ) | ||
{ | ||
failmsg("toMat: Object is not a numpy array"); | ||
} | ||
|
||
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("toMat: Data type = %d is not supported", typenum); | ||
} | ||
|
||
int ndims = PyArray_NDIM(o); | ||
|
||
if(ndims >= CV_MAX_DIM) | ||
{ | ||
failmsg("toMat: Dimensionality (=%d) is too high", ndims); | ||
} | ||
|
||
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) | ||
{ | ||
failmsg("toMat: Object has more than 2 dimensions"); | ||
} | ||
|
||
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 m; | ||
} | ||
|
||
PyObject* NDArrayConverter::toNDArray(const cv::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); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,60 @@ | ||
# ifndef __COVERSION_OPENCV_H__ | ||
# define __COVERSION_OPENCV_H__ | ||
|
||
#include <Python.h> | ||
#include <opencv2/imgproc/imgproc.hpp> | ||
#include <opencv2/highgui/highgui.hpp> | ||
#include <opencv2/core/core.hpp> | ||
#include "numpy/ndarrayobject.h" | ||
|
||
static PyObject* opencv_error = 0; | ||
|
||
static int failmsg(const char *fmt, ...); | ||
|
||
class PyAllowThreads; | ||
|
||
class PyEnsureGIL; | ||
|
||
#define ERRWRAP2(expr) \ | ||
try \ | ||
{ \ | ||
PyAllowThreads allowThreads; \ | ||
expr; \ | ||
} \ | ||
catch (const cv::Exception &e) \ | ||
{ \ | ||
PyErr_SetString(opencv_error, e.what()); \ | ||
return 0; \ | ||
} | ||
|
||
static PyObject* failmsgp(const char *fmt, ...); | ||
|
||
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; | ||
|
||
enum { ARG_NONE = 0, ARG_MAT = 1, ARG_SCALAR = 2 }; | ||
|
||
class NDArrayConverter | ||
{ | ||
private: | ||
void init(); | ||
public: | ||
NDArrayConverter(); | ||
cv::Mat toMat(const PyObject* o); | ||
PyObject* toNDArray(const cv::Mat& mat); | ||
}; | ||
|
||
# endif |
File renamed without changes.
File renamed without changes.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.