so I found a program in the answers to this question that I thought was brilliant, so here it is applied to my situation: I have the image
and here's the code:
img=https://i.stack.imgur.com/MRlBH.png;
img = GaussianFilter[i, 2]
squaredError = 1/2 ({cx - x, cy - y}.{-gy, gx})^2;
errDerivative = Expand[D[squaredError, {{cx, cy}}]];
linearSystem = {{D[errDerivative, cx],
D[errDerivative, cy]}, -errDerivative /. {cx -> 0, cy -> 0}}
gradientX = ImageData@GaussianFilter[img, 1, {0, 1}];
gradientY = ImageData@GaussianFilter[img, 1, {1, 0}];
xArr = Array[N[#2] &, Dimensions[gradientX]];
yArr = Array[N[#1] &, Dimensions[gradientX]];
ls = Total[
linearSystem /. {gx -> gradientX, gy -> gradientY, x -> xArr, y -> `yArr},{-2, -1}];`
center = LinearSolve @@ ls;
center[[1]] -= 1;
center[[2]] = Length[gradientX] - center[[2]];
maxRadius = 400;
polar = ImageTransformation[img,
center + {Cos[#[[1]]], Sin[#[[1]]]}*#[[2]] &, {360, maxRadius},
DataRange -> Full,
PlotRange -> {{0 \[Degree], 360 \[Degree]}, {1, maxRadius}}]
radiusStrength = Mean /@ ImageData[polar, DataReversed -> True];
peakX = Position[
MapThread[#1 > #2 && #1 > #3 &, {radiusStrength,
RotateLeft[radiusStrength], RotateRight[radiusStrength]}],
True][[All, 1]];
peaks = SortBy[Transpose[{peakX, radiusStrength[[peakX]]}], Last];
ListLinePlot[radiusStrength, PlotRange -> .8,
Epilog -> {Red, Point[peaks[[-6 ;;]]]}]
Show[img,
Graphics[{Red, Dashed, Circle[center, #] & /@ peaks[[-8 ;;, 1]]}]]
Fantastic, exactly what I want this code to do for this image. If I crop the image so I only have the top half of the circles it still works great. However, when I try out this image, it shits the bed:
This is the final output
Do you guys have any suggestions for a more robust algorithm to find the centre?
gradientX
andgradientY
(e.g. from 1 to 10) and also increasemaxRadius
to ~650 $\endgroup$