"""Object shape recognition with circle fittingauthor: Atsushi Sakai (@Atsushi_twi)"""import matplotlib.pyplot as pltimport mathimport randomimport numpy as npshow_animation = Truedef circle_fitting(x, y):"""Circle Fitting with least squaredinput: point x-y positionsoutput cxe x center positioncye y center positionre radius of circleerror: prediction error"""sumx = sum(x)sumy = sum(y)sumx2 = sum([ix ** 2 for ix in x])sumy2 = sum([iy ** 2 for iy in y])sumxy = sum([ix * iy for (ix, iy) in zip(x, y)])F = np.array([[sumx2, sumxy, sumx],[sumxy, sumy2, sumy],[sumx, sumy, len(x)]])G = np.array([[-sum([ix ** 3 + ix * iy ** 2 for (ix, iy) in zip(x, y)])],[-sum([ix ** 2 * iy + iy ** 3 for (ix, iy) in zip(x, y)])],[-sum([ix ** 2 + iy ** 2 for (ix, iy) in zip(x, y)])]])T = np.linalg.inv(F).dot(G)cxe = float(T[0, 0] / -2)cye = float(T[1, 0] / -2)re = math.sqrt(cxe**2 + cye**2 - T[2, 0])error = sum([np.hypot(cxe - ix, cye - iy) - re for (ix, iy) in zip(x, y)])return (cxe, cye, re, error)def get_sample_points(cx, cy, cr, angle_reso):x, y, angle, r = [], [], [], []# points samplingfor theta in np.arange(0.0, 2.0 * math.pi, angle_reso):nx = cx + cr * math.cos(theta)ny = cy + cr * math.sin(theta)nangle = math.atan2(ny, nx)nr = math.hypot(nx, ny) * random.uniform(0.95, 1.05)x.append(nx)y.append(ny)angle.append(nangle)r.append(nr)# ray casting filterrx, ry = ray_casting_filter(x, y, angle, r, angle_reso)return rx, rydef ray_casting_filter(xl, yl, thetal, rangel, angle_reso):rx, ry = [], []rangedb = [float("inf") for _ in range(int(math.floor((math.pi * 2.0) / angle_reso)) + 1)]for i, _ in enumerate(thetal):angleid = math.floor(thetal[i] / angle_reso)if rangedb[angleid] > rangel[i]:rangedb[angleid] = rangel[i]for i, _ in enumerate(rangedb):t = i * angle_resoif rangedb[i] != float("inf"):rx.append(rangedb[i] * math.cos(t))ry.append(rangedb[i] * math.sin(t))return rx, rydef plot_circle(x, y, size, color="-b"): # pragma: no coverdeg = list(range(0, 360, 5))deg.append(0)xl = [x + size * math.cos(np.deg2rad(d)) for d in deg]yl = [y + size * math.sin(np.deg2rad(d)) for d in deg]plt.plot(xl, yl, color)def main():# simulation parameterssimtime = 15.0 # simulation timedt = 1.0 # time tickcx = -2.0 # initial x position of obstaclecy = -8.0 # initial y position of obstaclecr = 1.0 # obstacle radioustheta = np.deg2rad(30.0) # obstacle moving directionangle_reso = np.deg2rad(3.0) # sensor angle resolutiontime = 0.0while time <= simtime:time += dtcx += math.cos(theta)cy += math.cos(theta)x, y = get_sample_points(cx, cy, cr, angle_reso)ex, ey, er, error = circle_fitting(x, y)print("Error:", error)if show_animation: # pragma: no coverplt.cla()# for stopping simulation with the esc key.plt.gcf().canvas.mpl_connect('key_release_event',lambda event: [exit(0) if event.key == 'escape' else None])plt.axis("equal")plt.plot(0.0, 0.0, "*r")plot_circle(cx, cy, cr)plt.plot(x, y, "xr")plot_circle(ex, ey, er, "-r")plt.pause(dt)print("Done")if __name__ == '__main__':main()
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。