2017-05-07 16 views
2

私のコースプロジェクトの1つとして、OpenCVs GPUライブラリを使用する必要があります。私はOpenCVのPythonが使用されている既存のコードに取り組んでいます。私の仕事はOpenCV Cudaライブラリにアクセスする方法を見つけることです。今はOpenCVのさまざまなCUDAモジュールへのPythonバインディングがありません。PythonのOpencv Cuda関数の使用

今のところ非常に必要な機能のうちの2つは、cuda::warpPerspectivecv::cuda::DescriptorMatcher::knnMatch()です。

私はAccessing OpenCV CUDA Functions from Python (No PyCUDA)で提案した@strumvulpesに従ってwarpPerspectiveを実装しようとしていて、完全に動作しています。今私はDescriptorMatcher::knnMatch()にこだわっています。より正確に言えば、私はブルートフォース記述子マッチャーknnmatch関数(CUDA)を使用する必要があります。私はオンラインでC++で書かれたものを検索したので、cythonを使って変換する方法を最初に考えました。

Ptr<cuda::DescriptorMatcher> matcher = 
cuda::DescriptorMatcher::createBFMatcher(); 
vector< vector< DMatch> > matches; 
matcher->knnMatch(descriptors_object_Gpu, descriptors_scene_Gpu, matches, 2); 

を私が最初に私は.pxdファイルに必要だと思ったものを追加これらの3行を実装するには:

私が見つけた例のほとんどは、次のようなものです。

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は、次のようになります:私のPXDファイルには、次のようになり、私が試したとき

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'と言うエラーがあります。

ここまで分かりましたが、PtrはタイプDescriptorMatcherの共有ポインタですので、.pxdファイルからPtrを定義する方法が間違っているはずです。

私はちょうどそれを修正する方法を知らない。私は本当に誰かがそれを解決するのを助けることができれば感謝します。

+0

あなたはそれを機能させることができましたか?どのバージョンのpythonとopencvを使用していますか? – Alvar

答えて

1

Ptrを正しく使用していないと思われます(knnMatchになる前に、Cythonで逆参照が必要です)。

Ptrを作成するには、Cython which wrap the similar classes std::shared_ptr and std::unique_ptrに組み込まれているC++標準ライブラリラッパーが適しています。

あなたは、これは(OpenCVのヘッダのような)のtypedefとして解釈されていないので、ラインT element_typeを行うにはしたくない - それは、メンバーが(存在しない)タイプTelement_type呼ば有するものと解釈しています。

Ptrの他のコンストラクタのいくつかを設定することもできます。それはあなたがデフォルトの空のラップだけをラップしたことになります。 (ファクトリ関数から取得しているので、コードにとって重要なようには見えません)。

最も重要なことに、間接参照演算子(operator*)も設定する必要があります。それはおそらく、あなたはそれを動作させるために実装する必要がすべてです:

cdef cppclass Ptr[T]: 
    Ptr() except + 
    Ptr(Ptr*) except + 
    T& operator*() # probably no exceptions 

あなたuse the cython.operator.dereferenceこれを使用するには:

(私は詳細にコードの残りの部分を見ていない
# at the top 
from cython.operator cimport dereference 

# later 
dereference(matcher).knnMatch(src_gpu,src_gpu_2,matches,2) 

+0

ありがとうございます。私は何のエラーもなく正常にコンパイルできました。私は本当にあなたの助けに感謝します。 –

+0

@MohammedRashidChowdhury私はこれを動作させようとしていますが、Ptrでコンパイルエラーが発生します。何か案は? GpuWrapper.pyx:77:44: ext_modulesで、 ファイル "setupGpuWrapper.py"、35行: 'のPtr [DescriptorMatcher]' トレースバック(最新の呼び出しの最後)に 'のPtr [T]' タイプを割り当てることができません。 = cythonize(拡張子) ファイル "/usr/local/lib/python3.5/dist-packages/Cython/Build/Dependencies.py"、行1039、cythonize cythonize_one(* args) ファイル "/ usr/local /lib/python3.5/dist-packages/Cython/Build/Dependencies.py "、line 1161、cythonize_one raise CompileError(None、pyx_file) – ThijsW

+1

@ThijsWあなたは、 'cdef Ptr [DescriptiorMatcher]が必要なときに、' cdef Ptr [T] something'や 'cdef Ptr something'のようなことをやり直してください。何か」)。代わりに関数の戻り値になる可能性があります。これで十分ではない場合は、自分の質問をすることをお勧めします。コードなしでは難しいので、 – DavidW

関連する問題