Ask Your Question

ostrumvulpes's profile - activity

2017-03-01 19:12:53 -0600 asked a question CUDA Warp Perspective - Improving Accuracy

I am writing a Python program with Cython bindings to OpenCV. I am trying to substitute a cv::warpPerspective(...) call with a cv::cuda::warpPerspective(...) call. However, when I compare the results of the two methods, I am getting very poor accuracy (some accuracies from multiple test photos follows below).

0.362847222222
0.328125
0.671875
0.725694444444
0.394097222222
0.505208333333
0.559027777778
0.350694444444
0.34375
0.371527777778
0.373263888889

Is there a way for me to improve the accuracy? I am rather sure that my Cython bindings are proper (I compared my Cython binding to OpenCV's Python binding for cv::warpPerspective, and they return identical results):

def cudaWarpPerspectiveWrapper(np.ndarray[np.uint8_t, ndim=2] _src,
                               np.ndarray[np.float32_t, ndim=2] _M,
                               _size_tuple,
                               int _flags=INTER_NEAREST):
    # 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)

    # Create CPU/host InputArray for M
    cdef Mat M_mat = Mat()
    pyopencv_to(<PyObject*> _M, M_mat)

    # Create Size object from size tuple
    # Note that size/shape in Python is handled in row-major-order -- therefore, width is [1] and height is [0]
    cdef Size size = Size(<int> _size_tuple[1], <int> _size_tuple[0])

    # Create empty GPU/device OutputArray for dst
    cdef GpuMat dst_gpu = GpuMat()
    warpPerspective(src_gpu, dst_gpu, M_mat, size, _flags)

    # Get result of dst
    cdef Mat dst_host
    dst_gpu.download(dst_host)
    cdef np.ndarray out = <np.ndarray> pyopencv_from(dst_host)
    return out

def warpPerspectiveWrapper(np.ndarray[np.uint8_t, ndim=2] _src,
                               np.ndarray[np.float32_t, ndim=2] _M,
                               _size_tuple,
                               int _flags=INTER_NEAREST):
    # Create GPU/device InputArray for src
    cdef Mat src_mat = Mat()
    pyopencv_to(<PyObject*> _src, src_mat)

    # Create CPU/host InputArray for M
    cdef Mat M_mat = Mat()
    pyopencv_to(<PyObject*> _M, M_mat)

    # Create Size object from size tuple
    # Note that size/shape in Python is handled in row-major-order -- therefore, width is [1] and height is [0]
    cdef Size size = Size(<int> _size_tuple[1], <int> _size_tuple[0])

    # Create empty GPU/device OutputArray for dst
    cdef Mat dst_mat = Mat()
    warpPerspective(src_mat, dst_mat, M_mat, size, _flags)

    # Get result of dst
    cdef np.ndarray out = <np.ndarray> pyopencv_from(dst_mat)
    return out
2017-02-19 01:11:19 -0600 received badge  Enthusiast
2017-02-13 02:02:26 -0600 commented answer Accessing Functions with Python Ctypes on .so Files

So I'm better off writing my own C++ code to call any OpenCV functions I need that don't have Python bindings, and then referencing my own code with ctypes?

2017-02-13 01:56:08 -0600 asked a question Accessing Functions with Python Ctypes on .so Files

Hello everybody,

I am trying to use Python's ctypes module to directly access functions that do not have Python bindings in OpenCV. More specifically, I want to access cv::cuda::warpPerspective from the module cudawarping.

I was hoping that with the following Python code, I could create a handle to the CUDA-accelerated warpPerspective function:

_CUDAWARPING = ctypes.cdll.LoadLibrary(os.path.join(_OPENCV_SO_DIR, "libopencv_cudawarping.so"))
_func = _CUDAWARPING.warpPerspective

However, after encountering a NameError and diving into libopencv_cudawarping.so, I discovered that there is no particular single warpPerspective function, and everything seems a bit mangled in a way I don't quite understand:

                 U nppiWarpPerspectiveBack_8u_C1R
                 U nppiWarpPerspectiveBack_8u_C3R
                 U nppiWarpPerspectiveBack_8u_C4R
                 U nppSetStream
0000000000106260 T ownFeaturesToIdx
0000000000191740 T ownGetFeature
0000000000191380 T ownGetMaskFeatures
0000000002c06fc0 D own_ipps_sCos_E7_ctab
00000000001c66a0 T own_ipps_sCos_E7EPnnn

I have two questions:

  1. I wanted to know why it isn't as straightforward as I thought it was to access the functions in the original C++ files through ctypes.

  2. My next bet is to write some of my own C++ source code as a wrapper for the functions I do want to call, and then use Python's ctypes to wrap that instead. Does this seem like a feasible approach?

Thanks for helping me understand this better!

2017-02-10 01:16:59 -0600 received badge  Supporter (source)
2017-02-10 01:16:57 -0600 received badge  Scholar (source)
2017-02-09 14:05:20 -0600 asked a question OpenCV CUDA Python Bindings

Hello everyone,

I am writing a Python-based application using OpenCV and its Aruco module for marker detection. I want to parallelize some parts of the application, and noticed that the latest OpenCV build on GitHub seems to have many of the CUDA module functions wrapped with export macros.

CV_EXPORTS double threshold(InputArray src, OutputArray dst, double thresh, double maxval, int type, Stream& stream = Stream::Null());

It seems that I should be able to call this directly from my Python code, but I have not been able to do so (as far as I know).

Is it still necessary at this point to use some external library to link my Python code with the OpenCV CUDA code, e.g., PyCUDA? Or am I already using the GPU implementation if I call cv2.threshold() if I've built OpenCV WITH_CUDA=ON?

Thanks!