利用Robocon2018 比赛地图 + OpenCv + matplotlib拟合贝塞尔曲线,并且生成路径坐标点

  • 原文链接

本文内容:

  • 贝塞尔曲线简介
  • 代码算法讲解
  • 总结

贝塞尔曲线简介:

原理:

Github上一位大佬已经总结得很详细了, 还有动态图的哦,,我这里就直接引用啦Github

计算公式:

此处引用一位大佬的总结:@L_Xian;
该大佬不仅解释了贝塞尔曲线的原理,还详细的推导了贝塞尔曲线各阶公式之间的联系。

意义:

此处只说一下对于全向机器人运动的意义:
由于贝塞尔曲线是一条光滑的曲线,即高阶可导。若机器人的运动轨迹可以拟合在这条曲线上,运动转弯将更加顺滑,这就催生了我写这个小程序的想法。利用 Python强大的科学计算,图像处理,绘图能力。将一个标准的场地地图导入,二值化之后,使用在地图上点击的起点与终点已经2个控制点,绘制出3阶贝塞尔曲线,再经过坐标转换,生成适合场地的机器人运动轨迹坐标。

代码算法讲解:

  • Gitub地址

  • 演示

获取鼠标点击的点:

class Get_Point_:
    # 使用OpenCv对图像进行初步的处理

    # 使用 plt获取鼠标点击的坐标
    def Get_Pos(src_img):
        plt.imshow(src_img, cmap=plt.get_cmap("gray"))
        pos = plt.ginput(4)
        return pos

    def Get_Point():
        return Points_List_

    def Get_Image():
        src_img = cv.imread('./img/changdi2.png')
        src_Gray_Image = cv.cvtColor(src_img, cv.COLOR_BGR2GRAY)
        ret, dst_Image = cv.threshold(src_Gray_Image, 98, 255, cv.THRESH_BINARY)
        return dst_Image
  • Get_Pos(src_img):

使用plt显示图像,并且利用.ginput(n)获取n个鼠标点击的点的坐标,这样子的好处是,matplotlib可以很容易的放大缩小图像,且坐标轴方向相对使用OpenCv与实际更为接近。

  • Get_Image():

使用OpenCV将图像灰度化然后二值化,便于观察绘制的曲线。

坐标点的解算:

这里直接使用的3阶贝塞尔曲线的方程,解算出各个坐标点

    # 解算Bezier方程的系数
    def Build_Bezier(Point_0, Point_1, Point_2, Point_3, t):
        A_0 = (1 - t) ** 3
        A_1 = ((1 - t) ** 2) * 3 * t
        A_2 = (t ** 2) * (1 - t) * 3
        A_3 = t ** 3

        x = Point_0[0] * A_0 + Point_1[0] * A_1 + Point_2[0] * A_2 + Point_3[0] * A_3
        y = Point_0[1] * A_0 + Point_1[1] * A_1 + Point_2[1] * A_2 + Point_3[1] * A_3
        return [int(x), int(y)]  # 坐标转换

return [int(x), int(y)]可以根据自己的需要对x, y进行转换之后再返回。

绘制图像

此处我绘制了未拟合的坐标点(红色),已经我们拟合出的路径(绿色)。
可见上面的演示

增加的功能:

既然已经生成了理想的运动轨迹,大可再绘制实际的运动轨迹,只需要利用无线串口之类的模块将机器人的运动轨迹实时传回电脑,然后在场地上绘制出轨迹。如演示图中左上角的绿色的,不太和谐的绿色曲线,,emm,,那个只是我作的一个小实验,,随便弄的几个点,然后画在同一张图中这样子。。

总结:

其实吧,,这个程序挺简单的,但是这个至少可以说明,自己完全可以利用程序实现自己的想法了。

GitHub

你可能感兴趣的:(利用Robocon2018 比赛地图 + OpenCv + matplotlib拟合贝塞尔曲线,并且生成路径坐标点)