-
Notifications
You must be signed in to change notification settings - Fork 5.8k
Fix race condition in Otsu's method #3970
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: 4.x
Are you sure you want to change the base?
Conversation
@troelsy Can you provide a test case which fails without this fix? |
The image size is not important in this part of the code as it only runs on the histogram. I did also consider your solution and it may be more suiting for OpenCV than us. It is a gamble on how likely it is to happen and I haven't been able to trigger the minimum reduction on our footage. It is probably more likely on computer generated images |
I did a quick bit of benchmarking, on an RTX 3070 TI your approach is quicker regardless of whether there is more than one unique solution ( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM 👍
I found that in some cases, Otsu's method can have two or more equal thresholds. In case of the CUDA implementation, this would create a race-condition where the last thread to write the output gets to choose which Otsu threshold to use. The resulting image from cv::cuda::threshold would be the same, but the returned threshold would vary for each run.
I solve this by first doing a poll to check if there are multiple matches with
__syncthreads_count
. If not, we can return the threshold as before. If there are more than one, the kernel does a minimum reduction to find the lowest threshold that matches the otsu score. It doesn't matter which threshold you choose as long as it is consistent, so I choose the smallest one.I'm unsure when
__syncthreads_count
as introduced, but it is compatible with CC≥2.0. CUDA Toolkit's archive only goes back to version 8.0, but it was documented back then (https://docs.nvidia.com/cuda/archive)Pull 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.