This image is originally 0-1 floats. I need to detect the circle in the image, but I am having trouble doing so with cv::HoughCircles. Clearly, I’d prefer not to be forced to run Canny edges (preferring instead to binarize the image myself), but the functions give me no choice. Any ideas for parameters or alternative methods? The SNR of this image is representative of the typical problem I am trying to solve.
See this example of “self-binarizing” via simple thresholding that fails cv::HoughCircles:
EdgeDrawing seems to work well, but quickly hangs on new input with the default parameters. This attached image is an example where the call to detectEllipses never returns (or takes too long for me to wait around for it to finish). Using 4.5.5. Any ideas?
My circle of interest is not guaranteed to be centered at the image center, maybe that was something you were assuming. Though the global image maximum should lay on the ring. Could you expand on your suggestion? Thanks!
The image is 8UC1, the call to convert and scale does this and it doesn’t hang or crash on the first image it sees, but the second. Here is the gdb output:
#0 0x00007f1dbbc7e7c6 in cv::ximgproc::EdgeDrawingImpl::SplitSegment2Lines(double*, double*, int, int) ()
at /opt/opencv4.5.5/lib/libopencv_ximgproc.so.405
#1 0x00007f1dbbc7fd71 in cv::ximgproc::EdgeDrawingImpl::detectEllipses(cv::_OutputArray const&) ()
at /opt/opencv4.5.5/lib/libopencv_ximgproc.so.405
I changed my test program to run through a directory of saved images similar to that shared above and it reliably core dumps, though some images are processed just fine, either with no returned ellipses or a correct one. Here is an example offending image:
Do you not want to run canny for performance reasons, or for some other reason?
Do you know where the circle is going to be in the image, or could you do a first pass to determine where it is? If so you could run canny only on the image ROI that is likely to contain the circle which could really save on processing time.
I have had luck searching for an appropriate canny parameter by starting at the center of a bounded range, and alternately searching higher / lower. When I get no edges back I stop searching higher, and when I get “too many” edges back, I stop searching lower. This might be too expensive for you to do, but I found it works well when you have to be robust to changes in edge intensity etc.
My notes say “II.8 - II.15” - I don’t recall why I chose this method from the paper, and I don’t recall why I chose this over hough circles, but it provides good results.