ok, I extracted the L and re-applied CHT. I now have an image with 50 alpha channels. I'll have to check them all to see if I got anything smile I supose it would be helpful if the process could have a filter that rejects circle sizes that have too few hits.

Well, let's start from some background: The CHT of a perfect, ideal circle, is a double cone, each one "opening" to different orientation (up and down). What you are seeing in this process are a series of horizontal cuts of these cones (for ***every*** circle). Since the cone is pretty regular, with a "clear" convergence to the optimal circle radius, you don't have to analize every single radius value in a wide range. You may get there with a multiscale approach

First try a large differential

Let's say, 10px. Then, you may find a very coarse range where the solution may be found, then, try 1px on it, or 2px, and repeat the process if needed.

Indeed such kind of rejection may be doable. I sort of normalized each plane, so the sum of the perimeter of the cone at each plane is always 1. This means, the pixel value gives something like the probability of being the optimal circle radius. Of course, if you have noise, adjacent circles, overlaping circles, etc., this may be screwed a bit, and you may end with values over 1, or give false positives.

I know CHT starts with a circle size and then tries to find it but for CHT to be useful it should be able to find *any* circle within a range and highlight those smile

If you want to plot the CHT, then you have to quantize the radius. Since the CHT is a three dimensional space, the only elegant way to manage that I found is to create alpha channels. An array of single channel images is just messy for plotting purposes.

Anyway, If you want just to detect the circle (one circle, for example), without plotting the CHT space, a more sophisticated algorithm may be written, where the maximum value of each layer is calculated, and then compared them all to find the most probable circle. It may be even a recursive algorithm, using subpixel accuracy. But I was too lazy at the time

Jokes apart, this is not hard to implement. Just needs time, and when I wrote this module, I needed the results quickly for a cooperation with researches of the Physics faculty.

Also the max of 100 is a bit low. The process is very very fast so I see no reason not to allow sizes up to min(width, height). Oh and it's 'differential' smile

Thanks for the correction

I need a spell checking machine

I can't remember the reason... I'll increase it next time I upgrade the code (for the "module compression task"

). The workaround: downsample the image.

After mucking with the image a little, using HT to remove the background noise and brightening the donut I'm seeing a clear CHT appear. I'm not sure why it's detecting the outer circle when the range doesn't allow that but this is pretty cool. Thanks very much for these!

As I said, I normalized the output so the values gives a sense of the probability of having a circle. For displaying purposes a STF is needed to see how pretty is this space

I don't think that it is detecting the outer "circle". If you analyze the image from the CHT point of view, there are not just 2 circles, at the boundaries of the donut. There are almost infinite circles between them, for every intermediate radius. That's why I suggested to calculate the modulus of the gradient, and use that as the input image. Also, if you look at very small radius values, the CHT will "find" all the circles that are located inside the donut. Remember, all the bright pixels are signals, and the CHT looks for every circle that fits the data.