一篇文章简单介绍YOLO v1到v8的演变

大家好,YOLO(You Only Look Once)是一种流行的目标检测库,它的第一个版本在2015年发布。YOLO工作速度很快,提供了良好的结果,而且预训练模型是公开可用的。该模型迅速变得流行,该项目至今仍在积极改进,这使我们有机会看到数据科学工具和库如何在多年间演变。本文将测试不同版本的YOLO,从最初的V1到最新的V8。

为了进行进一步的测试,将使用这张图片:

YOLO V1到V3

关于YOLO的第一篇论文,“You Only Look Once: Unified, Real-Time Object Detection”,于2015年发布。YOLO v1仍然可以下载,正如原始论文的作者之一Redmon所写的,他保留了这个版本“出于历史目的”。该模型以两个文件的形式分发,配置文件“yolo.cfg”包含有关神经网络模型的详细信息:

[net]batch=1height=448width=448channels=3momentum=0.9decay=0.0005...
[convolutional]batch_normalize=1filters=64size=7stride=2pad=1activation=leaky

第二个文件“yolov1.weights”,顾名思义,包含了预训练模型的权重。

这种格式不是来自PyTorch或Keras,该模型是使用Darknet创建的,Darknet是一种用C编写的开源神经网络框架。这个项目仍然可以在GitHub上找到,但它看起来已经被抛弃。在撰写本文时,有164个拉取请求和1794个未解决的问题,最后一次提交是在2018年,之后只有README.md文件有所更改。

原始的Darknet项目被抛弃了,不过readNetFromDarknet方法仍然在OpenCV中可用,甚至在最新的OpenCV版本中也存在。因此可以尝试使用Python环境加载原始的YOLO v1模型:

import cv2
model = cv2.dnn.readNetFromDarknet("yolo.cfg", "yolov1.weights")

运行得到如下错误:

darknet_io.cpp:902: error: 
(-212:Parsing error) Unknown layer type: local in function 'ReadDarknetFromCfgStream'

原来“yolo.cfg”中有一个名为“local”的层,这是OpenCV不支持的。YOLO v2配置中不再有这个层,可以成功在OpenCV中加载该模型:

import cv2
model = cv2.dnn.readNetFromDarknet("yolov2.cfg", "yolov2.weights")

使用模型并不像期望的那样简单,首先需要找到模型的输出层:

ln = model.getLayerNames()
output_layers = [ln[i - 1] for i in model.getUnconnectedOutLayers()]

然后需要加载图像并将其转换为模型能够理解的二进制格式:​​​​​​​

img = cv2.imread('test.jpg')
H, W = img.shape[:2]

blob = cv2.dnn.blobFromImage(img, 1/255.0, (608, 608), swapRB=True, crop=False)

最后运行正向传播,使用“forward”方法将运行计算并返回所请求的层输出:​​​​​​​

model.setInput(blob)
outputs = model.forward(output_layers)

执行正向传播很简单,但解析输出可能有点棘手。该模型产生85维特征向量作为输出,其中前4个数字表示对象矩形,第5个数字是对象存在的概率,最后80个数字包含模型训练的80个类别的概率信息。有了这些信息,可以在原始图像上绘制标签:

threshold = 0.5
boxes, confidences, class_ids = [], [], []

# Get all boxes and labels
for output in outputs:
    for detection in output:
        scores = detection[5:]
        class_id = np.argmax(scores)
        confidence = scores[class_id]
        if confidence > threshold:
            center_x, center_y = int(detection[0] * W), int(detection[1] * H)
            width, height = int(detection[2] * W), int(detection[3] * H)
            left = center_x - width//2
            top = center_y - height//2
            boxes.append([left, top, width, height])
            class_ids.append(class_id)
            confidences.append(float(confidence))

# Combine boxes together using non-maximum suppression
indices = cv2.dnn.NMSBoxes(boxes, confidences, 0.5, 0.4)

# All COCO classes
classes = "person;bicycle;car;motorbike;aeroplane;bus;train;truck;boat;traffic light;fire hydrant;stop sign;parking meter;bench;bird;" \
          "cat;dog;horse;sheep;cow;elephant;bear;zebra;giraffe;backpack;umbrella;handbag;tie;suitcase;frisbee;skis;snowboard;sports ball;kite;" \
          "baseball bat;baseball glove;skateboard;surfboard;tennis racket;bottle;wine glass;cup;fork;knife;spoon;bowl;banana;apple;sandwich;" \
          "orange;broccoli;carrot;hot dog;pizza;donut;cake;chair;sofa;pottedplant;bed;diningtable;toilet;tvmonitor;laptop;mouse;remote;keyboard;" \
          "cell phone;microwave;oven;toaster;sink;refrigerator;book;clock;vase;scissors;teddy bear;hair dryer;toothbrush".split(";")

# Draw rectangles on image
colors = np.random.randint(0, 255, size=(len(classes), 3), dtype='uint8')
for i in indices.flatten():
    x, y, w, h = boxes[i]
    color = [int(c) for c in colors[class_ids[i]]]
    cv2.rectangle(img, (x, y), (x + w, y + h), color, 2)
    text = f"{classes[class_ids[i]]}: {confidences[i]:.2f}"
    cv2.putText(img, text, (x + 2, y - 6), cv2.FONT_HERSHEY_COMPLEX, 0.5, color, 1)

# Show
cv2.imshow('window', img)
cv2.waitKey(0)
cv2.destroyAllWindows()

这里使用`np.argmax`来找到具有最大概率的类别ID。YOLO模型是使用COCO(Common Objects in Context,知识共享署名4.0许可)数据集进行训练的,为了简化起见,直接将所有80个标签名称放入了代码中,还使用了OpenCV的`NMSBoxes`方法将嵌套的矩形组合在一起。最终结果如下:

 下一个版本YOLO v3,在两年后的2018年发布,也可以使用相同的代码运行它(权重和配置文件可以在线获取)。正如作者在论文中所写的,新模型更精确,可以轻松验证这一点:

YOLO V5到V7

使用`readNetFromDarknet`方法加载的模型有效,但所需的代码相当“低级”且繁琐。OpenCV的开发者决定让生活变得更轻松,在2019年的4.1.2版本中添加了一个新的`DetectionModel`类。可以通过以下方式加载YOLO模型,总体逻辑仍然相同,但所需的代码量要小得多。该模型直接在一个方法调用中返回类别ID、置信度值和矩形框:

import cv2

model = cv2.dnn_DetectionModel("yolov7.cfg", "yolov7.weights")
model.setInputParams(size=(640, 640), scale=1/255, mean=(127.5, 127.5, 127.5), swapRB=True)

class_ids, confidences, boxes = model.detect(img, confThreshold=0.5)

# Combine boxes together using non-maximum suppression
indices = cv2.dnn.NMSBoxes(boxes, confidences, 0.5, 0.4)

# All COCO classes
classes = "person;bicycle;car;motorbike;aeroplane;bus;train;truck;boat;traffic light;fire hydrant;stop sign;parking meter;bench;bird;" \
          "cat;dog;horse;sheep;cow;elephant;bear;zebra;giraffe;backpack;umbrella;handbag;tie;suitcase;frisbee;skis;snowboard;sports ball;kite;" \
          "baseball bat;baseball glove;skateboard;surfboard;tennis racket;bottle;wine glass;cup;fork;knife;spoon;bowl;banana;apple;sandwich;" \
          "orange;broccoli;carrot;hot dog;pizza;donut;cake;chair;sofa;pottedplant;bed;diningtable;toilet;tvmonitor;laptop;mouse;remote;keyboard;" \
          "cell phone;microwave;oven;toaster;sink;refrigerator;book;clock;vase;scissors;teddy bear;hair dryer;toothbrush".split(";")

# Draw rectangles on image
colors = np.random.randint(0, 255, size=(len(classes), 3), dtype='uint8')
for i in indices.flatten():
    x, y, w, h = boxes[i]
    color = [int(c) for c in colors[class_ids[i]]]
    cv2.rectangle(img, (x, y), (x + w, y + h), color, 2)
    text = f"{classes[class_ids[i]]}: {confidences[i]:.2f}"
    cv2.putText(img, text, (x, y - 5), cv2.FONT_HERSHEY_SIMPLEX, 0.5, color, 1)

# Show
cv2.imshow('window', img)
cv2.waitKey(0)
cv2.destroyAllWindows()

正如所看到的,不再需要从模型输出中提取框和置信度值的所有低级代码。运行YOLO v7的结果,总体上是相同的:

图片

YOLO V8

第8版于2023年发布,为了比较结果,看一下现在运行YOLO所需的代码:

from ultralytics import YOLO
import supervision as sv


model = YOLO('yolov8m.pt')
results = model.predict(source=img, save=False, save_txt=False, verbose=False)
detections = sv.Detections.from_yolov8(results[0])

# Create list of labels
labels = []
for ind, class_id in enumerate(detections.class_id):
    labels.append(f"{model.model.names[class_id]}: {detections.confidence[ind]:.2f}")

# Draw rectangles on image
box_annotator = sv.BoxAnnotator(thickness=2, text_thickness=1, text_scale=0.4)
box_annotator.annotate(scene=img, detections=detections, labels=labels)

# Show
cv2.imshow('window', img)
cv2.waitKey(0)
cv2.destroyAllWindows()

正如所看到的,代码变得更加紧凑,不需要关心数据集标签名称(模型提供了“names”属性)或如何在图像上绘制矩形和标签,结果非常准确:

本文测试了从2016年到2023年制作的几乎所有YOLO模型,多年来流行的数据科学工具和库演变是很有趣的,从低级代码到高级方法的趋势,这些方法可以做任何事情。OpenCV“本地”能够运行深度学习模型是很重要的,这使得可以在不仅在PyTorch或Keras等大型框架中使用神经网络模型,而且还可以在纯Python甚至是C ++应用程序中使用。并非每个应用程序都在拥有几乎无限资源的云中运行,物联网市场正在增长,这对在低功耗设备上运行神经网络(如机器人、监控摄像头或智能门铃)尤其重要。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/445710.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

ai学习前瞻-python环境搭建

python环境搭建 Python环境搭建1. python的安装环境2. MiniConda安装3. pycharm安装4. Jupyter 工具安装5. conda搭建虚拟环境6. 安装python模块pip安装conda安装 7. 关联虚拟环境运行项目 Python环境搭建 1. python的安装环境 ​ python环境安装有4中方式。 从上图可以了解…

python之数组,链表,栈,队列

1.数组 优点: 索引操作速度快:通过索引可以直接访问元素,因此索引操作的时间复杂度是 $O(1)$,即常数级 缺点: 插入、删除元素慢: 如果需要在中间或开始位置插入或删除元素,可能需要移动大量…

漫漫数学之旅036

文章目录 经典格言数学习题古今评注名人小传 - 爱因斯坦 经典格言 纯数学在其领域内是逻辑思想的诗歌。——阿尔伯特爱因斯坦 “纯数学在其领域内是逻辑思想的诗歌”这句话体现了爱因斯坦对数学的深刻理解和热爱。在这句话中,爱因斯坦将纯数学比作诗歌,…

mmdetection如何计算准确率、召回率、F1值

1、训练 python tools/train.py configs/fcos/fcosrdweed3.py 2、测试 这一步要加–outresult.pkl,才能计算准确率和召回率 python tools/test.py configs/fcos/fcosrddweed3.py work_dirs/fcosrddweed3/epoch_300.pth --outresultfcos.pkl3、计算准确率和召回率…

三维GIS的业务导向

的确,目前三维GIS以做特效居多,酷炫、亮眼,从二维转到三维,第一眼就给人眼前一亮的感觉,就凭这一项,很多客户就会买单,GIS的客户以政府、科研院所、特种行业为主,买过一次单后&#…

riscv简单常用汇编指令xv6

文章目录 前言entry.Smretasm volatileread csrwrite csrriscv常见csr寄存器 ecall, 系统调用指令cpu执行异常处理指令的三种事件 异常处理相关寄存器用户态trapsret指令页表切换操作用户态系统调用过程总结 内核态trap缺页异常 中断与设备驱动Locking调度文件系统操作系统拥有…

Docker完整版(一)

Docker完整版(一) 一、Docker概述1.1、Docker简介1.2、Docker的用途1.3、容器与虚拟机的区别1.4、Docker系统架构1.5、Docker仓库 二、Docker引擎2.1、Docker引擎架构2.2、Docker引擎分类2.3、Docker引擎的安装2.4、Docker镜像加速器 三、Docker镜像3.1、…

Android 完整SDK项目中添加对应的JNI与底层通信

安卓应用发消息给底层 近日需要写一个安卓app和底层发消息,这就涉及到java如何到c层的一个逻辑,app已经写好,就差发个消息了。至于如何对接底层,得和写底层的人进一步沟通,本文笔者只写从java层通信到cpp,…

视频远程监控平台EasyCVR集成后播放只有一帧画面的原因排查与解决

智慧安防视频监控平台EasyCVR能在复杂的网络环境中(专网、局域网、广域网、VPN、公网等)将前端海量的设备进行统一集中接入与视频汇聚管理,平台可支持的接入协议包括:国标GB28181、RTSP/Onvif、RTMP,以及厂家的私有协议…

C++ 字符串OJ

目录 1、14. 最长公共前缀 2、 5. 最长回文子串 3、 67. 二进制求和 4、43. 字符串相乘 1、14. 最长公共前缀 思路一:两两字符串进行比较,每次比较过程相同,可以添加一个函数辅助比较,查找最长公共前缀。 class Solution { pu…

Vue.set:Vue中的数据绑定利器

🤍 前端开发工程师、技术日更博主、已过CET6 🍨 阿珊和她的猫_CSDN博客专家、23年度博客之星前端领域TOP1 🕠 牛客高级专题作者、打造专栏《前端面试必备》 、《2024面试高频手撕题》 🍚 蓝桥云课签约作者、上架课程《Vue.js 和 E…

【JAVA/Web】数组转对象

一. 需求 数组转对象 数组结构 List:[{id:1,code:phone,value:10101001},{id:2,code:name,value:admin},{id:3,code:address,value:XXXXXX} ]二. 数组转对象(键值对映射关系) 对象结构 object:{phone:10101001,name:admin,address:XXXXXX }2.1 Java…

Java Socket:飞鸽传书的网络套接字

套接字(Socket)是一个抽象层,应用程序可以通过它发送或接收数据;就像操作文件那样可以打开、读写和关闭。套接字允许应用程序将 I/O 应用于网络中,并与其他应用程序进行通信。网络套接字是 IP 地址与端口的组合。 01、…

VUE3 使用axios网络请求

1.新建工程 参考,VUE3 环境搭建:https://blog.csdn.net/LQ_001/article/details/136293795,运行命令 vue create vue-demo 2.引入axios 不管何种引用,都要在工程中安装 axios 包。安装命令:npm install --save axio…

linux paddle For C++环境搭建

paddle介绍 Paddle是类似tesseract的文字识别ocr。因为tesseract-ocr的中文识别效果不好。因此才准备安装Paddle。Paddle最方便的安装方式的使用Python的包管理安装。pip3 install paddlepaddle。但我使用了一下感觉还是用C更加方便,QT OpenCV Paddle应当还不错。…

Go语言必知必会100问题-19 浮点数溢出问题

问题呈现 在Go语言中,有两种浮点数类型(虚数除外):float32和float64. 浮点数是用来解决整数不能表示小数的问题。我们需要知道浮点数算术运算是实数算术运算的近似,下面通过例子说明浮点数运算采用近似值的影响以及如…

⭐每天一道leetcode:83.删除排序链表中的重复元素(简单;链表遍历、删除经典题目)

⭐今日份题目 给定一个已排序的链表的头 head , 删除所有重复的元素,使每个元素只出现一次 。返回 已排序的链表 。 示例1 输入:head [1,1,2] 输出:[1,2] 示例2 输入:head [1,1,2,3,3] 输出:[1,2,3] …

【R语言爬虫实战】抓取省市级城市常务会议内容

🍉CSDN小墨&晓末:https://blog.csdn.net/jd1813346972 个人介绍: 研一|统计学|干货分享          擅长Python、Matlab、R等主流编程软件          累计十余项国家级比赛奖项,参与研究经费10w、40w级横向 文…

enumerate函数的用法

enumerate() 函数是 Python 内置函数之一,用于同时返回可迭代对象的索引和对应的值。 它的语法结构如下: enumerate(iterable, start0) iterable: 表示一个可迭代的对象,如列表、元组、字符串等。start: 可选参数,表示索引起始…

02hadoop伪分布式搭建

3. 环境安装 3.1 安装方式 单机模式 只能启动MapReduce 伪分布式 能启动HDFS、MapReduce 和 YARN的大部分功能 完全分布式 能启动Hadoop的所有功能 3.2 安装JDK 3.2.1 JDK安装步骤 下载JDK安装包(下载Linux系统的 .tar.gz 的安装包) https://www…