yoloV3的目标检测_3.11

news/2024/4/29 16:36:01/文章来源:https://blog.csdn.net/m0_60657960/article/details/137017602

目标

  • 利用yolo模型进行目标检测的方法
  • 完成目标检测功能的实现

整个流程如下:

基于OPenCV中的DNN模块

  • 加载已训练好的yolov3模型及其权重参数
  • 将要处理的图像转换成输入到模型中的blobs
  • 利用模型对目标进行检测
  • 遍历检测结果
  • 应用非极大值抑制
  • 绘制最终检测结果,并存入到ndarray中,供目标追踪使用。

代码如下:

1.加载yolov3模型及其权重参数

# 1.加载可以识别物体的名称,将其存放在LABELS中,一共有80种,在这我们只使用car
labelsPath = "./yolo-coco/coco.names"
LABELS = open(labelsPath).read().strip().split("\n")# 设置随机数种子,生成多种不同的颜色,当一个画面中有多个目标时,使用不同颜色的框将其框起来
np.random.seed(42)
COLORS = np.random.randint(0, 255, size=(200, 3),dtype="uint8")# 加载已训练好的yolov3网络的权重和相应的配置数据
weightsPath = "./yolo-coco/yolov3.weights"
configPath = "./yolo-coco/yolov3.cfg"# 加载好数据之后,开始利用上述数据恢复yolo神经网络
net = cv2.dnn.readNetFromDarknet(configPath, weightsPath)
# 获取YOLO中每一网络层的名称:['conv_0', 'bn_0', 'relu_0', 'conv_1', 'bn_1', 'relu_1', 'conv_2', 'bn_2', 'relu_2'...]
ln = net.getLayerNames()
# 获取输出层在网络中的索引位置,并以列表的形式:['yolo_82', 'yolo_94', 'yolo_106']
ln = [ln[i[0] - 1] for i in net.getUnconnectedOutLayers()]

2.要处理的图像转换成输入到模型中的blobs

# 2. 读取图像
frame = cv2.imread("./images/car1.jpg")
# 视频的宽度和高度,即帧尺寸
(W, H) = (None, None)
if W is None or H is None:(H, W) = frame.shape[:2]# 根据输入图像构造blob,利用OPenCV进行深度网路的计算时,一般将图像转换为blob形式,对图片进行预处理,包括缩放,减均值,通道交换等
# 还可以设置尺寸,一般设置为在进行网络训练时的图像的大小
blob = cv2.dnn.blobFromImage(frame, 1 / 255.0, (416, 416), swapRB=True, crop=False)

3.利用模型对目标进行检测

# 3.将blob输入到前向网络中,并进行预测
net.setInput(blob)
start = time.time()
# yolo前馈计算,获取边界和相应的概率
# 输出layerOutsputs介绍:
# 是YOLO算法在图片中检测到的bbx的信息
# 由于YOLO v3有三个输出,也就是上面提到的['yolo_82', 'yolo_94', 'yolo_106']
# 因此layerOutsputs是一个长度为3的列表
# 其中,列表中每一个元素的维度是(num_detection, 85)
# num_detections表示该层输出检测到bbx的个数
# 85:因为该模型在COCO数据集上训练,[5:]表示类别概率;[0:4]表示bbx的位置信息;[5]表示置信度
layerOutputs = net.forward(ln)

4.遍历检测结果,获得检测框

# 下面对网络输出的bbx进行检查:
# 判定每一个bbx的置信度是否足够的高,以及执行NMS算法去除冗余的bbxboxes = []  # 用于存放识别物体的框的信息,包括框的左上角横坐标x和纵坐标y以及框的高h和宽w
confidences = []  # 表示识别目标是某种物体的可信度
classIDs = []  # 表示识别的目标归属于哪一类,['person', 'bicycle', 'car', 'motorbike'....]# 4. 遍历每一个输出层的输出
for output in layerOutputs:# 遍历某个输出层中的每一个目标for detection in output:scores = detection[5:]  # 当前目标属于某一类别的概率classID = np.argmax(scores)  # 目标的类别IDconfidence = scores[classID]  # 得到目标属于该类别的置信度# 只保留置信度大于0.3的边界框,若图片质量较差,可以将置信度调低一点if confidence > 0.3:# 将边界框的坐标还原至与原图片匹配,YOLO返回的是边界框的中心坐标以及边界框的宽度和高度box = detection[0:4] * np.array([W, H, W, H])(centerX, centerY, width, height) = box.astype("int") # 使用 astype("int") 对上述 array 进行强制类型转换,centerX:框的中心点横坐标, centerY:框的中心点纵坐标,width:框的宽度,height:框的高度x = int(centerX - (width / 2))  # 计算边界框的左上角的横坐标y = int(centerY - (height / 2))  # 计算边界框的左上角的纵坐标# 更新检测到的目标框,置信度和类别IDboxes.append([x, y, int(width), int(height)])  # 将边框的信息添加到列表boxesconfidences.append(float(confidence))  # 将识别出是某种物体的置信度添加到列表confidencesclassIDs.append(classID) # 将识别物体归属于哪一类的信息添加到列表classIDs

5.非极大值抑制

# 5. 非极大值抑制
idxs = cv2.dnn.NMSBoxes(boxes, confidences, 0.5, 0.3)

6.最终检测结果,绘制,并存入到ndarray中,供目标追踪使用

# 6. 获得最终的检测结果
dets = []  # 存放检测框的信息,包括左上角横坐标,纵坐标,右下角横坐标,纵坐标,以及检测到的物体的置信度,用于目标跟踪
if len(idxs) > 0:  # 存在检测框的话(即检测框个数大于0)for i in idxs.flatten():  #  循环检测出的每一个box# yolo模型可以识别很多目标,因为我们在这里只是识别车,所以只有目标是车的我们进行检测,其他的忽略if LABELS[classIDs[i]] == "car":(x, y) = (boxes[i][0], boxes[i][1])  # 得到检测框的左上角坐标(w, h) = (boxes[i][2], boxes[i][3])  # 得到检测框的宽和高cv2.rectangle(frame, (x, y), (x+w, y+h), (0,255,0), 2)  # 将方框绘制在画面上dets.append([x, y, x + w, y + h, confidences[i]])  # 将检测框的信息的放入dets中
# 设置数据类型,将整型数据转换为浮点数类型,且保留小数点后三位
np.set_printoptions(formatter={'float': lambda x: "{0:0.3f}".format(x)})
# 将检测框数据转换为ndarray,其数据类型为浮点型
dets = np.asarray(dets)plt.imshow(frame[:,:,::-1])

在视频中进行目标检测:

labelsPath = "./yolo-coco/coco.names"
LABELS = open(labelsPath).read().strip().split("\n")# 设置随机数种子,生成多种不同的颜色,当一个画面中有多个目标时,使用不同颜色的框将其框起来
np.random.seed(42)
COLORS = np.random.randint(0, 255, size=(200, 3),dtype="uint8")# 加载已训练好的yolov3网络的权重和相应的配置数据
weightsPath = "./yolo-coco/yolov3.weights"
configPath = "./yolo-coco/yolov3.cfg"# 加载好数据之后,开始利用上述数据恢复yolo神经网络
net = cv2.dnn.readNetFromDarknet(configPath, weightsPath)
# 获取YOLO中每一网络层的名称:['conv_0', 'bn_0', 'relu_0', 'conv_1', 'bn_1', 'relu_1', 'conv_2', 'bn_2', 'relu_2'...]
ln = net.getLayerNames()
# 获取输出层在网络中的索引位置,并以列表的形式:['yolo_82', 'yolo_94', 'yolo_106']
ln = [ln[i[0] - 1] for i in net.getUnconnectedOutLayers()]"""
视频处理类
"""# 初始化vediocapture类,参数指定打开的视频文件,也可以是摄像头
vs = cv2.VideoCapture('./input/test_1.mp4')
# 视频的宽度和高度,即帧尺寸
(W, H) = (None, None)
# 视频文件写对象
writer = Nonetry:# 确定获取视频帧数的方式prop = cv2.cv.CV_CAP_PROP_FRAME_COUNT if imutils.is_cv2() \else cv2.CAP_PROP_FRAME_COUNT# 获取视频的总帧数total = int(vs.get(prop))# 打印视频的帧数print("[INFO] {} total frames in video".format(total))
except:print("[INFO] could not determine # of frames in video")print("[INFO] no approx. completion time can be provided")total = -1# 循环读取视频中的每一帧画面
while True:# 读取帧:grabbed是bool,表示是否成功捕获帧,frame是捕获的帧(grabbed, frame) = vs.read()# 若未捕获帧,则退出循环if not grabbed:break# 若W和H为空,则将第一帧画面的大小赋值给他if W is None or H is None:(H, W) = frame.shape[:2]# 根据输入图像构造blob,利用OPenCV进行深度网路的计算时,一般将图像转换为blob形式,对图片进行预处理,包括缩放,减均值,通道交换等# 还可以设置尺寸,一般设置为在进行网络训练时的图像的大小blob = cv2.dnn.blobFromImage(frame, 1 / 255.0, (416, 416), swapRB=True, crop=False)# 将blob输入到前向网络中net.setInput(blob)start = time.time()# yolo前馈计算,获取边界和相应的概率layerOutputs = net.forward(ln)"""输出layerOutsputs介绍:是YOLO算法在图片中检测到的bbx的信息由于YOLO v3有三个输出,也就是上面提到的['yolo_82', 'yolo_94', 'yolo_106']因此layerOutsputs是一个长度为3的列表其中,列表中每一个元素的维度是(num_detection, 85)num_detections表示该层输出检测到bbx的个数85:因为该模型在COCO数据集上训练,[5:]表示类别概率;[0:4]表示bbx的位置信息;[5]表示置信度"""end = time.time()"""下面对网络输出的bbx进行检查:判定每一个bbx的置信度是否足够的高,以及执行NMS算法去除冗余的bbx"""boxes = []  # 用于存放识别物体的框的信息,包括框的左上角横坐标x和纵坐标y以及框的高h和宽wconfidences = []  # 表示识别目标是某种物体的可信度classIDs = []  # 表示识别的目标归属于哪一类,['person', 'bicycle', 'car', 'motorbike'....]# 遍历每一个输出层的输出for output in layerOutputs:# 遍历某个输出层中的每一个目标for detection in output:scores = detection[5:]  # 当前目标属于某一类别的概率"""# scores = detection[5:] ---> [0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.#                                 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.#                               0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.#                                 0. 0. 0. 0. 0. 0. 0. 0.]# scores的大小应该是1*80,因为在训练yolo模型时是80类目标"""classID = np.argmax(scores)  # 目标的类别IDconfidence = scores[classID]  # 得到目标属于该类别的置信度# 只保留置信度大于0.3的边界框,若图片质量较差,可以将置信度调低一点if confidence > 0.3:# 将边界框的坐标还原至与原图片匹配,YOLO返回的是边界框的中心坐标以及边界框的宽度和高度box = detection[0:4] * np.array([W, H, W, H])(centerX, centerY, width, height) = box.astype("int") # 使用 astype("int") 对上述 array 进行强制类型转换,centerX:框的中心点横坐标, centerY:框的中心点纵坐标,width:框的宽度,height:框的高度x = int(centerX - (width / 2))  # 计算边界框的左上角的横坐标y = int(centerY - (height / 2))  # 计算边界框的左上角的纵坐标# 更新检测到的目标框,置信度和类别IDboxes.append([x, y, int(width), int(height)])  # 将边框的信息添加到列表boxesconfidences.append(float(confidence))  # 将识别出是某种物体的置信度添加到列表confidencesclassIDs.append(classID) # 将识别物体归属于哪一类的信息添加到列表classIDs# 上一步中已经得到yolo的检测框,但其中会存在冗余的bbox,即一个目标对应多个检测框,所以使用NMS去除重复的检测框# 利用OpenCV内置的NMS DNN模块实现即可实现非最大值抑制 ,所需要的参数是边界 框、 置信度、以及置信度阈值和NMS阈值# 第一个参数是存放边界框的列表,第二个参数是存放置信度的列表,第三个参数是自己设置的置信度,第四个参数是关于threshold(阈值# 返回的idxs是一个一维数组,数组中的元素是保留下来的检测框boxes的索引位置idxs = cv2.dnn.NMSBoxes(boxes, confidences, 0.5, 0.3)dets = []  # 存放检测框的信息,包括左上角横坐标,纵坐标,右下角横坐标,纵坐标,以及检测到的物体的置信度,用于目标跟踪if len(idxs) > 0:  # 存在检测框的话(即检测框个数大于0)for i in idxs.flatten():  #  循环检测出的每一个box# yolo模型可以识别很多目标,因为我们在这里只是识别车,所以只有目标是车的我们进行检测,其他的忽略if LABELS[classIDs[i]] == "car":(x, y) = (boxes[i][0], boxes[i][1])  # 得到检测框的左上角坐标(w, h) = (boxes[i][2], boxes[i][3])  # 得到检测框的宽和高dets.append([x, y, x + w, y + h, confidences[i]])  # 将检测框的信息的放入dets中# 设置数据类型,将整型数据转换为浮点数类型,且保留小数点后三位np.set_printoptions(formatter={'float': lambda x: "{0:0.3f}".format(x)})# 将检测框数据转换为ndarray,其数据类型为浮点型dets = np.asarray(dets)

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

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

相关文章

数据库审计和安全

互联网、云计算、物联网等新技术的应用,数据安全面临前所未有的挑战!我国信息安全已从终端安全、网络安全,发展到数据安全建设阶段。数据安全的核心是对“数据”全方位的安全防护,其产品及解决方案直接涉及国家和企业的核心机密 核心数据库存…

win10微软拼音输入法 - bug - 在PATH变量为空的情况下,无法输入中文

文章目录 win10微软拼音输入法 - bug - 在PATH变量为空的情况下,无法输入中文概述笔记实验前提条件100%可以重现 - 无法使用win10拼音输入法输入中文替代的输入法软件备注END win10微软拼音输入法 - bug - 在PATH变量为空的情况下,无法输入中文 概述 在…

ES6学习之路:迭代器Iterator和生成器Generator

迭代器 一、知识背景 什么是迭代器 迭代器就是在一个数据集合中不断取出数据的过程迭代和遍历的区别 遍历是把所有数据都取出迭代器注重的是依次取出数据,它不会在意有多少数据,也不会保证能够取出多少或者能够把数据都取完。比如斐波那契额数列&#…

linux nginx配置ssl, 实现https+ip访问

mkdir sslZhengShu openssl req -newkey rsa:2048 -nodes -keyout ca.key -out ca.csr openssl x509 -req -days 365 -in ca.csr -signkey ca.key -out ca.crt openssl genrsa -out server.key 2048 openssl req -new -key server.key -out server.csr 和之前输入一样即可 …

Python基本运算

1.逻辑运算符 第四行会有黄色的下划线是因为这个不是系统推荐的写法,系统推荐的是第五行的链式比较; 2.短路求值 对于and而言,左边的语句是false,那么整体一定是false,右边的表达式就不会进行计算; 对于or而言&…

FTP 文件传输服务

FTP连接 控制连接:TCP 21,用于发送FTP命令信息 数据连接:TCP 20,用于上传、下载数据 数据连接的建立类型: 主动模式:服务端从 20 端口主动向客户端发起连接 被动模式:服务端在指定范围…

平台介绍-搭建赛事运营平台(3)

上文介绍了品牌隔离的基本原理,就是通过不同的前端和微服务来实现。但是确实很多功能是类似的,所以从编程角度还是有些管理手段的。 前端部分:前端部分没有什么特别手段,就是两个独立的项目工程,分别维护。相同的部分复…

神策数据参与制定首份 SDK 网络安全国家标准

国家市场监督管理总局、国家标准化管理委员会发布中华人民共和国国家标准公告(2023 年第 13 号),全国信息安全标准化技术委员会归口的 3 项国家标准正式发布。其中,首份 SDK 国家标准《信息安全技术 移动互联网应用程序&#xff0…

2核4G服务器租用价格表,阿里云/腾讯云/华为云/京东云

当前最新2核4G云服务器多少钱?165元一年,30元3个月。阿里云2核4G服务器165元一年,30元3个月、腾讯云2核4G5M服务器165元一年、京东云2核4G云主机126元1年,华为云也提供2核4G配置云服务器。阿腾云atengyun.com整理2024年最新云服务…

【NLP笔记】预训练+Prompt Tuning新范式之LLM时代(GPT3...)

文章目录 概述GPT3 【参考链接】 一张图总结大语言模型的技术分类、现状和开源情况 大语言模型LLM微调技术:Prompt Tuning A Survey of Large Language ModelsThe Practical Guides for Large Language ModelsGPT3:Language Models are Few-Shot Learner…

行存储与列存储:大数据存储方案的选择与优缺点分析

随着大数据时代的来临,数据的规模和复杂性呈指数级增长,传统的关系数据库已经不再适应这一巨大的存储量和计算要求。在大数据存储领域,行存储和列存储成为两种备受关注的存储方案。本文将探讨行存储和列存储的定义、优缺点,并结合…

python pytz是什么

pytz模块常用于时区的转换,常常配合datetime一起使用。我们知道datetime除了data方法生成的时间是没有时区概念,其他如time、datetime等都是有时区概念,即指定了tzinfo信息。 >>> import datetime >>> datetime.datetime.n…

骗子查询系统源码

源码简介 小权云黑管理系统 V1.0 功能如下: 1.添加骗子,查询骗子 2.可添加团队后台方便审核用 3.在线反馈留言系统 4.前台提交骗子,后台需要审核才能过 5.后台使用光年UI界面 6.新增导航列表,可给网站添加导航友链 7.可添加云黑类…

C语言运算符和表达式——增1和减1运算符

目录 增1和减1运算符 一元运算符 前缀增1/减1运算符 后缀增1/减1运算符 前缀与后缀对变量和表达式的影响 稍微复杂一点的例子 增1和减1运算符的优缺点 增1和减1运算符 增1运算符(Increment) *使变量的值增加1个单位 减1运算符(Decre…

量化交易软件开发定制的步骤

量化交易软件的定制开发是一个复杂而精细的过程,需要经过一系列步骤来确保最终交付的软件符合客户的需求并具有高度的可靠性和效率。以下是量化交易软件开发定制的主要步骤: 1. 需求分析与规划 在开始开发之前,首先需要与客户深入沟通&…

【使用matlab绘制音频数据的时域图和频域图】

使用matlab绘制音频数据的时域图和频域图 虚拟的数据集见附件 一、读取数据并设置参数 close all;clear all;colordef black 设置参数 filedir D:\Projects\MATLAB\data name 2024-03-28.txt % disp(filedir);Fs 8192; %采样率,即单位时间的样本个数&#xff…

电脑如何更新AMD独立显卡驱动?安装官方驱动的方法来了!

前言 有小伙伴在电脑上安装了独立显卡之后,总会用驱动人生或者驱动精灵等软件给独立显卡安装驱动。这种安装方法并不能说是错的,反正能用就行。 安装官方驱动的办法其实很简单,现在独立显卡一共就那么几家,最常见的显卡就是Nvidi…

Java基于微信小程序的校园订餐小程序的实现,附源码和数据库

博主介绍:✌Java徐师兄、7年大厂程序员经历。全网粉丝13w、csdn博客专家、掘金/华为云等平台优质作者、专注于Java技术领域和毕业项目实战✌ 🍅文末获取源码联系🍅 👇🏻 精彩专栏推荐订阅👇🏻 不…

今日早报 每日精选15条新闻简报 每天一分钟 知晓天下事 3月29日,星期五

每天一分钟,知晓天下事! 2024年3月29日 星期五 农历二月二十 1、 网络表演(直播与短视频)运营团体标准发布:应建立举报处置机制。 2、 商务部:中国决定终止对澳大利亚进口葡萄酒征收反倾销税和反补贴税。…

八大技术趋势案例(虚拟现实增强现实)

科技巨变,未来已来,八大技术趋势引领数字化时代。信息技术的迅猛发展,深刻改变了我们的生活、工作和生产方式。人工智能、物联网、云计算、大数据、虚拟现实、增强现实、区块链、量子计算等新兴技术在各行各业得到广泛应用,为各个领域带来了新的活力和变革。 为了更好地了解…