1
$\begingroup$

enter image description here

question 1 get the center


(sample data)

sample is the black circle with cusp.

 (*Input 1 ==< *)
 sample = Binarize[Import["https://i.stack.imgur.com/z7isS.png"]]
(*Output CellExpression, You can copy to Notebook or just Skip*)
 \!\(\*GraphicsBox[TagBox[RasterBox[CompressedData["1:eJztnc1u1DAUhR3Egh079jwKPEJ5glaCLVJBQn17mpnpNImPnTj+ude+51OpVI1jn/v5ZzLTqfj69Pvh1wfn3J9Pr98eHv99e35+fPnx8fWH7y9/fz7ND32enPvy+m9qhpuJPz65W7MFq8fHw+1ouT0cszKmmGm9YtbVX782Le+tt44Gw6/0bsUZtLLdGP7PsfaDSilhRSZ4VfatrMse3AraCrsFwotG8kMrK4pXM4QbWtlSN32vbirnXvbdh5ZG89jZZmqUtWMrFdP2Y6V5zi7UtM+o3YrgtCk2I7mYlVoRny2VB4x4JFrZC6DCiqI0iszoSbJ8eSSYRdHcvLF871MqgkIr0om0CXlHMhmtaBs7jlAyhQfKGpGAtKJiyFO0TUkrsmPl0i4qrYSH6UDJG7SCqJ3XdWuldv9dCblSOXWnVnY/65vdd4dOZuolp5VAv30qmerN6BhWSlcwhpXCvTa4Q6zK+41W0Sp6t1L8NVHPTz4LaAVSUkuHr3wClKyEVmr3JUuxSuo8n4lBK4gytQyl5Ep+RWMtlCvFrBRLpIH8mR7RSm5VI+6fmby6aKX81XrJqGuwG5U1p2ujlciFNTKp4JwYI1aSPq088vZ5I73C8Z3kWBnZS7IVA/sn/ZSwcKqctlI1kwbSvNBKpHXlTPLQCiLFihEl0+J3zwfuQOxYSXkNbNHKzmKxcaty5+BacWaO2gtHrVhycoFWEEdOFmtOjp2ktBJs0yyRBvatGBNygVYQe1bMbZ4btIKgFUR8D9FK6NHGgVSwb8WmmNiLRFrxirerZKIVDK0gaAVBKwGwF1qhFR9oJXp7ZwFkJXJvZ4SIFbFM8tAKglYQtIKgFUTQytCfrt3Dt8KVQisYWoGErJj24n+ciU5iVix74VrB0AqCVhDb5xxamUFWRAOpgFYQKyvcPjdoBUErCFpB0Apidc9PK3doBUErPjxXELSCoBUErSCcW3ihlRu0gqAVBM8VBK0gaAVDKwha8eEOQqysTHyP/wqtIGgFQSsIWkEgKxRDKwhaQdAKglYQWwu0MkMrCFpB0AoCWRGMowRaQXAHIWgFQSsIWvHxHdAKrWBoBQEc0Aq8Z6OVoBXTXmgFQSsIWvHB5Zu3El0rRr0EiqcVvFVM7yBaQcStWNWyY8WkFheunVZia8Wgl8iCiAgbnZiV2PYamWjVzupiiVdt7H86vLNXtc3VslewRSeHrVjycqhcWgk2ohXUyJKWg9Wa0nK4WFrJajgCqVZseKEVREqpVqykLQBayW/dK87Rio/jWgGkrhUbXtJrpJXoNdUyCXNy2mml4GW9cLI4WolcRivosjF/73x+ytNvcvoho7JhrWTVRSuVrtdIfk0Dni1FKhrTSpFOaAV1Qiuok3HEFKuEViIdjWClYB20Eu+tby/FZ5dWoh0W6k+ECidB916qFEArTbttQ7XsI1ip8mZrr2Iq5na0ItF7JarP5vszfkdeqkemlZ0hevHSJCytRIfpQEzbpLSyN2CT0U6wMtIqZVdWmqXsy4rIsO0GPUrqx4vLDaxZi5gVoa17ANlctHIkgMD4HioCqQixREUgFSGWiO8ebUGc05LET6Mlh7QVkEh4eAVCZqRTSY8fpkCyU9dux9XkhFYwtBIkJ2H6db4QfUZyU45q5crZrCnXgDH0CrlAK2FQ7kjylNZ9CrlAKyGwGa+GQLODSBSWxVkrSZ4kCsvirJU0JCrL5WSNAxuZqWml+7+zPjXzKW27hFZihJ5fpHPJkmFlXHXBexHpYIqgDIRuK/8B+/IYOQ=="], {{0, 271}, {278, 0}}, {0, 1},ColorFunction->GrayLevel],BoxForm`ImageTag["Bit", ColorSpace -> Automatic, Interleaving -> None],Selectable->False],BaseStyle->"ImageGraphics",ImageSizeRaw->{278, 271},PlotRange->{{0, 278}, {0, 271}}]\)
 (*Input 2 ==< *)
pts0 = PrincipalComponents@N@Position[ImageData[sample], 0];
{length = pts0 // Length, 
radius = EuclideanDistance[#, {0, 0}] & /@ pts0 // Mean,
center = Mean@pts0 // N // Chop, 
g1 = Graphics[{Point[pts0], {Red, Thick, circleNew = Circle[center, radius]}}]
}
Output result see picture ==> :)@@

I do not like this, I' d like the red circle overlap the black circle.

question 2 get the cusp.


Thought 1:

Put one locator in the cusp and drag it to along the diameter (from cusp point to center), and the circleNew will go to the center.

Maybe need interpolation, ie something BezierCurve or BSplineCurve..

Thought 2:

Go on ImageProcessing, directly make circleNew (smooth except the place of cusp) overlap the balck circle.

Maybe here we can directly Fit one curve with one function?

 (*Input 3 ==< *)
 Pruning[Thinning[ColorNegate[Erosion[sample, 1]]]]
(*Output CellExpression, You can copy to Notebook or just Skip*)
 \!\(\*GraphicsBox[TagBox[RasterBox[CompressedData["1:eJztnMtu00AYhWcQC3bs2PMo8AjlCVoJtkgFCfXtSVtTcjm2ZzyX/3Y+qRfXdnLOZ8/ISZp8fvh59+NdSunXh9O3u/s/Xx4f75++vT8tfH36/f3hedXHnNKn0xcxQH5DOokezl3Qy0LeXIxCvuJmvUQoAd76l00dZ7IczzT55peivRY1PrU0H22HWnqMAFejqOP1h5uLmREdjHsZdlztehl7qhsdSONDm9My50gam3unJrWhZfrhs3C6SERUr0UmoGYtgnOf3mlXOpb0/QM0HCsFES5RkkdJjAU1aRTNL2qCvKIijTInSYUWBRFuEM8kHgAifP7qlJJEveibUs4QyqbaSRLSotxJEkmoX8r8jNpHz8LUS10jTl6ZlNWUk1lWbDlJcwKbk8KXplYYHdqklNGpbUoZnNuqlKHJ7UoZmN2ylGHpbUuhFcyQ/NalDGlgX8qADh6kdG/hQ0rnHl6k9G1CK2NvSpp+VRxJ6VfGlZRedZxJ6VPInZQelRxKae/kUUp7K59WWms5tdLWy6uUpmZ+pTR08yzlcDvfUg728y7lWENa6bWPMeorBpBS3zGClPqWtNK+uVnqekaxUvmxQaNSaKOmaBgpNU3jSKnoGklKeVtaOb6ZF2gFUtQ3mpSyxvGsFFQOKGW/c0Qpu6VDStlrHVPKTu2gUrZ7R5VCK5it5nGtbFWnlep1vqEVCIcQZLV7ZCmr5UNLoRUIrUBW6ge3stI/uhUoILwUWoHQCgIYoBRagdAKglYQtIK4VUAptIK5cUApiVYwHEEIWkHQCoLzCoJWINcWaOWFvLEUF1pB5NWFyOSV32NDKwhaQdAKglYQtIKgFQStIGgFQSsIWkHQCoJWELSCoBUErSBoBUErCFpB0AqCVhB8jh9BKwhaQdAKgq+oImgFkTcXo0IrCFpB0AqA/wGGoBUErSBoBUErCFpB0AqCVhC0AuC7GwB8exCCVhC0AuA73xH89BUAFhBdC60gaAVBK4CV+rRS9fcY0AqCVhCr7UNroRXAendaqVvjn43ucbVsNQ9rZbN4VCvbvWnlyGqn7LYOqWW/dEAtBZXjWSlpHM5KWeFoWgr7xtJS2pZW2jb0AK0gystG0kIrgJqqcbRUNY2ipa4nrfTY3Cq0AqhuGUJLfckAWg5U9G/lUEPvWg72863laDta6bmfCY6X86yloZtfLS3NvFrJbcV8amlu5VFLh07+tHRp5E1Lpz7OtNAKoFsbV1r6lXGkpWMVP1a6NvGipXMPJ1p613ChpXsJD1YGdLCvZUgD61oG5betZVh6y1oGZrerZWhyo1oan5Dcv/2xNz+G8aENapkRefTZ2J1JeW1pmZbWkpaJWQ1pmRnVipbJk6ANLdNTWtAikFG9FplLCOVapOKp1iIXTq8W0QtwrVqEc2WNj4o0ZFIQ4RIdgXSdL4rCMAlESxgtORZUxFE0ehYUBFIQ4YYsOuvK3vs2YsHUGnlB4pBpPk3+w+e/MDOfQTYjZWJWQ06eOeQl58o5wpiUdOThUb74UXIPlXegg7pP8Xjbumw3o07SMiQKN73YreB2j2ZSQlH+q402S5s38kLem0XRyrXN7Z8ll6y2wSvyOanArVFWGpUU9ajjH+hYO65bwfWYkM6jCwohhATjL3IdCrM="], {{0, 271}, {278, 0}}, {0, 1},ColorFunction->GrayLevel],BoxForm`ImageTag["Bit", ColorSpace -> Automatic, Interleaving -> None],Selectable->False],BaseStyle->"ImageGraphics",ImageSizeRaw->{278, 271},PlotRange->{{0, 278}, {0, 271}}]\)

enter image description here

$\endgroup$
17
  • 1
    $\begingroup$ Looks like this could help: mathematica.stackexchange.com/questions/27007/… $\endgroup$ Jun 14, 2013 at 13:44
  • 5
    $\begingroup$ You have over 1000 reputation points. I think it's time that you take some time and learn how to properly format your code with markdown. $\endgroup$
    – m_goldberg
    Jun 14, 2013 at 13:53
  • 1
    $\begingroup$ @m_goldberg ok, I'll read that. $\endgroup$ Jun 14, 2013 at 14:10
  • 2
    $\begingroup$ I formatted your code once again. I hope you will study what I did and learn from it. The most important reworking was adding spaces and making line breaks in the proper places to improve the code's readability. $\endgroup$
    – m_goldberg
    Jun 14, 2013 at 14:18
  • 1
    $\begingroup$ What's the {0,0}? $\endgroup$
    – cormullion
    Jun 14, 2013 at 16:00

3 Answers 3

8
$\begingroup$
i1 = ColorNegate@ Opening[Binarize@Import@"https://i.stack.imgur.com/3VEuj.jpg", 1];
ct = 1 /. ComponentMeasurements[FillingTransform@i1, "Centroid"];
r = Mean[EuclideanDistance[ct, #] & /@ PixelValuePositions[i1, 1]];
Show[i1, Graphics[{Thick, Red, Circle[ct, r]}]]

enter image description here

$\endgroup$
3
  • $\begingroup$ Late to respond for struggling with so many questions. I like it. @@ any suggestion for question2 $\endgroup$ Jun 15, 2013 at 14:33
  • $\begingroup$ @HyperGroups Re:your second question. The problem is that you're not imposing any constraints, so the "cusp" could be anything. You could propose a cusp "model", some constraints, anything to thin down the infinite possibilities $\endgroup$ Jun 15, 2013 at 14:39
  • $\begingroup$ Ok, I'll edit after I've done some continued work. $\endgroup$ Jun 15, 2013 at 14:42
6
$\begingroup$

Since the binary image a little noisy, the easiest thing is to Dilate it a bit to make it one connected component.

img = Dilation[ColorNegate[Import["https://i.stack.imgur.com/z7isS.png"]], 1]

enter image description here enter image description here

Now we can use ComponentMeasurements to find the desired properties:

ComponentMeasurements[img, {"Centroid", "EquivalentDiskRadius"}]

{1 -> {{139.859, 131.044}, 68.0123}}

So the center is about {139.859, 131.044} and the radius is 68.0123. Approaching it this way gives this circle:

Show[Import["https://i.stack.imgur.com/z7isS.png"], 
   Graphics[{Thick, Red, Circle[{139.859, 131.044}, 2 68.0123]}]]

enter image description here

$\endgroup$
2
  • $\begingroup$ ha, nicie. I think put one slider in the cusp and drag to fit the whole circle is one way. And you can think my question 2 @@ $\endgroup$ Jun 14, 2013 at 14:09
  • $\begingroup$ I might approach it this way: define an ideal version of the cusped circle. First, locate the best real circle like above to find the approximate center and radius. Then correlate your cusped circle with the image, once for each possible rotation. When you get the highest correlation, you will have the proper orientation of the cusped circle. $\endgroup$
    – bill s
    Jun 14, 2013 at 14:57
6
$\begingroup$

Cusp detection using information from this post, and following the code from @belisarius' answer:

Transformation of the image to polar coordinates:

maxRadius = r + 10;
polar = ImageTransformation[i1, 
ct + {Cos[#[[1]]], Sin[#[[1]]]}*#[[2]] &, {360, maxRadius}, 
DataRange -> Full, 
PlotRange -> {{0, 360 \[Degree]}, {1, maxRadius}}]

result: polar circle

Then we find the position of the peak:

diff = Mean[Flatten[Position[#, 1]]] & /@ 
Transpose[ImageData[polar]];
cusp = Mean[Flatten[Position[diff, Max[diff]]]]

272

Display the detected cusp:

Show[i1, Graphics[{Thick, Red, Circle[ct, r], Green, 
Arrowheads[Large], 
Rotate[Arrow[{ct + {r - 50, 0}, ct + {r, 0}}], 
cusp Degree, ct]}]]

arrow pointing to cusp

$\endgroup$
2
  • $\begingroup$ nice, I should take time to read that post, welcome to move on. $\endgroup$ Jun 16, 2013 at 13:08
  • $\begingroup$ seems @somebody in Answer and Post will not really notify somebody, rm-rf told me yesterday. $\endgroup$ Jun 16, 2013 at 13:09

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.