欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

基于树莓派的智能小车:自动避障、实时图像传输、视觉车道线循迹、目标检测、网球追踪

程序员文章站 2022-03-28 20:04:52
树莓派智能小车,实现功能:基于超声波和红外的自动避障、树莓派端向PC端的实时图像传输、基于视觉的车道线循迹、基于Tensorflow Object Detection的目标检测、基于视觉的网球追踪。 ......

简介

本项目的github链接

本项目是学校项目设计课程内的项目,要求是使用一个基于树莓派的小车来实现一些简单的功能。

本项目适合初次接触树莓派,希望利用树莓派及小车配件实现一些简单功能的同学们。

目前我们实现的功能有:

  • 自动避障:基于超声波和红外,使小车在运行过程中不会撞上障碍物;
  • 实时图像传输:将树莓派摄像头拍摄到的视频流传到pc端,并在pc端查看;
  • 视觉车道循迹:基于视觉,使小车沿车道线行驶;
  • 目标检测:识别并定位摄像头图像中的各类常见物体;
  • 网球追踪:基于视觉,使小车追踪一个移动的网球,并与网球保持一定距离。

学校提供的小车的商家是,商家提供了一些使用教程,适合初学,基于c语言,实现了一些简单的红外避障、红外寻迹、超声波避障和摄像头调用。

本项目选用python作为编程语言,有几点原因:python相比较c语言更简明;我们对python的掌握情况更好一些(c语言没学好啊);方便之后使用tensorflow做一些深度学习的功能。但同时带来的缺点就是运行速度会差一点。

下面我们会对小车配置、功能实现和使用方法进行详细的介绍。本文结构如下:

  • 配置要求
  • 项目架构
  • 准备工作
  • 硬件调试
  • 功能实现(原理介绍)
  • 功能实现(使用教程)

若想成功实现本项目的功能,请:

  • 首先确保完成准备工作
  • 之后进行硬件调试
  • 之后在阅读过功能实现-原理介绍的基础上
  • 根据功能实现-使用教程来运行相应程序、实现功能

配置要求

  • 树莓派3
  • 驱动板(l298n)
  • csi摄像头
  • 超声波测距传感器
  • 红外避障传感器
  • 小车车体 + 4个电机
  • 电脑 (ubuntu18.04)

项目架构

我们的源代码全部放在pythoncode文件夹内。

我们对每个传感器定义了一个类,放在相应的py文件里,由此可以很清晰方便地对每个传感器进行单独的调试。

名称以main开头的文件是实现相应功能的主程序,在主程序里定义了一个car类,该类继承了所有传感器的类。

准备工作

重装树莓派的系统

商家给树莓派预装了系统,应该是商家自己改过的,也是几年前的了。强烈建议自己将树莓派的系统进行重装(重装后opencv和tensorflow的安装都会简单很多),推荐安装树莓派的官方系统raspbian。安装方法百度一下,教程很多,也很简单。

关于树莓派教程,推荐,里面的教程基本准确好用。

使用ssh登录,操作树莓派

对树莓派进行操作的方法有很多:

我们基本上是使用ssh登录到树莓派进行操作的,也就是使用putty登录。这需要树莓派和pc在同一个局域网下,我们选择让树莓派创建一个wifi热点,然后让pc连接这个wifi热点。方法:创建wifi热点并开机自启动,其中使用了github上一个开源的库create_ap。同时,还要设置热点开机自动启动。另外注意要设置开启树莓派的ssh服务,否则putty连接会显示失败。

更换下载源

使用官方的源因为众所周知的原因会非常慢且不稳定,所以要换成国内的源。

opencv安装

使用最新版树莓派系统,可以直接用pip3安装opencv。

教程:python3 + opencv

硬件调试

首先需要确定树莓派、驱动板、传感器之间的连线是正确的。

电机

直流电机相关知识

  • 工作原理
  • h桥
  • pwm

电机相关代码在move.py内。需要注意gpio端口号的设置,python用的是bcm编码。

基于树莓派的智能小车:自动避障、实时图像传输、视觉车道线循迹、目标检测、网球追踪

在move.py中,定义了前进、后退、左转、右转、停车功能。转弯是通过左右轮差速实现的。

超声波测距传感器

超声波测距传感器有关知识

  • 超声波测距基本原理
  • 超声波测距程序实现
  • 提升测距准确性的方法

超声波相关代码在ultrasound.py内,实现了超声波测距和对测距进行移动平均来减小误差。

红外避障传感器

红外避障相关代码在infrared.py内,infraredmeasure函数是小车左右的两个红外避障传感器,trackingmeasure是小车底部两个红外寻线传感器。

注意,红外避障传感器传回0表示前方有障碍物,传回1表示前方无障碍物。

摄像头

调用摄像头需要先在sudo raspi-config中启用camera,然后重启。

python调用摄像头有两种方式:

  • 使用picamera
  • 使用opencv

我们使用的是picamera方式,因为我们发现使用opencv的方式会有延时,它返回的第一帧图像是在镜头初始化那一刻的图像,而不是主程序请求时的图像。

具体调用方法参考 树莓派(raspberry pi)中picamera+opencv的使用

摄像头相关代码在camera.py中,其中实现了:

  • 摄像头初始化
  • 实时图像传输(发送端),注意host为pc在此wifi网络下的ip地址(通过ifconfig查看),port设置一个和接收端相同的端口号就可以。

另外注意,程序终止是一定要关闭摄像机(camera.close()),否则下次无法正常打开。

功能实现(原理介绍)

自动避障

基于树莓派的智能小车:自动避障、实时图像传输、视觉车道线循迹、目标检测、网球追踪

基于超声波和红外,使小车在运行过程中不会撞上障碍物。

主程序为main_obstacle_avoidance.py,其思想很简单,超声波传感器测出小车距离前方障碍物的距离,两边的红外传感器测出两边是否有障碍物,根据测量结果进行运动决策和电机控制。

实时图像传输

将树莓派摄像头拍摄到的视频流传到pc端,并在pc端查看。目的是为了便于摄像头姿态的调整和图像处理算法的调试。另外,如果需要的话可以使用传输到pc的图像在pc端进行处理(我们没有实现此功能)。

可选择的传输协议有两种:

  • tcp:面向连接,提供可靠地服务,无差错,不丢失,不重复;实时性差,效率低;系统资源要求较多。
  • udp:可以无连接;尽最大努力交付,即不保证可靠交付;实时性强,效率高;系统资源要求较少。

我们使用udp传输协议进行图像传输。具体实现主要分为发送端和接收端两部分:

  • 发送端:(camera.py videotransimssion)
    • 图像编码(cv2.imencode)
    • 校验数据发送(数据长度作为校验)
    • 编码数据发送(socket.sendall)
  • 接收端:(pc_receiver.py)
    • 接收校验数据(4字节数据)
    • 接收图像编码(校验数据后的第一个数据包)
    • 简单校验(校验数据 == 编码数据长度)
    • 图像解码(cv2.imdecode)
      其中,发送端在树莓派端运行,接收端在pc端运行。二者同时运行。

视觉车道循迹

基于视觉,使小车沿车道线行驶。环境要求为白色的地板,黑色(深色)的车道线。

基于树莓派的智能小车:自动避障、实时图像传输、视觉车道线循迹、目标检测、网球追踪
基于树莓派的智能小车:自动避障、实时图像传输、视觉车道线循迹、目标检测、网球追踪

主程序为main_lane_tracking.py,其流程大致如下:

  • 车道线检测
    • 图像二值化,提取车道线
    • 提取车道线的内侧点:在图像的特定行,从中间向两侧检索,检测到0像素点及为车道线点。图像左半边检测到的点即为左车道线点,右半边检测到的点即为右车道线点。(为防止因各种原因车道线部分缺失,我们选择图像4个行提取4组车道线内侧点)
  • 运动控制
    • 运动决策
      • 如果两侧车道线都能检测到,则直行
      • 如果只能检测到一侧车道线,则有三种情况:
        • 该侧车道线靠近图像边缘,则还可以继续直行
        • 该侧车道线靠近图像*,则急需转弯,原地旋转
        • 该侧车道线位置适中,则缓慢转弯,在前进中转弯
      • 如果两侧车道线都检测不到,则维持之前的动作
    • 电机控制:根据决策结果,控制小车电机输出

在本实验中,车道线检测部分较容易实现,我们发现,在这种简单的环境下,固定阈值的二值化效果比大津法好。另外,因为我们的车道线偏蓝色,我们选择提取图像的r通道进行二值化。检测效果如图:

基于树莓派的智能小车:自动避障、实时图像传输、视觉车道线循迹、目标检测、网球追踪

运动控制部分相对较为复杂,我们只采用了一个简单的逻辑,效果还可以。

目标检测

识别并定位摄像头图像中的各类常见物体。

基于树莓派的智能小车:自动避障、实时图像传输、视觉车道线循迹、目标检测、网球追踪

主程序为main_object_detection.py,其调用了tensorflow object detection api,使用了训练好的的ssdlite目标检测模型,在树莓派端进行目标检测。

tensorflow安装方法及tensorflow object detection api配置方法可以完全参考此文档:edjeelectronics/tutorial to set up tensorflow object detection api on the raspberry pi

或者tensorflow object detection api可以直接clone这位的 xyc2690/raspberry_objectdetection_camera,可以不用配置tensorflow object detection api,下载即用。

我们使用的ssdlite模型主要优点是运行速度快、占用内存小,适合在树莓派端进行运算。据我们测试,帧率大概为0.8帧/s。我们使用的是树莓派3,如果是更新的型号,速度会更快一点。

网球追踪

基于摄像头,使小车追踪一个移动的网球,并与网球保持一定距离。

基于树莓派的智能小车:自动避障、实时图像传输、视觉车道线循迹、目标检测、网球追踪

主程序在main_tennis_tracking.py中,网球追踪流程大概如下:

实验显示:
在不同光照条件下,网球的色调(h)基本上保持一致,范围大致在25至50 (opencv范围),在可靠明亮的光照条件下,范围大致在30至40。

网球检测的程序在detect_new.py中,具体流程如下:

  • 关注区域裁切:裁掉不可能出现网球的区域
  • 高斯滤波:去除一定噪声
  • 霍夫圆检测:检测出图像中所有可能存在的圆(视频中的绿色圆)
  • 针对每个检测出的圆的内切正方形:
    • rgb to hsv
    • 利用hsv域计算符合网球颜色的像素点数目
    • 统计上述像素点数目占比
  • 选出占比最大的圆,若其占比大于设定阈值,则认为是网球(视频中的红色圆)
基于树莓派的智能小车:自动避障、实时图像传输、视觉车道线循迹、目标检测、网球追踪

经测试,帧率大概在15帧/s。

运动控制的程序在main_tennis_tracking.py中,具体流程如下:

  • 移动平均:对检测得网球位置进行移动平均,减小误差
  • 决策:根据当前网球相对于小车的位置,决策下一步的动作
    • 根据网球x坐标决策转向动作
    • 根据网球半径r决策前进后退动作
  • 控制:根据决策结果,控制小车电机输出

目前存在的问题:

  • 我们使用的小车是4电机四驱差速转向小车,但在没有细致调教的差速控制算法的情况下,这样的配置使得在小车在转弯的时候存在较大的滑动摩擦(a skidding turn),所以转向时小车存在一个“最低启动速度”,当pwm的占空比小于一定值时,小车由于摩擦力的原因无法真的转起来,在原地“蹩着”,所以要小车转起来,只能给一个相对大的速度,这样就很容易转向过度。
  • 同时,由于摩擦力,小车在转向时也存在明显的车身抖动,使得转向时拍摄的图像发飘发糊,导致此时网球检测得效果也收到影响,进一步影响了转向追网球的准确性。
  • 网球检测的效果受光照的影响还是挺大的,白天光照充足的环境下(白天室外)效果会好很多。

功能实现(使用教程)

自动避障

在树莓派终端中输入:

cd pythoncode
python3 main_obstacle_avoidance.py

实时图像传输

树莓派发送图像,在树莓派终端输入:

cd pythoncode
python3 camera.py

同时,如果想在pc端接收图像,在pc终端输入:

cd pythoncode
python3 pc_receiver.py

notice:camera.py和pc_receiver.py均需要根据具体情况配置host和post:

  • 二者中的host均为pc在此wifi网络下的ip地址(通过ifconfig查看)
  • 二者的port设置为同一个端口号就可以(eg:8000)。

视觉车道循迹

在树莓派终端输入:

cd pythoncode
python3 main_lane_tracking.py

如果想在pc端接收车道检测图像,则在pc终端输入:

cd pythoncode
python3 pc_receiver.py

目标检测

在树莓派终端中输入:

cd pythoncode
python3 main_object_detection.py

如果想在pc端接收图像,则在pc终端输入:

cd pythoncode
python3 pc_receiver.py

notice:tensorflow object detection api 和 ssdlite模型并未上传至此仓库,需要自行安装。二者的安装和配置方法请参考此文档:edjeelectronics/tutorial to set up tensorflow object detection api on the raspberry pi
; 或者tensorflow object detection api可以直接clone这位的 xyc2690/raspberry_objectdetection_camera,可以不用配置tensorflow object detection api,下载即用。

网球追踪

在树莓派终端输入:

cd pythoncode
python3 main_tennis_tracking.py

如果想在pc端接收网球检测图像,则在pc终端输入:

cd pythoncode
python3 pc_receiver.py

notes

all tutorials on raspberry-pi | github