Implement cv::cuda::inRange (Fixes OpenCV #6295)#2803
Implement cv::cuda::inRange (Fixes OpenCV #6295)#2803opencv-pushbot merged 1 commit intoopencv:masterfrom
Conversation
alalek
left a comment
There was a problem hiding this comment.
Thank you for contribution!
Please take a look on comments below.
| inRangeImpl<double, 4>}}; | ||
|
|
||
| const func_t func = funcs.at(channels - 1).at(depth); | ||
| func(src, lb, ub, dst, stream); |
There was a problem hiding this comment.
Please use CV_Check*() macro to validate channels / depth values.
There was a problem hiding this comment.
Previously wasn't; I was trying to cover all depths. I've now realized that it doesn't work for float16, because CUDA doesn't have a float16 vector type. So I added a CV_Check that the depth is CV_64F or lower
| @param dst output array of the same size as src and CV_8U type. | ||
| @param stream Stream for the asynchronous version. | ||
|
|
||
| @sa inRange |
There was a problem hiding this comment.
There is self-reference loop.
Try this one instead:
@sa cv::inRange
|
|
||
| @sa inRange | ||
| */ | ||
| CV_EXPORTS_W void inRange(InputArray src, InputArray lowerb, InputArray upperb, OutputArray dst, Stream& stream = Stream::Null()); |
There was a problem hiding this comment.
CV_EXPORTS_W
Did you try to call this from Python binding? Are lowerb / upperb handled properly?
There was a problem hiding this comment.
I can make calls like
src = (np.random.random((1920, 1080, 4)) * 256).astype(np.uint8)
lowerb = (0, 0, 0, 0)
upperb = (255, 255, 255, 255)
dst = cv2.cuda.inRange(src, lowerb, upperb)with different types and numbers of channels for src (up to 4 channels). The CV_Check fires correctly if I pass the wrong shape for lowerb or upperb, or too many channels for src. It doesn't work if I pass a cv2.cuda_GpuMat (I get a TypeError: Expected Ptr<cv::UMat> for argument 'src') - I'm really not familiar with using OpenCV CUDA from Python so I don't know if that's the intended behavior.
There was a problem hiding this comment.
I get a TypeError
Current messages from Python bindings are quite useless. You can set OPENCV_PYTHON_DEBUG=1 env variable to investigate conversion errors.
The "GPU" overload assumes that all inputs must be a GpuMat including lowerb/upperb parameters (because they a InputArray). But wrapping 4 scalars into GpuMat has significant overhead.
InputArray lowerb, InputArray upperb
Try to replace type to const Scalar& to eliminate unnecessary complexity.
There was a problem hiding this comment.
Please add simple Python test into this file.
(please note, that public OpenCV CI doesn't run CUDA code/tests)
There was a problem hiding this comment.
Done. I switched to const Scalar& for lowerb and upperb, and added a Python test to that file which passes on my machine, it now works if you pass a numpy array or a cuda_GpuMat
4213ba3 to
a102a0a
Compare
|
I think everything has been addressed, but the docs build is failing on CI with It passes on my machine and this seems unrelated to anything I've done, not sure if there's anything I can do to fix it |
|
@amiller27 It is CI issue, I will fix that soon. Custom (CUDA) builder is failed due to changes from #2807 (should be fixed soon in separate PR) |
alalek
left a comment
There was a problem hiding this comment.
Well done! Thank you for contribution 👍
Merge with extra: opencv/opencv_extra#834
resolves opencv/opencv#6295
Implementation of
cv::cuda::inRange, as requested in this issue. It's not a complete implementation ofcv::inRange; my implementation supportscv::Scalarfor the upper and lower bounds, which seems like the most common use case by far, but the CPU version does also supportMats for the bounds as well, which mine does not. It seemed like more of a challenge to support that as well, but if you don't want to merge this without full feature parity I might be able to spend more time on it to figure that out.Some questions -
masteror3.4, happy to rebase to3.4if desired. I do usestd::array, but I think that's the only C++11 feature I'm using and it'd be easily removed.functional.hppto copy and compare CUDA vectors; if CUDA or OpenCV already has utilities somewhere to do this I can switch to make that simplerPull Request Readiness Checklist
See details at https://github.com/opencv/opencv/wiki/How_to_contribute#making-a-good-pull-request
Patch to opencv_extra has the same branch name.