基于ros和yolov5的视觉识别部署测试

基于ros和yolov5的视觉识别部署测试

引言

随着计算机视觉技术的快速发展,目标检测已成为众多应用的核心部分,尤其是在机器人技术和自动化领域。YOLOv5作为一种先进的目标检测模型,因其高效、准确且易于部署而受到广泛欢迎。ROS(Robot Operating System)作为机器人软件开发的事实标准,为机器人系统的开发提供了强大的支持。本文旨在探讨如何将YOLOv5模型集成到ROS环境中,以实现对实时视频流的目标检测。

本文首先介绍了YOLOv5模型的基本结构和工作原理,随后详细阐述了在ROS环境下部署YOLOv5的步骤,包括创建虚拟环境、安装必要的软件包、获取YOLOv5源码以及设置ROS节点来处理来自摄像头的数据流。我们还提供了具体的脚本实例,展示了如何使用ROS节点来捕获图像或视频,并将这些数据送入YOLOv5模型进行目标检测。

Yolov5的网络结构和工作原理

Yolov5采用了一种轻量级的网络结构,由一系列卷积层、池化层和全连接层组成。它通过不同尺度的特征图来检测不同大小的目标,并使用置信度和类别概率来判断检测框的准确性。

Yolov5的工作原理可以分为三个主要步骤:特征提取、目标检测和后处理。在特征提取阶段,Yolov5使用一系列卷积层来提取输入图像的特征。这些特征图具有不同的尺度和语义信息,能够捕捉目标的不同特征。

在目标检测阶段,Yolov5将特征图分为不同的网格,并为每个网格预测一组目标框。每个目标框包含目标位置和类别概率信息。通过调整目标框的位置和大小,并计算其与真实目标框的相似度,Yolov5能够准确地检测出图像中的目标。

在后处理阶段,Yolov5通过非极大值抑制(NMS)算法来消除重叠的检测框,并选择置信度最高的检测结果作为最终输出。通过这种方式,Yolov5能够实现准确且高效的目标检测。

Yolov5在不同数据集上的性能和应用场景

Yolov5在多个数据集上进行了训练和测试,并在目标检测任务中取得了优秀的性能。例如,在COCO数据集上,Yolov5能够达到较高的平均精度和较低的检测时间。这使得Yolov5在实时应用和资源有限的场景中具有广泛的应用前景。

此外,Yolov5还可以应用于不同的目标检测场景。它可以用于车辆检测和识别,人脸检测和识别,物体跟踪和行人检测等任务。Yolov5的高效和准确性使得它在无人驾驶、安防监控、智能交通等领域具有很大的潜力。

在ros里面的部署流程

这里以工控机为例,树莓派等ros主控的部署也与在工控机的部署流程类似,以下步骤以睿抗智能侦查赛道的小车为例。

创建自己的虚拟环境

在这一步之前,首先确保自己的工控机已经安装好conda等基础依赖,这些在工控机中已经存在。
打开终端,使用 annaconda 的 conda 命令创建虚拟环境

conda create -n yolov5 python=3.8

主要基于这段指令:conda create -n <环境名称自定义> python=<python 的版本号>
工控机已安装的python版本可通过以下指令在终端进行查询:

python --version

当显示以下结果,则说明创建环境成功。
在这里插入图片描述
可以通过以下指令进行验证:

conda activate yolov5

运行之后终端会进行刚刚创建好的虚拟环境。

安装pytorch

接下来打开浏览器进入以下网址安装pytorch:https://pytorch.org/get-started/locally/
在这里插入图片描述
选择好 conda 版本和 cpu 版本,在下面便得到安装指令

conda install pytorch torchvision torchaudio cpuonly -c pytorch

粘贴到终端之后回车执行,注意终端首先要进入刚刚创建好的虚拟环境。等待一段时间之后出现以下结果说明安装成功。
在这里插入图片描述
可通过依次输入以下指令回车执行观察输出,验证是否安装成功。若出现 pytorch 版本号就代表安装成功。

python3
import torch
torch.__version__

下载yolov5源码

之后在浏览器输出以下网址获取Yolov5 源码,在其中任选一个即可,这里选择的是monkey_cici/
yolov5。

https://so.gitee.com/?q=yolov5

点击进入–>点击克隆/下载–>下载 zip
在这里插入图片描述
下载完成后,在文件夹下载中找到 yolo-master 压缩包,将其提取。然后再将解压后的文件夹复制到主目录。
打开终端,进入文件夹目录:

cd yolov5-master

输入以下指令进入虚拟环境:

conda activate yolov5

yolov5是我自己刚刚创建的虚拟环境名。
在终端指定清华源安装所需的环境:

pip install -U -r requirements.txt -i https://pypi.tuna.tsinghua.edu.cn/simple

看到以下结果说明所有包和环境安装完成。
在这里插入图片描述

测试yolov5

在终端继续输入以下指令测试yolov5:

python detect.py

等待一段时间后,模型完成下载。当运行成功后,结果会保存在 runs/detect/exp。即以下结果:
在这里插入图片描述
进入上述路径便可查看 yolov5 实现目标检测结果。
路径~/yolov5-master/data/images是 yolov5 获取源图片的位置,我们将需要自定义检测的图片放入即可完成对识别对象的替换。替换完成之后再运行以下指令便可完成识别

python detect.py

yolov5相关二次开发

如果要实现使用小车相机进行目标检测,则打开 detect.py 文件,将 default = ROOT / “data/images”改为 default=ROOT / “0” 【0 表示使用笔记本默认摄像头】,完成之后再次运行python detect.py。若想用其他外接摄像头进行检测操作,则需要将这里的 default = ‘0’改为 default = ‘1’或者‘2’等,需 usb 摄像头搭载在哪里,输入指令 ls -l /dev/video* 查看。

由于yolov5的识别对象存储在路径~/yolov5-master/data/images下,因此我们可以自己编写一个脚本完成拍照或者录像,再将拍照所得到的jpg格式图片或者录像截取的jpg格式图片存储在yolov5获取识别对象路径下即可。这里提供拍照的脚本demo:

#!/usr/bin/env python3  
# encoding=utf-8  
import rospy  
from sensor_msgs.msg import Image  
from cv_bridge import CvBridge, CvBridgeError  
import os  
import cv2  # 导入cv2模块  
import time  
  
class ImageSaverNode:  
    def __init__(self):  
        # 初始化ROS节点  
        rospy.init_node('image_saver', anonymous=True)  
  
        # 创建一个CvBridge对象,用于在ROS图像消息和OpenCV图像格式之间转换  
        self.bridge = CvBridge()  
  
        # 订阅图像话题,不同相机驱动获取的图像话题名称可能不一致,需要调试
        self.image_sub = rospy.Subscriber("/camera/color/image_raw", Image, self.callback)  
  
        # 设置保存图像的文件夹  
        self.save_folder = "/home/mowen/桌面/yolov5/test1"  
        if not os.path.exists(self.save_folder):  
            os.makedirs(self.save_folder)  
  
        # 设置连拍张数和间隔时间(秒)  
        self.num_photos = 3  
        self.interval = 0.01  # 每秒拍一张,调整间隔时间为1秒  
  
        # 初始化计数器  
        self.count = 0  
  
        # 等待直到拍摄完所有照片或节点被关闭  
        while not rospy.is_shutdown() and self.count < self.num_photos:  
            # 这里不需要调用rospy.spin(),因为我们在循环中等待  
            time.sleep(0.1)  # 简单的轮询等待,可以根据需要调整  
  
        # 拍摄完所有照片后关闭节点  
        rospy.signal_shutdown("Finished taking photos")  
  
    def callback(self, data):  
        # 检查是否还有图片需要保存  
        if self.count < self.num_photos:  
            try:  
                # 将ROS图像消息转换为OpenCV图像  
                cv_image = self.bridge.imgmsg_to_cv2(data, "bgr8")  
  
                # 保存图像  
                file_name = os.path.join(self.save_folder, "image_{}.jpg".format(self.count))  
                cv2.imwrite(file_name, cv_image)  
                rospy.loginfo("Saved {}".format(file_name))  
  
                # 更新计数器  
                self.count += 1  
  
                # 如果需要间隔拍摄,则等待  
                if self.interval > 0:  
                    time.sleep(self.interval)  
  
            except CvBridgeError as e:  
                rospy.logerr(e)  
  
if __name__ == '__main__':  
    try:  
        image_saver = ImageSaverNode()    
    except rospy.ROSInterruptException:  
        pass

如果是通过录像,这里也提供脚本demo:

#!/usr/bin/env python3  
# encoding=utf-8  
import rospy  
from sensor_msgs.msg import Image  
from cv_bridge import CvBridge, CvBridgeError  
import os  
import cv2  
  
  
class VideoRecorderNode:  
    def __init__(self):  
        # 初始化ROS节点  
        rospy.init_node('video_recorder', anonymous=True)  

        self.bridge = CvBridge()  
  
        # 订阅图像话题  
        self.image_sub = rospy.Subscriber("/camera/color/image_raw", Image, self.callback)  
  
        # 设置保存视频的文件夹和文件名  
        self.save_folder = "/home/mowen/test_ws/src/cam/scripts/saved_videos"  
        if not os.path.exists(self.save_folder):  
            os.makedirs(self.save_folder)  
        self.video_file = os.path.join(self.save_folder, "output.avi")  
   
        self.fourcc = cv2.VideoWriter_fourcc(*'XVID')  
        self.out = cv2.VideoWriter(self.video_file, self.fourcc, 20.0, (640, 480))  
  
        # 注册一个回调函数,在ROS节点关闭时释放视频文件  
        rospy.on_shutdown(self.cleanup)  
  
        # 保持节点运行,等待回调函数执行  
        rospy.spin()  
  
    def callback(self, data):  
        try:  
            # 将ROS图像消息转换为OpenCV图像  
            cv_image = self.bridge.imgmsg_to_cv2(data, "bgr8")  
  
            # 写入视频文件  
            self.out.write(cv_image)  
  
        except CvBridgeError as e:  
            rospy.logerr(e)  
  
    def cleanup(self):  
        # 确保视频文件正确关闭  
        self.out.release()  
        rospy.loginfo("Video file released and closed.")  
  
  
if __name__ == '__main__':  
    try:  
        video_recorder = VideoRecorderNode()  
    except rospy.ROSInterruptException:  
        pass

这个脚本demo得到的视频文件是avi格式的,要转换成mp4格式,这里也提供脚本demo:

#!/usr/bin/env python3  
#encoding=utf-8
import subprocess  
import os  
  
def convert_video_to_mp4(input_video_path, output_video_path):  
    
    try:  
        # 构造ffmpeg命令  
        ffmpeg_command = [  
            'ffmpeg',  
            '-i', input_video_path,  # 输入文件  
            '-c:v', 'libx264',       # 使用H.264视频编码器  
            '-crf', '23',            
            output_video_path        # 输出文件  
        ]  
          
        subprocess.run(ffmpeg_command, check=True)  
        print(f"Video converted successfully: {output_video_path}")  
    except subprocess.CalledProcessError as e:  
        print(f"Failed to convert video: {e}")  

def play_video(video_path):  

    if not os.path.exists(video_path):  
        print(f"Video file not found: {video_path}")  
        return  

    try:  
         
        subprocess.run(['smplayer', video_path], check=True)  
    except subprocess.CalledProcessError as e:  
         
        print(f"Failed to play video with SMPlayer: {e}")  
    except FileNotFoundError:  
        
        print("SMPlayer not found. Please ensure it is installed and in your system PATH.")  

if __name__ == '__main__':  
    input_avi_path = '/home/mowen/test_ws/src/cam/scripts/saved_videos/output.avi'  # AVI视频文件的完整路径  
    output_mp4_path = '/home/mowen/test_ws/src/cam/scripts/saved_videos/output.mp4'  # MP4视频文件的完整路径  
    if os.path.exists(input_avi_path):  
        convert_video_to_mp4(input_avi_path, output_mp4_path)  
        play_video(output_mp4_path)  # 转换后播放视频 
    else:  
        print(f"AVI video file not found: {input_avi_path}")

通过这个脚本可以将avi格式视频转换成mp4格式视频。

Yolov5的改进和未来发展方向

尽管Yolov5已经取得了很大的成功,但仍然存在一些改进的空间和发展方向。首先,Yolov5在处理小目标和密集目标方面仍然存在一定的挑战。这是由于Yolov5的特征提取方式和目标检测算法的限制所导致的。未来的发展方向可以包括设计更加复杂的网络结构和引入更多的数据增强技术。

此外,Yolov5还可以进一步优化其目标检测和分类性能。可以通过引入注意力机制、多尺度特征融合和级联检测等技术来提高Yolov5的准确性和鲁棒性。此外,还可以通过引入预训练模型和迁移学习等方法来提高Yolov5在不同数据集和任务上的泛化能力。

小结

通过上述步骤,希望可以帮助大家了解到如何在ROS环境下成功部署YOLOv5进行目标检测,并能够利用ROS的强大功能来实现复杂的应用场景。这种结合使得YOLOv5能够在各种机器人和自动化系统中发挥重要作用,特别是在需要实时处理大量视觉信息的情况下。

【资源介绍】 基于ROSyolov5实时目标检测python源码+项目说明.zip 开发环境: - Ubuntu 16.04 / 18.04 - ROS kinetic/melodic - Python>=3.6.0环境,PyTorch>=1.7 安装Anaconda: 1.首先下载对应的安装包[Anaconda](https://www.anaconda.com/products/individual#linux) 2.然后执行脚本安装anaconda(文件名为下载对应的.sh文件名) ``` bash ~/Downloads/Anaconda3-2021.05-Linux-x86_64.sh ``` 安装 Pytorch: 1. 首先创建python3.6以上版本的conda环境 ``` conda create -n mypytorch python=3.8 ``` 2. 激活创建好的conda环境 ``` conda activate mypytorch ``` 3. 在PyTorch官网上选择指定版本安装Pytorch Install PyTorch: https://pytorch.org/get-started/locally/ ``` conda install pytorch torchvision torchaudio cpuonly -c pytorch ``` 安装Yolov5_ROS ``` cd /your/catkin_ws/src csdn下载源码解压 cd yolov5_ros/yolov5 sudo pip install -r requirements.txt ``` 基于ROSyolov5实时目标检测python源码+项目说明.zip 【备注】 该项目是个人毕设/课设/大作业项目,代码都经过严格调试测试,功能ok才上传,可快速上手运行!欢迎下载使用,若遇到问题请及时私信沟通,帮助解决。 该资源主要针对计算机、通信、人工智能、自动化等相关专业的学生、老师或从业者下载使用,可直接作为期末课程设计、课程大作业、毕业设计等。 项目整体具有较高的学习借鉴价值!基础还可以,动手能力强的也可做二次开发,以实现不同的功能。 欢迎下载使用,也欢迎交流学习!
1 目标检测的定义 目标检测(Object Detection)的任务是找出图像中所有感兴趣的目标(物体),确定它们的类别位置,是计算机视觉领域的核心问题之一。由于各类物体有不同的外观、形状姿态,加上成像时光照、遮挡等因素的干扰,目标检测一直是计算机视觉领域最具有挑战性的问题。 目标检测任务可分为两个关键的子任务,目标定位目标分类。首先检测图像中目标的位置(目标定位),然后给出每个目标的具体类别(目标分类)。输出结果是一个边界框(称为Bounding-box,一般形式为(x1,y1,x2,y2),表示框的左上角坐标右下角坐标),一个置信度分数(Confidence Score),表示边界框中是否包含检测对象的概率各个类别的概率(首先得到类别概率,经过Softmax可得到类别标签)。 1.1 Two stage方法 目前主流的基于深度学习的目标检测算法主要分为两类:Two stageOne stage。Two stage方法将目标检测过程分为两个阶段。第一个阶段是 Region Proposal 生成阶段,主要用于生成潜在的目标候选框(Bounding-box proposals)。这个阶段通常使用卷积神经网络(CNN)从输入图像中提取特征,然后通过一些技巧(如选择性搜索)来生成候选框。第二个阶段是分类位置精修阶段,将第一个阶段生成的候选框输入到另一个 CNN 中进行分类,并根据分类结果对候选框的位置进行微调。Two stage 方法的优点是准确度较高,缺点是速度相对较慢。 常见Tow stage目标检测算法有:R-CNN系列、SPPNet等。 1.2 One stage方法 One stage方法直接利用模型提取特征值,并利用这些特征值进行目标的分类定位,不需要生成Region Proposal。这种方法的优点是速度快,因为省略了Region Proposal生成的过程。One stage方法的缺点是准确度相对较低,因为它没有对潜在的目标进行预先筛选。 常见的One stage目标检测算法有:YOLO系列、SSD系列RetinaNet等。 2 常见名词解释 2.1 NMS(Non-Maximum Suppression) 目标检测模型一般会给出目标的多个预测边界框,对成百上千的预测边界框都进行调整肯定是不可行的,需要对这些结果先进行一个大体的挑选。NMS称为非极大值抑制,作用是从众多预测边界框中挑选出最具代表性的结果,这样可以加快算法效率,其主要流程如下: 设定一个置信度分数阈值,将置信度分数小于阈值的直接过滤掉 将剩下框的置信度分数从大到小排序,选中值最大的框 遍历其余的框,如果当前框的重叠面积(IOU)大于设定的阈值(一般为0.7),就将框删除(超过设定阈值,认为两个框的里面的物体属于同一个类别) 从未处理的框中继续选一个置信度分数最大的,重复上述过程,直至所有框处理完毕 2.2 IoU(Intersection over Union) 定义了两个边界框的重叠度,当预测边界框真实边界框差异很小时,或重叠度很大时,表示模型产生的预测边界框很准确。边界框A、B的IOU计算公式为: 2.3 mAP(mean Average Precision) mAP即均值平均精度,是评估目标检测模型效果的最重要指标,这个值介于0到1之间,且越大越好。mAP是AP(Average Precision)的平均值,那么首先需要了解AP的概念。想要了解AP的概念,还要首先了解目标检测中PrecisionRecall的概念。 首先我们设置置信度阈值(Confidence Threshold)IoU阈值(一般设置为0.5,也会衡量0.75以及0.9的mAP值): 当一个预测边界框被认为是True Positive(TP)时,需要同时满足下面三个条件: Confidence Score > Confidence Threshold 预测类别匹配真实值(Ground truth)的类别 预测边界框的IoU大于设定的IoU阈值 不满足条件2或条件3,则认为是False Positive(FP)。当对应同一个真值有多个预测结果时,只有最高置信度分数的预测结果被认为是True Positive,其余被认为是False Positive。 PrecisionRecall的概念如下图所示: Precision表示TP与预测边界框数量的比值
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值