code: def circle_fit(edge, ret_dev=False):
      
      sx, sy = edge.shape
      x = np.linspace(0, sx, sx, endpoint=False).reshape(-1, 1)
      y = np.linspace(0, sy, sy, endpoint=False).reshape(1, -1)
      params = lmfit.Parameters()
      # initial parameters
      sum_edge = np.sum(edge)
      params.add("cx", np.sum(x * edge) / sum_edge)
      params.add("cy", np.sum(y * edge) / sum_edge)
      # data
      xedge, yedge = np.where(edge)
      # minimize
      out = lmfit.minimize(circle_residual, params, args=(xedge, yedge))
      center = (out.params["cx"].value, out.params["cy"].value)
      radii = circle_radii(out.params, xedge, yedge)
      radius = np.mean(radii)
  
      ret = [center, radius]
      if ret_dev:
          dev = np.average(np.abs(radii - radius))
          ret.append(dev)
      return ret
docs: Fit a circle to a boolean edge image
  
      Parameters
      ----------
      edge: 2d boolean ndarray
          Edge image
      ret_dev: bool
          Return the average deviation of the distance from contour to
          center of the fitted circle.
  
      Returns
      -------
      center: tuple of (float, float)
          Coordinates of the circle center
      radius: float
          Radius of the circle [px]
      rdev:
          Only returned if `ret_dev` is True
          Average deviation of the radius from the circle