CUDA Treshold does not seem to work

Hi, i’m trying to get tresholding to work with CUDA. I’ve tried a few different approaches and conversions to different types, but nothing seems to solve it.
I’m working off this definition

double 	cv::cuda::threshold (InputArray src, OutputArray dst, double thresh, double maxval, int type, Stream &stream=Stream::Null())
 	Applies a fixed-level threshold to each array element.

Test Code

import cv2

frame = cv2.imread("001.jpg")

frame_gpu = cv2.cuda_GpuMat()
frame_gpu.upload(frame)
frame_gpu = frame_gpu.convertTo(cv2.CV_8UC1)

dst_gpu = cv2.cuda_GpuMat(frame_gpu.size(), cv2.CV_8UC1)

dst_gpu = cv2.cuda.threshold(frame_gpu, dst_gpu, 128, 255, cv2.THRESH_BINARY)
print(dst_gpu)

Produces this error

cv2.error: OpenCV(4.9.0) :-1: error: (-5:Bad argument) in function 'threshold'
> Overload resolution failed:
>  - src is not a numpy array, neither a scalar
>  - Expected Ptr<cv::cuda::GpuMat> for argument 'dst'
>  - Expected Ptr<cv::UMat> for argument 'src'

I’m probably missing something obvious haha but i’d greatly appreciate any help.
The code i’ve submitted is just the minimal code needed to reproduce, the idea was using the tresholding for harris corner detection, if anyone has any tricks for that too i’d greatly appreciate it.

I don’t know where is doc but this line does not give an error

dst_gpu = cv.cuda.threshold(frame_gpu,128, 255, cv.THRESH_BINARY)

May be you must use doc threshold doc ?

2 Likes

Thank you, that solved it!

@Zadkiel When you know the function you want to use, check the help docs for the function signature so you know which arguments it expects

>>> help(cv.cuda.threshold)
Help on built-in function threshold:

threshold(...)
    threshold(src, thresh, maxval, type[, dst[, stream]]) -> retval, dst
    .   @brief Applies a fixed-level threshold to each array element.
    .
    .   @param src Source array (single-channel).
    .   @param dst Destination array with the same size and type as src .
    .   @param thresh Threshold value.
    .   @param maxval Maximum value to use with THRESH_BINARY and THRESH_BINARY_INV threshold types.
    .   @param type Threshold type. For details, see threshold . The THRESH_OTSU and THRESH_TRIANGLE
    .   threshold types are not supported.
    .   @param stream Stream for the asynchronous version.
    .
    .   @sa threshold

In your case both

1)
ret, dst_gpu = cv.cuda.threshold(frame_gpu,128, 255, cv.THRESH_BINARY)

and

2)
dst_gpu = cv2.cuda_GpuMat(frame_gpu.size(), cv2.CV_8UC1)
cv.cuda.threshold(frame_gpu,128, 255, cv.THRESH_BINARY, dst = dst_gpu )

will work. The only difference is that the first approach will allocate a new dst_gpu on the GPU each time it is called resulting in a slight performance hit.