I'm working on a project that takes powder diffraction images and tries to find all the elliptical rings in the image.
I'm using a RANSAC algorithm that fits an ellipse to the data, then subtracts those points (the inliers) and proceeds to fit another ellipse until the inlier ratio becomes small enough.
My problem is that it either fits more ellipses than there should be or not enough based on how I set the threshold distance.
I'm wondering is there anyway to improve RANSAC to be more accurate or is there a better algorithm that I should be using?
RAW IMAGE
THRESHOLD DISTANCE SET TO TO 5
THRESHOLD DISTANCE SET TO TO 10
I do not have a background knowledge of the process you are dealing with but looks like all the ovals (hard to say if really ellipses) are concentric so to improve accuracy I would try:
Find the center
or approximate of it. Let call it x0,y0
and let the image resolution be xs,ys
. Either you already know its position (due to knowledge of your image properties) or estimate it (scan one oval and find 2 lines that goes through whole oval their intersection is your center). If the center is un-precise then the result will be more like ovals then ellipses but that does not matter you can reconstruct original de-noised image latter and or recompute center from latter data...
Cast ray from (x0,y0)
to (xs-1,0)
and copy image content along it to some cleared line buffer of size xs+ys
just to be sure to cover any center position with reserve...
Integrate the whole image with rays
so cast rays always from (x0,y0)
to (xs-1,1),(xs-1,2)...(xs-1,ys-1)
then (xs-2,ys-1),...(0,ys-1)
etc to cover whole circumference of image.
Find out the scale ratio to original stored line (most of peaks must match) and add rescaled image content along rays into to stored line buffer.
Remember the scale for each angle used.
After covering whole image divide line buffer by the count of used rays so you got average cut through the oval rings with much much lover noise. Now just find the peaks in it. Each peak represents separate oval and its position gives you radius at the initial ray position angle.
The scales gives you the oval/elliptical properties. So find min and max scale that gives you angles where major and minor axises are ... The scale itself with peak position gives you the size of axis ... So no need for RANSAC (but you can still use it for the scale computation).
[Notes]
To avoid seems in the average line you can add a count for each pixel in it holding how many rays was added to each pixel and use that for the final division.
Also these QA's might help a bit:
[Edit1] some further info
I was curious so I did it a try (proof of concept). I resized your image to 512x512
so it fits into window for easier visual check and manually set center as (133,285)
Then create the integration of all rays (without scaling for now) and then I partially reconstruct the image:
the sun like shape is the reconstructed image from integrated average line and the rest is original image. As you can see those two fits almost perfectly so your ovals are almost circular (or are circular and I got center a bit off).
The aqua graph is intensity (y-axis) against distance form center of the integrated average line. Each peak represents one circle. So you can find the circles in 1D data instead of fit in 2D. Here completely reconstructed image without any debug draws:
How ever it looks like the scaling is not a good way for this and offsetting (by up to +/- few pixels from last previous ray offset) should be used instead. Will give it a try if got more time mood for this ...
[edit2] more precise center and further info
The closer you fit the center the sharper and bigger spikes are present in the average line. It can be use to fit the center more precisely (I use that and found out that I was off by 1 pixel in x axis which is pretty good for manual center selection...). After that no scaling or shifting is necessary as the ovals are circles. Then just substract sliding average of the average line (Aqua graph) and detect positive spikes only (Blue graph):
Each spike represent a circle (radius is distance from center which is also address in the line array in pixels) so just treshold intensity spikes and output circles...
And after applying peak detection and full precision integration:
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With