Skip to content
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

cv::cuda::HoughCirclesDetector and cv::HoughCircles do not give the same results #7830

Open
chacha21 opened this issue Dec 9, 2016 · 6 comments
Labels

Comments

@chacha21
Copy link
Contributor

chacha21 commented Dec 9, 2016

Hello,

System information (version)

OpenCV 3.1.0, Windows 7 64 bits, Visual Studio 2010, Cuda 8

Detailed description

I have noticed that for a similar input, cv::cuda::HoughCirclesDetector and cv::HoughCircles do not give the same results. I am not sure if it is normal, because the documentation does not tell that it should be the case (algorithms may be different).
However, it would be convenient, either to fix it, or explain how to circumvent it by adapting the parameters.

Steps to reproduce

Image provided as attachement, and here is a sample code :

cv::Mat img = cv::imread("test.png", cv::IMREAD_GRAYSCALE);

  float dp = 1;
  float minDist = 100;
  int cannyThreshold = 122;
  int accThreshold = 50;
  int minRadius = 1;
  int maxRadius = std::max(img.size().width, img.size().height);

  std::vector<cv::Vec3f> cpuCircles;
  cv::HoughCircles(img, cpuCircles, cv::HOUGH_GRADIENT, dp, minDist, cannyThreshold, accThreshold, minRadius, maxRadius);

  std::vector<cv::Vec3f> gpuCircles;
  cv::Ptr<cv::cuda::HoughCirclesDetector> gpuDetector = cv::cuda::createHoughCirclesDetector(dp, minDist, cannyThreshold, accThreshold, minRadius, maxRadius);
  cv::cuda::GpuMat gpuMat;
  cv::cuda::GpuMat gpuResult;
  gpuMat.upload(img);
  gpuDetector->detect(gpuMat, gpuResult);
  gpuCircles.resize(gpuResult.size().width);
  if (!gpuCircles.empty())
    gpuResult.row(0).download(cv::Mat(gpuCircles).reshape(3, 1));

  printf("CPU circles :\n");
  for(std::vector<cv::Vec3f>::const_iterator it = cpuCircles.begin() ; it != cpuCircles.end() ; ++it)
    printf("(%f,%f,%f)", it->val[0], it->val[1], it->val[2]);
  printf("\n");
  printf("GPU circles :\n");
  for(std::vector<cv::Vec3f>::const_iterator it = gpuCircles.begin() ; it != gpuCircles.end() ; ++it)
    printf("(%f,%f,%f)", it->val[0], it->val[1], it->val[2]);
  printf("\n");

Output result :
CPU circles :
(165.500000,329.500000,56.925388)
GPU circles :
(165.500000,328.500000,100.000000)(165.500000,328.500000,56.000000)(165.500000,3
28.500000,60.000000)(165.500000,328.500000,65.000000)(165.500000,328.500000,73.0
00000)(165.500000,328.500000,87.000000)(165.500000,328.500000,151.000000)(165.50
0000,328.500000,178.000000)(165.500000,328.500000,180.000000)(165.500000,328.500
000,183.000000)(165.500000,328.500000,185.000000)(165.500000,328.500000,187.0000
00)(165.500000,328.500000,190.000000)(165.500000,328.500000,224.000000)

test

@chacha21 chacha21 changed the title cv::cuda::HoughCirclesDetector does not give the same results as cv::HoughCircles cv::cuda::HoughCirclesDetector do not give the same results as cv::HoughCircles Dec 9, 2016
@chacha21 chacha21 changed the title cv::cuda::HoughCirclesDetector do not give the same results as cv::HoughCircles cv::cuda::HoughCirclesDetector and cv::HoughCircles do not give the same results as Dec 9, 2016
@chacha21 chacha21 changed the title cv::cuda::HoughCirclesDetector and cv::HoughCircles do not give the same results as cv::cuda::HoughCirclesDetector and cv::HoughCircles do not give the same results Dec 9, 2016
@chacha21
Copy link
Contributor Author

chacha21 commented Dec 9, 2016

I did not mention why I would like to see the same results :
I want the cuda implementation to be an optimization called under the hood if the hardware is compatible. Thus, I need the results to be equivalent so that it can be transparent to the user.

@alalek
Copy link
Member

alalek commented Dec 9, 2016

GPU-based algorithms with "bit-exact" results are usually very ineffective (except very simple cases).

Usage questions should go to User Q/A forum: http://answers.opencv.org

@chacha21
Copy link
Contributor Author

chacha21 commented Dec 9, 2016

I am not sure to understand what you mean.
What I wanted to highlight is that there is not the same number of circles. The CPU returns 1 circle, the GPU 14 circles.
If there was the same number of circles, I wouldn't care that the floating values of their centers would not be the same exact floating values.

@alalek
Copy link
Member

alalek commented Dec 9, 2016

I mean that in general your should not expect "the same" results from CPU and GPU algorithms.
There is usual consequence: different floating values -> different threshold result -> different number of results.

If you have evidences that there is real bug in implementation then please open a ticket with details.

@chacha21
Copy link
Contributor Author

I think I have found evidences of a real difference in implementation, but it this a bug ?
When using a dummy image with just white concentric circles on black background:

the CPU version reports 1 circle because the "minDistance" parameter is used while trying to find the best radii.
the GPU version reports multiple circles, because the "minDistance" is used before trying to find the best radii.

Those are two different interpretations of the minDistance parameter, because the doc does not tell how it should handle concentric circles.

@zachary-zheng
Copy link

@chacha21 @alalek Hello, I have encountered the same phenomenon that GPU gave more circles result, and it seems the parameter ''minDist Minimum distance'' is valid. The centers of the detected circles are obvious larger than minDist.
why?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants