# How to fit implicit function based on an image in mathematica?

I know how to make a plot given a function, but I don't know how to get implicit function based on an image.

For example, I have the image shown below (thumbnail):

Full size image import:

Import @ "https://i.stack.imgur.com/SLkeC.png"


I want to find the math function within it. It seems to be an ellipse, but what is a good way to get the function that plot as this ellipse?

• Please show us the code you evaluated to get the image shown above. Add it to your question by making an edit to it. – m_goldberg Jan 15 '18 at 3:01
• Simon says this is the answers to your question mathematica.stackexchange.com/a/17780/8070 – Sumit Jan 15 '18 at 9:01
• @Sumit, I read this post,but that method cannot get implicit function.And I cannot open Michael Trott's 3 post. – kittygirl Jan 15 '18 at 9:34
• Note that the is not a unique function that has the boundary of the shape as zero-set. – Henrik Schumacher Jan 15 '18 at 11:20
• Perhaps these Q&A are closer to your question: (25589), (99578) – Michael E2 Jan 15 '18 at 20:47

Along the same line, I first binarize the image to obtain the ellipse, and rotate the image to get the correct origin of the pixel coordinates (we should recall that the pixel coordinates origin are at the left top corner):

imgbw = Binarize[ImageRotate[img, 270 Degree],Method -> {"BlackFraction", 0.99}];
elip = N@Position[ImageData@imgbw, 1];


Now, we fit the best ellipse by means of 51491:

lin = {#1^2, #1, #2, 2 #1 #2, #2^2} & @@@ elip;
lm = LinearModelFit[lin, {1, a, b, c, d}, {a, b, c, d}];
pa = lm["BestFitParameters"];
w[x_, y_] := pa.{1, x^2, x, y, 2 x y} - y^2;
ContourPlot[w[x, y] == 0,
{x, 200, 400}, {y, 200, 500}, ContourStyle -> {Black, Dashed},
Epilog -> {Red, , PointSize[0.003], Point[elip]}]


$w[x,y]=-3.06274 x^2-y^2+1192.22 x+152.71 y+1.829648 xy-196494=0$

lhere is a function which returns an implicit function such as the equation of an ellipse.

functionThatReturnsImplicit[image_] := Module[
{img,edgeCoordinates,lin},
edgeCoordinates = PixelValuePositions[EdgeDetect[image],1];

lin = {#1^2, #1, #2, 2 #1 #2, #2^2} & @@@edgeCoordinates;
lm = LinearModelFit[lin, {1, a, b, c, d}, {a, b, c, d}];

pa = lm["BestFitParameters"];
w[xx_, yy_] := pa.{1, xx^2, xx, yy, 2 xx yy} - yy^2;
w[x, y] == 0
]


for instance

     image = Import@"https://i.stack.imgur.com/SLkeC.png";


   functionThatReturnsImplicit[image]

   -197019. + 1190.93 x - 3.05173 x^2 + 157.116 y + 1.81471 x y - y^2 == 0


• Your function functionThatReturnsImplicit doesn't use its argument image... – Alexey Popkov Jan 16 '18 at 1:06
• @AlexeyPopkov thanks I will edit it, my bad – Conor Cosnett Jan 16 '18 at 6:50

Yet another approach:

img = Import@"https://i.stack.imgur.com/SLkeC.png";
{center, sa, angle} =
1 /. ComponentMeasurements[AlphaChannel@img, {"Centroid", "SemiAxes", "Orientation"}];
Show[Binarize[img], Graphics[{Blue, Thick, Dashed, Rotate[Circle[center, sa], angle]}]]


m = TransformedRegion[Ellipsoid[center, sa], RotationTransform[angle]][[2]];
ellipseEquation = Expand[({x, y} - center).Inverse[m].({x, y} - center) - 1] == 0


$0.000349686 x^2-0.000207989 x y-0.136216 x+0.000114855 y^2-0.0181534 y+22.5165=0$

Show[ContourPlot[Evaluate@ellipseEquation, {x, 200, 400}, {y, 200, 500}],
Graphics[{Red, Thick, Dashed, Rotate[Circle[center, sa], angle]}]]