def fit_circle(points_l, scale, debug=False): """Get information about a circle from a list of points `points_l`. This may involve fitting a circle or ellipse to a set of points? pip install circle-fit https://github.com/AlliedToasters/circle-fit Assuing for now that points_l contains a list of (x,y,z) points, so we take only (x,y) and scale according to `scale`. Both methods return a tuple of four values: xc: x-coordinate of solution center (float) yc: y-coordinate of solution center (float) R: Radius of solution (float) variance or residual (float) These methods should be identical if we're querying this with actual circles. Returning the second one for now. """ from circle_fit import hyper_fit, least_squares_circle data = [(item[0] * scale, item[1] * scale) for item in points_l] data = np.array(data) circle_1 = hyper_fit(data) circle_2 = least_squares_circle(data) xc_1, yc_1, r_1, _ = circle_1 xc_2, yc_2, r_2, _ = circle_2 if debug: print(f'(hyperfit) rad {r_1:0.4f}, center ({xc_1:0.4f},{yc_1:0.4f})') print(f'(least-sq) rad {r_2:0.4f}, center ({xc_2:0.4f},{yc_2:0.4f})') return circle_2
def detect_fit_cercle(myimg, y1, y2): #obsolete edgeX = [] edgeY = [] cercle_edge = [] for i in range(y1 + 10, y2 - 10): li = myimg[i, :-5] li_filter = savgol_filter(li, 51, 3) li_gr = np.gradient(li_filter) a = np.where((abs(li_gr) > 80)) if i == 650: plt.plot(li_gr) plt.show() s = a[0] if s.size != 0: c_x1 = s[0] c_x2 = s[-1] edgeX.append(c_x1) edgeY.append(i) edgeX.append(c_x2) edgeY.append(i) cercle_edge.append([c_x1, i]) cercle_edge.append([c_x2, i]) #best fit du cercle centre, radius, rms CercleFit = cf.hyper_fit(cercle_edge) #print (CercleFit) #calcul des x,y cercle cy = CercleFit[1] cx = CercleFit[0] radius = CercleFit[2] cercle = [] for y in range(y1, y2): x = ((radius * radius - ((y - cy) * (y - cy)))**0.5) xa = cx - x cercle.append([xa, y]) xb = cx + x cercle.append([xb, y]) # plot cercle sur image np_m = np.asarray(cercle_edge) xm, ym = np_m.T np_cercle = np.asarray(cercle) xc, yc = np_cercle.T plt.imshow(myimg) plt.scatter(xm, ym, s=0.1, marker='.', edgecolors=('red')) plt.scatter(xc, yc, s=0.1, marker='.', edgecolors=('green')) plt.show() return CercleFit
def fit(points): center_x, center_y, radius, _ = hyper_fit(points) return Circle(Point(center_x, center_y), radius)
def test_hyper_fit(self): circle = hyper_fit(self.data) circle = hyper_fit(self.numpy_data)