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.