How to find the center of a circle using least square in python?

I am trying to fit some data points to find the center of the circle. All of the following points are noisy data points around the circumference of a circle:

data = [(2.2176383052987667, 4.218574252410221), (3.3041214516913033, 5.223500807396272), (4.280815855023374, 6.461487709813785), (4.946375258539319, 7.606952538212697), (5.382428804463699, 9.045717060494576), (5.752578028217334, 10.613667377465823), (5.547729017414035, 11.92662513852466), (5.260208374620305, 13.57722448066025), (4.642126672822957, 14.88238955729078), (3.820310290976751, 16.10605425390148), (2.8099420132544024, 17.225880123445773), (1.5731539516426183, 18.17052077121059), (0.31752822350872545, 18.75261434891438), (-1.2408437559671106, 19.119355580780265), (-2.680901948575409, 19.15018791257732), (-4.190406775175328, 19.001321726517297), (-5.533990404926917, 18.64857428377178), (-6.903383826792998, 17.730112542165955), (-8.082883753215347, 16.928080323602334), (-9.138397388219254, 15.84088004983959), (-9.92610373064812, 14.380575762984085), (-10.358670204629814, 13.018017342781242), (-10.600053524240247, 11.387283417089911), (-10.463673966507077, 10.107554951600699), (-10.179820255235496, 8.429558128401448), (-9.572153386953028, 7.1976672709797676), (-8.641475289758178, 5.8312286526738175), (-7.665976739804268, 4.782663065707469), (-6.493033077746997, 3.8549965442534684), (-5.092340806635571, 3.384419909199452), (-3.6530364510489073, 2.992272643733981), (-2.1522365767310796, 3.020780664301393), (-0.6855406924835704, 3.0767643753777447), (0.7848958776292426, 3.6196842530995332), (2.0614188482646947, 4.32795711960546), (3.2705467984691508, 5.295836809444288), (4.359297538484424, 6.378324784240816), (4.981264502955681, 7.823851404553242)] 

I tried to use some kind of library like Scipy , but I was having problems using the available functions.

There are for example:

 # == METHOD 2 == from scipy import optimize method_2 = "leastsq" def calc_R(xc, yc): """ calculate the distance of each 2D points from the center (xc, yc) """ return sqrt((x-xc)**2 + (y-yc)**2) def f_2(c): """ calculate the algebraic distance between the data points and the mean circle centered at c=(xc, yc) """ Ri = calc_R(*c) return Ri - Ri.mean() center_estimate = x_m, y_m center_2, ier = optimize.leastsq(f_2, center_estimate) xc_2, yc_2 = center_2 Ri_2 = calc_R(*center_2) R_2 = Ri_2.mean() residu_2 = sum((Ri_2 - R_2)**2) 

But does this seem to use one XY? Any ideas on how to connect this function to my data example?

+5
source share
4 answers

Your data seems pretty clean and I don’t see any outliers, so many environment tuning algorithms will work.

I recommend you start with the Coope method, which works by magically linearizing the problem:

(X-Xc)^2+(Y-Yc)^2=R² rewritten as

2XcX+2YcY+R²-Xc²-Yc²=X²+Y² , then

AX+BY+C=X²+Y² , is solved using linear least squares.

+2
source

As a continuation of the publication of Bas Swinckels, I decided that I would send my code by implementing the Halir and Flusser method to set the ellipse

https://github.com/bdhammel/least-squares-ellipse-fitting

Using the code above, you can find the center with the following method.

 from ellipses import LSqEllipse import numpy as np import matplotlib.pyplot as plt from matplotlib.patches import Ellipse lsqe = LSqEllipse() lsqe.fit(data) center, width, height, phi = lsqe.parameters() plt.close('all') fig = plt.figure(figsize=(6,6)) ax = fig.add_subplot(111) ax.axis('equal') ax.plot(data[0], data[1], 'ro', label='test data', zorder=1) ellipse = Ellipse(xy=center, width=2*width, height=2*height, angle=np.rad2deg(phi), edgecolor='b', fc='None', lw=2, label='Fit', zorder = 2) ax.add_patch(ellipse) plt.legend() plt.show() 

enter image description here

+3
source

I have no experience in creating circles, but I worked with a more general case of setting ellipses. Proper data execution using noisy data is not trivial. For this problem, the algorithm described in Halir and Flusser Numerically Resistant Direct Least Square Ellipses works very well. The document includes Matlab code, which should be easy to translate into Numpy. Perhaps you can use this algorithm to match the ellipse, and then take the average of the two axes as a radius or so. Some links in the document also mention suitable circles, you can see them.

+2
source

I know this is an old question, but in 2019, a circle-fit fitting library called circle-fit appeared in python.

 pip install circle-fit 

You can use one of two algorithms to solve, at least_squares_circle or hyper_fit .

 import circle_fit as cf xc,yc,r,_ = cf.least_squares_circle((data) 

then you get xc, yc as the coordinate pair for the center of the solution circle.

0
source

Source: https://habr.com/ru/post/1205549/


All Articles