从python使用Opencv Cuda函数 [英] Using Opencv Cuda functions from python

查看:1047
本文介绍了从python使用Opencv Cuda函数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

对于我的课程项目之一,我需要使用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::warpPerspectivecv::cuda::DescriptorMatcher::knnMatch().

Two of the functions that i extremely need right now are cuda::warpPerspective and cv::cuda::DescriptorMatcher::knnMatch().

我尝试通过遵循warpPerspective >从Python(无PyCUDA)访问OpenCV CUDA函数,并且运行良好.现在,我被困在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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆