scipy
私は自分のポイントに円を最もよく「合わせる」ために使用します。単純な重心計算によって、中心と半径の開始点を取得できます。これは、ポイントが円全体に均一に分布している場合にうまく機能します。以下の例のように、そうでない場合でも、何もないよりはましです。
円はシンプルなのでフィッティング機能もシンプルです。接線 (半径) サーフェスが常に最適であるため、フィット円からポイントまでの半径距離を見つけるだけで済みます。
import numpy as np
from scipy.spatial.distance import cdist
from scipy.optimize import fmin
import scipy
# Draw a fuzzy circle to test
N = 15
THETA = np.random.random(15)*2*np.pi
R = 1.5 + (.1*np.random.random(15) - .05)
X = R*np.cos(THETA) + 5
Y = R*np.sin(THETA) - 2
# Choose the inital center of fit circle as the CM
xm = X.mean()
ym = Y.mean()
# Choose the inital radius as the average distance to the CM
cm = np.array([xm,ym]).reshape(1,2)
rm = cdist(cm, np.array([X,Y]).T).mean()
# Best fit a circle to these points
def err((w,v,r)):
pts = [np.linalg.norm([x-w,y-v])-r for x,y in zip(X,Y)]
return (np.array(pts)**2).sum()
xf,yf,rf = scipy.optimize.fmin(err,[xm,ym,rm])
# Viszualize the results
import pylab as plt
fig = plt.figure()
ax = fig.add_subplot(1, 1, 1)
# Show the inital guess circle
circ = plt.Circle((xm, ym), radius=rm, color='y',lw=2,alpha=.5)
ax.add_patch(circ)
# Show the fit circle
circ = plt.Circle((xf, yf), radius=rf, color='b',lw=2,alpha=.5)
ax.add_patch(circ)
plt.axis('equal')
plt.scatter(X,Y)
plt.show()