从python使用Opencv Cuda函数 [英] Using Opencv Cuda functions from python
问题描述
对于我的课程项目之一,我需要使用OpenCVs GPU库.我正在研究使用OpenCV python的现有代码,我的工作是找到一种访问OpenCV Cuda库的方法,因为目前没有可访问的Python绑定到OpenCV的各种CUDA模块.
For one of my course projects, I need to use the OpenCVs GPU libraries. I am working on an existing code where OpenCV python is used and my work is to find a way to access the OpenCV Cuda libraries as right now there are no accessible Python bindings to OpenCV's various CUDA modules.
我现在非常需要的两个功能是cuda::warpPerspective
和cv::cuda::DescriptorMatcher::knnMatch()
.
Two of the functions that i extremely need right now are cuda::warpPerspective
and cv::cuda::DescriptorMatcher::knnMatch()
.
我尝试通过遵循DescriptorMatcher::knnMatch()
中.更精确地说,我需要使用蛮力描述符匹配器knnmatch
函数(CUDA).我在网上搜索了例如用C ++编写的代码,以便初步了解如何通过cython进行转换以使其工作.
i tried to implement the warpPerspective
by following what @ostrumvulpes suggested in Accessing OpenCV CUDA Functions from Python (No PyCUDA) and it is working perfectly. Right now i am stuck in DescriptorMatcher::knnMatch()
. To be more precise, i need to use the brute-force descriptor matchers knnmatch
function (CUDA). i searched online for example written in C++, so that i get an initial idea how to convert it via cython to make it work.
我发现的大多数示例如下:
Most of the examples that i found is like following:
Ptr<cuda::DescriptorMatcher> matcher =
cuda::DescriptorMatcher::createBFMatcher();
vector< vector< DMatch> > matches;
matcher->knnMatch(descriptors_object_Gpu, descriptors_scene_Gpu, matches, 2);
要实现这三行代码,我首先在.pxd文件中添加了我认为必要的内容.我的pxd文件如下所示:
To implement these three lines i first added what i thought was necessary in the .pxd file. My pxd file looks like the following:
GpuWrapper.pxd
from libcpp cimport bool
from cpython.ref cimport PyObject
from libcpp.vector cimport vector
# References PyObject to OpenCV object conversion code borrowed from OpenCV's own conversion file, cv2.cpp
cdef extern from 'pyopencv_converter.cpp':
#mrc689 April 20,2017
void import_array()
cdef PyObject* pyopencv_from(const Mat& m)
cdef bool pyopencv_to(PyObject* o, Mat& m)
cdef extern from 'opencv2/imgproc.hpp' namespace 'cv':
cdef enum InterpolationFlags:
INTER_NEAREST = 0
cdef enum ColorConversionCodes:
COLOR_BGR2GRAY
cdef extern from 'opencv2/core/core.hpp':
cdef int CV_8UC1
cdef int CV_32FC1
cdef extern from 'opencv2/core/core.hpp' namespace 'cv':
cdef cppclass Size_[T]:
Size_() except +
Size_(T width, T height) except +
T width
T height
ctypedef Size_[int] Size2i
ctypedef Size2i Size
cdef cppclass Scalar[T]:
Scalar() except +
Scalar(T v0) except +
cdef extern from 'opencv2/core/core.hpp' namespace 'cv':
cdef cppclass Mat:
Mat() except +
void create(int, int, int) except +
void* data
int rows
int cols
#added to test the Algorithm class inside core.hpp on May5th 12.52 AM.
cdef cppclass Algorithm:
Algorithm() except +
cdef extern from 'opencv2/core/base.hpp' namespace 'cv':
cdef enum NormTypes:
NORM_INF= 1,
NORM_L1= 2,
NORM_L2= 4,
NORM_HAMMING= 6,
NORM_HAMMING2= 7,
cdef extern from 'opencv2/core/cuda.hpp' namespace 'cv::cuda':
cdef cppclass GpuMat:
GpuMat() except +
void upload(Mat arr) except +
void download(Mat dst) const
cdef cppclass Stream:
Stream() except +
cdef extern from 'opencv2/core/types.hpp' namespace 'cv':
cdef cppclass DMatch:
DMatch() except +
float distance
int imgIdx
int queryIdx
int trainIdx
cdef extern from 'opencv2/core/cvstd.hpp' namespace 'cv':
cdef cppclass Ptr[T]:
T element_type
Ptr() except +
cdef extern from 'opencv2/cudafeatures2d.hpp' namespace 'cv::cuda':
cdef cppclass DescriptorMatcher:
@staticmethod
Ptr[DescriptorMatcher] createBFMatcher(int normType) except+
#Expected to see error here
void knnMatch(GpuMat queryDescriptors, GpuMat trainDescriptors, vector[vector[DMatch]] &matches,int k)
cdef extern from 'opencv2/cudawarping.hpp' namespace 'cv::cuda':
cdef void warpPerspective(GpuMat src, GpuMat dst, Mat M, Size dsize, int flags, int borderMode, Scalar borderValue, Stream& stream)
# Function using default values
cdef void warpPerspective(GpuMat src, GpuMat dst, Mat M, Size dsize, int flags)
我的pyx看起来像这样:
and my pyx looks like this:
GpuWrapper.pyx
import numpy as np # Import Python functions, attributes, submodules of numpy
cimport numpy as np # Import numpy C/C++ API
def match_feature(np.ndarray[np.float32_t, ndim=3] _src,
np.ndarray[np.float32_t, ndim=2] _M):
np.import_array()
# Create GPU/device InputArray for src
cdef Mat src_mat
cdef GpuMat src_gpu
pyopencv_to(<PyObject*> _src, src_mat)
src_gpu.upload(src_mat)
cdef Mat src_mat_2
cdef GpuMat src_gpu_2
pyopencv_to(<PyObject*> _M, src_mat_2)
src_gpu_2.upload(src_mat_2)
cdef Ptr[DescriptorMatcher] matcher= Ptr()
matcher = DescriptorMatcher.createBFMatcher(4)
cdef vector[vector[DMatch]] matches
matcher.knnMatch(src_gpu,src_gpu_2,matches,2)
print("no problem so far")
当我尝试对其进行编译时,出现错误消息'Ptr[DescriptorMatcher]' has no attribute 'knnMatch'
.
When i tried to compile it i got an error which says 'Ptr[DescriptorMatcher]' has no attribute 'knnMatch'
.
据我所知,Ptr是类型为DescriptorMatcher
的共享指针,因此在我从.pxd文件定义Ptr的方式中一定存在一些错误.
Now as far i understood, the Ptr is a shared pointer of type DescriptorMatcher
, So there must be something wrong in my way of defining Ptr from .pxd file.
我只是不知道如何解决它.如果有人可以帮助我解决问题,我将不胜感激.
i just dont know how to fix it. I will really appreciate if someone can help me solving it.
推荐答案
我认为您没有正确使用Ptr
(在获取knnMatch
之前,它需要在Cython中取消引用).
I don't think you're using Ptr
correctly (it needs dereferencing in Cython before you can get to knnMatch
).
看看如何制作Ptr
的好地方是内置于Cython中的C ++标准库包装器
A good place to look at how to make Ptr
is the C++ standard library wrappers built into Cython which wrap the similar classes std::shared_ptr
and std::unique_ptr
.
您不想执行T element_type
行,因为它不会被解释为typedef(就像在OpenCV标头中一样)-它被解释为具有名为element_type
的成员,而该成员的类型为T
(不存在.
You don't want to do the line T element_type
since this isn't interpreted as a typedef (like in the OpenCV headers) - it's interpreted as having a member called element_type
of type T
(which doesn't exist).
您可能想为Ptr
设置一些其他构造函数.就目前而言,您只包装了默认的空包装. (因为您从工厂函数中获取了代码,所以它对您的代码似乎无关紧要.)
You possibly want to set up some of the other constructors for Ptr
. As it stands you've only wrapped the default empty one. (It doesn't look like it matters for your code since you get it from a factory function).
最重要的是,您还想设置解除引用运算符(operator*
).这可能是您需要执行的所有工作:
Most importantly, you also want to set up the dereference operator (operator*
). That's probably all you need to implement for it to work:
cdef cppclass Ptr[T]:
Ptr() except +
Ptr(Ptr*) except +
T& operator* () # probably no exceptions
要使用它,您使用cython.operator.dereference
:
To use it you use the cython.operator.dereference
:
# at the top
from cython.operator cimport dereference
# later
dereference(matcher).knnMatch(src_gpu,src_gpu_2,matches,2)
(我没有详细研究其余的代码,因此我对它是否正确没有任何评论)
(I haven't looked at the rest of the code in detail so I have no comment on whether it is right)
这篇关于从python使用Opencv Cuda函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!