Pass pointer between python and C++

Hi guys,

We would like to add some features to png encoding process, so some changes were applied to the C++ function:

CV_EXPORTS_W bool imencode( const String& ext, InputArray img,
                            CV_OUT std::vector<uchar>& buf,
                            const std::vector<int>& params = std::vector<int>(),
                             std::vector<unsigned char*>& workspace);

The obvious change in the parameter list is that we add a vector with point type:

std::vector<unsigned char*>& workspace

However, we cannot build it successfully, and it seems python doesn’t recognize it:

/home/hongbinl/work/PNG_encode_decode/opencv/modules/python/src2/cv2.cpp: In instantiation of 'bool pyopencv_to(PyObject*, T&, const ArgInfo&) [with T = unsigned char*; PyObject = _object]':
/home/hongbinl/work/PNG_encode_decode/opencv/modules/python/src2/cv2.cpp:1746:25:   required from 'bool pyopencv_to_generic_vec(PyObject*, std::vector<_Tp>&, const ArgInfo&) [with Tp = unsigned char*; PyObject = _object]'
/home/hongbinl/work/PNG_encode_decode/opencv/modules/python/src2/cv2.cpp:1862:43:   required from 'static bool pyopencvVecConverter<Tp>::to(PyObject*, std::vector<_Tp>&, const ArgInfo&) [with Tp = unsigned char*; PyObject = _object]'
/home/hongbinl/work/PNG_encode_decode/opencv/modules/python/src2/cv2.cpp:1720:40:   required from 'bool pyopencv_to(PyObject*, std::vector<_Tp>&, const ArgInfo&) [with Tp = unsigned char*; PyObject = _object]'
/home/hongbinl/work/PNG_encode_decode/opencv/modules/python/src2/cv2.cpp:81:27:   required from 'bool pyopencv_to_safe(PyObject*, _Tp&, const ArgInfo&) [with _Tp = std::vector<unsigned char*>; PyObject = _object]'
/home/hongbinl/work/PNG_encode_decode/opencv/build/modules/python_bindings_generator/pyopencv_generated_funcs.h:15562:77:   required from here
/home/hongbinl/work/PNG_encode_decode/opencv/modules/python/src2/cv2.cpp:96:94: error: 'to' is not a member of 'PyOpenCV_Converter<unsigned char*, void>'
   96 | bool pyopencv_to(PyObject* obj, T& p, const ArgInfo& info) { return PyOpenCV_Converter<T>::to(obj, p, info); }

Any help will be appreciated!

try

CV_EXPORTS_W bool imencode( const String& ext, InputArray img,
CV_OUT std::vector& buf,
const std::vector& params = std::vector(),
InputArray workspace);

basically, the cv2 wrappers do not know about vectors of pointers
(shouldnt it alsobe const ?)

what would be on the other (python) side as input ?

please explain, what you are trying to pass inside there, maybe someone has an idea, then

Hi berak, I am not clear what the python side would be either.
We have two interfaces here.
In the first function, we allocate a list of GPU memory with cudaMalloc(), which are stored in workspace:

void init_workspace(vector<unsigned char*> workspace)

In the second function imencode(), we use the workspace to accommodate some tensors and do some GPU-accelerated optimizations.
I ever tried to use vector<vector< unsigned char>> to replace it, but it didn’t work for cudaMalloc().

Hi sturkmen, I am not familiar with InputArray.
Inside the C++ function, I need multiple pointers to store the memory space on GPU.
I don’t know if InputArray works in this case.
And I find vector<intptr_t> and vector< long> return the same error as above, that’s a little weird.

if all you need in python is to “pass around” your cuda workspace vectors
(as in: A() produces it, B() consumes it, and noone tries to “peek into it” from python inbetween),
you could wrap it opaquely into some struct:


// the struct is exposed to python, the content not so !
struct CV_EXPORTS_W Workspace {
	vector<uchar*> workspace;
};

CV_EXPORTS_W Ptr<Workspace> init_workspace() {
	Ptr<Workspace> ws = makePtr<Workspace>();
	// ... fill ws->workspace
	return ws;
}

CV_EXPORTS_W bool imencode( const String& ext, InputArray img,
CV_OUT std::vector& buf,
const std::vector& params = std::vector(),
CV_IN Ptr<Workspace> workspace) {
	// do something with workspace->workspace;
}

usage from python would be as simple as:

ws = init_workspace()
...
cv2.imencode(ext,buffer,params,ws)
2 Likes

Thanks berak, it seems the code snippet meets my requirement, and I will try that.