草庐IT

YOLOv5 小目标检测、无人机视角小目标检测

liguiyuan112 2023-04-13 原文

1.简述

近年随着无人机的快速发展,通用无人机已广泛应用于摄影、农业、监控等多个领域。这里举个例子,比如我们要监控城市主干道的交通情况,就可以通过无人机传回画面来实时监控。我们可以通过人工智能技术来分析传回的图像,来统计行人、汽车的流通量。

然而,也是存在难点:(1)部分目标过小,无人机拍摄的画面比较远时,而行人在远景中就显得非常小,容易漏检;(2)航拍的视频画面中,有大量的检测物体,可能会同时出现几十上百个目标,而目标被遮挡或重叠,也造成不小的难度。

这里我采用YOLOv5算法及VisDrone2021数据集来实现自己的小目标检测任务。

2.数据集处理

(1)数据集下载

VisDrone2021数据集,是无人机视觉目标检测的数据集,VisDrone2021版本和VisDrone2019是同一个数据集,里面包含很多的小目标。这个数据集不需要注册,可以免费下载。作者提供了百度网盘和谷歌网盘的下载方式。

下载地址:Object Detection – VisDrone

(2)密集区域过滤

整理数据集的时候发现有一个分类是 "ignored regions",这个是忽略的区域,因为有些区域包含了密集的很小的目标,是无法进行标注的,所以我们要把这个区域忽视掉。这里我直接用opencv来进行覆盖住就可以了。

 (遮挡前)

 

(密集小目标遮挡后)

(3)图片分割、标签生成

因为我们要检测的图像分辨率很大,比如无人机拍摄的图片尺寸为5630x4314,但又有些目标很小,如果直接把图像缩放到640x640训练的话,效果不好,很多小目标就检测不到了。

因为:yolov5使用了5次下采样,最后输出的特征图大小是20 * 20, 40 * 40, 80 * 80

80* 80 负责检测小目标的,对应到640 * 640 上,每格特征图对应的感受野大小是 640/80=8 * 8。再对应到原图中,以长边为例,5630/640 * 8 = 71,即原图中目标小于71像素的目标,是无法学习到有效特征的。

所以要对原图分割成多个小图再进行检测,我这里把图像分割成 2行3列,即6个小图。

有一点值得注意的是,有一些目标正好位于两个小图中间,正好被截断了,这就可能导致检测不到目标。为了避免这种情况,我们在两个小图之间设置一个overlap重叠区域,这里我设置的重叠区域面积占总面积的20%。

然后把标签中boxes的坐标也要跟着做相应的变换,保存到VisDrone_chip文件夹中。同时,生成yolov5训练所需要的标签格式。

原图分割后生成的训练目录:

3.模型训练

(1)创建自己的数据

我们首先用git拉取YOLOv5的代码,github地址:

GitHub - ultralytics/yolov5: YOLOv5 🚀 in PyTorch > ONNX > CoreML > TFLiteYOLOv5 🚀 in PyTorch > ONNX > CoreML > TFLite. Contribute to ultralytics/yolov5 development by creating an account on GitHub.https://github.com/ultralytics/yolov5.git

然后在yolov5/data/ 目录下创建自己的数据集配置文件 VisDrone_data.yaml

# VisDrone2019-DET dataset https://github.com/VisDrone/VisDrone-Dataset

# Train/val/test sets as 1) dir: path/to/imgs, 2) file: path/to/imgs.txt, or 3) list: [path/to/imgs1, path/to/imgs2, ..]
train: ./data/VisDrone_chip/images/train  # train images (relative to 'path')  6471 images
val: ./data/VisDrone_chip/images/val  # val images (relative to 'path')  548 images
test: ./data/VisDrone_chip/images/test  # test images (optional)  1610 images

# Classes
nc: 10  # number of classes
names: ['pedestrian', 'people', 'bicycle', 'car', 'van', 'truck', 'tricycle', 'awning-tricycle', 'bus', 'motor']

这里我们把 "others"这个分类去掉,一共10个类别。

(2)创建自己的模型

进入到yolov5/models/ 目录下,拷贝一个模型作为自己的模型,这里我分别尝试了YOLOv5的small版本和large版本模型,这里就用small版本进行讲解。

cp yolov5s.yaml yolov5s_visdrone.yaml

然后修改类别的数量,这里共有10个分类,把nc的参数改为10: 

(3)模型训练

下载pretrain模型模型 YOLOv5s , 存放在yolov5 目录里。

开始训练:

python train.py --img 640 --batch 16 --epochs 100 --data ./data/VisDrone_data.yaml --weights yolov5s.pt

这里我训练100个epochs,经过9个多小时的训练,训练结果如下:

 

 mAP@0.5 达到了0.591,效果挺好的。

YOLOv5l 版本则经过漫长的26个小时训练, mAP@0.5 达到了0.648,效果非常好。

4.推理合并

在模型推理的时候,输入的是一张无人机拍下是原始图像,我们同样也需要把原图切割成多个小图来推理,再把小图的推理的结果合并到原图,然后再统一做nms操作。

步骤:

(1)小图跑模型推理,得到推理结果pred;

(2)对pred的结果中boxes位置进行坐标转换,转换为对应于原图中的位置;

(3)把各个小图推理的结果用 torch.cat 来进行合并;

(4)使用nms非极大值抑制 过滤掉重复的框。

训练后模型检测效果:

显示标签的效果:

 

 

 可以看到效果是非常好的,无论对于大目标还是行人等小目标,无论夜间还是白天的画面,精度的表现都挺不错的。


转载文章请注明出处:YOLOv5 小目标检测_liguiyuan的博客-CSDN博客

参考:

深入浅出Yolo系列之Yolov5核心基础知识完整讲解 - 知乎

目标检测任务超大图像的切图实现_zengwb的博客-CSDN博客

有关YOLOv5 小目标检测、无人机视角小目标检测的更多相关文章

  1. ruby - RuntimeError(自动加载常量 Apps 多线程时检测到循环依赖 - 2

    我收到这个错误:RuntimeError(自动加载常量Apps时检测到循环依赖当我使用多线程时。下面是我的代码。为什么会这样?我尝试多线程的原因是因为我正在编写一个HTML抓取应用程序。对Nokogiri::HTML(open())的调用是一个同步阻塞调用,需要1秒才能返回,我有100,000多个页面要访问,所以我试图运行多个线程来解决这个问题。有更好的方法吗?classToolsController0)app.website=array.join(',')putsapp.websiteelseapp.website="NONE"endapp.saveapps=Apps.order("

  2. ruby - 检测由 RSpec、Ruby 运行的代码 - 2

    我想知道我的代码是否在rspec下运行。这可能吗?原因是我正在加载一些错误记录器,这些记录器在测试期间会被故意错误(expect{x}.toraise_error)弄得乱七八糟。我查看了我的ENV变量,没有(明显的)测试环境变量的迹象。 最佳答案 在spec_helper.rb的开头添加:ENV['RACK_ENV']='test'现在您可以在代码中检查RACK_ENV是否经过测试。 关于ruby-检测由RSpec、Ruby运行的代码,我们在StackOverflow上找到一个类似的问题

  3. ruby - 使用 Ruby Daemons gem 检测停止 - 2

    我正在使用rubydaemongem。想知道如何向停止操作添加一些额外的步骤?希望我能检测到停止被调用,并向其添加一些额外的代码。任何人都知道我如何才能做到这一点? 最佳答案 查看守护程序gem代码,它似乎没有用于此目的的明显扩展点。但是,我想知道(在守护进程中)您是否可以捕获守护进程在发生“停止”时发送的KILL/TERM信号...?trap("TERM")do#executeyourextracodehereend或者你可以安装一个at_exit钩子(Hook):-at_exitdo#executeyourextracodehe

  4. ruby - Ruby 脚本如何检测到它正在 irb 中运行? - 2

    我有一个定义类的Ruby脚本。我希望脚本执行语句BoolParser.generate:file_base=>'bool_parser'仅当脚本作为可执行文件被调用时,而不是当它被irbrequire(或通过-r在命令行上传递)时。我可以用什么来包装上面的语句,以防止它在我的Ruby文件加载时执行? 最佳答案 条件$0==__FILE__...!/usr/bin/ruby1.8classBoolParserdefself.generate(args)p['BoolParser.generate',args]endendif$0==_

  5. Ruby 无法检测字符串中的换行符 - 2

    我有以下字符串,我想检测那里的换行符。但是Ruby的字符串方法include?检测不到它。我正在运行Ruby1.9.2p290。我哪里出错了?"/'ædres/\nYour".include?('\n')=>false 最佳答案 \n需要在双引号内,否则无法转义。>>"\n".include?'\n'=>false>>"\n".include?"\n"=>true 关于Ruby无法检测字符串中的换行符,我们在StackOverflow上找到一个类似的问题: h

  6. 【自动驾驶环境感知项目】——基于Paddle3D的点云障碍物检测 - 2

    文章目录1.自动驾驶实战:基于Paddle3D的点云障碍物检测1.1环境信息1.2准备点云数据1.3安装Paddle3D1.4模型训练1.5模型评估1.6模型导出1.7模型部署效果附录show_lidar_pred_on_image.py1.自动驾驶实战:基于Paddle3D的点云障碍物检测项目地址——自动驾驶实战:基于Paddle3D的点云障碍物检测课程地址——自动驾驶感知系统揭秘1.1环境信息硬件信息CPU:2核AI加速卡:v100总显存:16GB总内存:16GB总硬盘:100GB环境配置Python:3.7.4框架信息框架版本:PaddlePaddle2.4.0(项目默认框架版本为2.3

  7. ruby - 重新连接 tcpsocket(或如何检测已关闭的套接字) - 2

    我有一个连接到服务器的ruby​​tcpsocket客户端。在发送数据之前如何检查套接字是否已连接?我是否尝试“拯救”断开连接的tcpsocket,重新连接然后重新发送?如果是这样,有没有人有一个简单的代码示例,因为我不知道从哪里开始:(我很自豪我设法在rails中获得了一个持久连接的客户端tcpsocket。然后服务器决定杀死客户端,一切都崩溃了;)编辑我已经使用此代码解决了一些问题-如果未连接,它将尝试重新连接,但如果服务器已关闭则不会处理这种情况(它将继续重试)。这是正确方法的开始吗?谢谢defself.write(data)begin@@my_connection.write(

  8. css - 检测到 Sass 更改但 style.css 仅在我保存时每 5 到 7 次被覆盖 - 2

    我在一台Windows764位机器上使用Sass和Ruby(最新版本),我正在我的家庭服务器上处理一个共享文件夹。(但是,我不得不承认问题本身也出现在服务器上,因为我试图安装Ruby并直接-watch服务器上的文件)。问题如下:如果我第一次保存,检测到变化,我的style.css被直接覆盖。之后,我总是需要保存多达7次才能覆盖style.css。每次都会检测到更改,但不会编译任何内容。这是一个屏幕:>>>Sassiswatchingforchanges.PressCtrl-Ctostop.overwritestyle.css>>>Changedetectedto:E:/Websites

  9. ruby-on-rails - 检测 Rails 是否正在运行站点 - 2

    我所在的团队负责管理公司面向公众的云平台。我们拥有大量运行面向互联网的VM的用户群。我想对我们的地址空间进行自动扫描,看看是否有人在运行Rails应用程序,这样我就可以通知他们升级他们的Rails版本,以避免本周出现的严重安全漏洞。我注意到在某些Apache部署中,有一个有用的PassengerHeader:X-Powered-By:PhusionPassenger(mod_rails/mod_rack)2.0.3然而,这并不可靠。我想知道是否有一种可靠的方法来检测在Web服务器后面运行的Rails,无论是使用响应header还是某种可以确定的GET/POST。谢谢!

  10. ruby - 正则表达式 - 这个用于素数检测的正则表达式的复杂性是多少? - 2

    这行ruby​​代码检测素数(太棒了!)。("1"*n)!~/^1?$|^(11+?)\1+$/#wherenisapositiveinteger详细信息在这篇博文中解释http://www.noulakaz.net/weblog/2007/03/18/a-regular-expression-to-check-for-prime-numbers/我很好奇它在BIG-O表示法中的表现。有人帮忙吗? 最佳答案 根据经验数据,它似乎是O(n2)。我对前10000个质数中的每100个运行Ruby代码。以下是结果:蓝点是记录的时间,橙色线是

随机推荐