OpenCV实例(九)基于深度学习的运动目标检测(三)YOLOv3识别物体

基于深度学习的运动目标检测(三)YOLOv3识别物体

  • 1.基于YOLOv3识别物体
  • 2.让不同类别物体的捕捉框颜色不同
  • 3.不用Matplotlib实现目标检测

目标检测,粗略地说就是输入图片/视频,经过处理后得到目标的位置信息(比如左上角和右下角的坐标)、目标的预测类别、目标的预测置信度。前面我们阐述了不少理论知识,现在需要动手实战了。对于初学者来说,自己实现YOLO算法不太现实,幸运的是OpenCV的DNN(Deep Neural Network)模块封装了Darknet框架(封装了YOLO算法)。使用OpenCV能更方便地直接运行已训练的深度学习模型,本次采用在目标检测中最强劲的YOLOv3,基本步骤是先让OpenCV加载预训练YOLOv3模型,然后进行各种检测,比如图片识别、打开计算机自带摄像头进行物体检测等。

为了加载预训练YOLOv3模型,需要准备3个文件(在工程目录下):yolov3.cfg、yolov3.weights和coco.names。其中,yolov3.cfg为yolov3网络配置文件,yolov3.weights为权重文件,coco.names为标签文件。

1.基于YOLOv3识别物体

使用OpenCV dnn模块加载YOLO模型,代码如下:

     net = cv2.dnn.readNet("yolov3.weights", "yolov3.cfg")

从coco.names导入类别并存储为列表,代码如下:

classes = []
with open("coco.names","r")as f:classes = [line.strip() for line inf.readlines()]
print(classes)

完整代码:

import cv2
import numpy as npnet = cv2.dnn.readNet("yolov3.weights", "yolov3.cfg")
classes = []
with open("coco.names", "r") as f:   #这里使用的是coco所训练的模型yolov3.cfg所以这里对应为coco.namesclasses = [line.strip() for line in f.readlines()]print(classes)layer_names = net.getLayerNames()
print(layer_names)output_layers = [layer_names[i[0] - 1] for i in net.getUnconnectedOutLayers()]
print(output_layers)img = cv2.imread("demo1.jpg")# 获取图像尺寸与通道值
height, width, channels = img.shape
print('The image height is:',height)
print('The image width is:',width)
print('The image channels is:',channels)blob = cv2.dnn.blobFromImage(img, 1.0 / 255.0, (416, 416), (0, 0, 0), True, crop=False)from matplotlib import pyplot as pltfig = plt.gcf()
fig.set_size_inches(20, 10)num = 0
for b in blob:for img_blob in b:img_blob=cv2.cvtColor(img_blob, cv2.COLOR_BGR2RGB)num += 1ax = plt.subplot(3/3, 3, num)ax.imshow(img_blob)title = 'blob_image:{}'.format(num)ax.set_title(title, fontsize=20)net.setInput(blob)
outs = net.forward(output_layers)for i in range(len(outs)):print('The {} layer out shape is:'.format(i), outs[i].shape)class_ids = []
confidences = []
boxes = []i = 0
for out in outs:for detection in out:a = sum(detection[5:])if a > 0:print(detection[5:])i += 1if i == 2:breaki = 0
for out in outs:for detection in out:print('中心像素坐标 X 对原图宽比值:',detection[0])print('中心像素坐标 Y 对原图高比值:',detection[1])print('边界框的宽度 W 对原图宽比值:',detection[2])print('边界框的高度 H 对原图高比值:',detection[3])print('此边界框置信度:',detection[4])breakbreakplt_img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)fig = plt.gcf()
fig.set_size_inches(20, 10)plt.imshow(plt_img)# jupyter 对每次运行结果会保留,再次运行列表创建
class_ids = []
confidences = []
boxes = []i = 0for out in outs:for detection in out:scores = detection[5:]class_id = np.argmax(scores)confidence = scores[class_id]if confidence > 0.5:center_x = int(detection[0] * width)center_y = int(detection[1] * height)w = int(detection[2] * width)        h = int(detection[3] * height)x = int(center_x - w / 2)y = int(center_y - h / 2)boxes.append([x, y, w, h])confidences.append(float(confidence))class_ids.append(class_id)label = classes[class_id]plt.gca().add_patch(plt.Rectangle((x, y), w,h, fill=False,edgecolor=(0, 1, 1), linewidth=2))plt.text(x, y - 10, label, color = (1, 0, 0), fontsize=20)print('object {} :'.format(i), label)i += 1plt.show()plt_img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)fig = plt.gcf()
fig.set_size_inches(30, 20)ax_img = plt.subplot(1, 2, 1)ax_img.imshow(plt_img)# jupyter 对每次运行结果会保留,再次运行一次
class_ids = []
confidences = []
boxes = []i = 0for out in outs:for detection in out:scores = detection[5:]class_id = np.argmax(scores)confidence = scores[class_id]if confidence > 0.5:center_x = int(detection[0] * width)center_y = int(detection[1] * height)w = int(detection[2] * width)        h = int(detection[3] * height)x = int(center_x - w / 2)y = int(center_y - h / 2)boxes.append([x, y, w, h])confidences.append(float(confidence))class_ids.append(class_id)label = classes[class_id]plt.gca().add_patch(plt.Rectangle((x, y), w,h, fill=False,edgecolor=(0, 1, 1), linewidth=2))plt.text(x, y - 10, label, color = (1, 0, 0), fontsize=20)print('object {} :'.format(i), label + ' '*(10 - len(label)), 'confidence :{}'.format(confidence))i += 1print(confidences)
indexes = cv2.dnn.NMSBoxes(boxes, confidences, 0.5, 0.4)
print(indexes, end='')ax_img = plt.subplot(1, 2, 2)
ax_img.imshow(plt_img)
for j in range(len(boxes)):if j in indexes:x, y, w, h = boxes[j]label = classes[class_ids[j]]plt.gca().add_patch(plt.Rectangle((x, y), w,h, fill=False,edgecolor=(0, 1, 1), linewidth=2))plt.text(x, y - 10, label, color = (1, 0, 0), fontsize=20)plt.show()

获得输出层的代码:

     layer_names = net.getLayerNames()print(layer_names)output_layers = [layer_names[i[0] - 1] for i in net.getUnconnectedOutLayers()]print(output_layers)

其中,getLayerNames函数获取网络各层名称;getUnconnectedOutLayers函数返回具有未连接输出的图层索引。

添加处理图像并获取blob的代码:

    img = cv2.imread("demo1.jpg")# 获取图像尺寸与通道值height, width, channels = img.shapeprint('The image height is:',height)print('The image width is:',width)print('The image channels is:',channels)blob = cv2.dnn.blobFromImage(img, 1.0 / 255.0, (416, 416), (0, 0, 0), True,
crop=False)

此时运行程序,打印的高度、宽度和通道数如下:

     The image height is: 2250The image width is: 4000The image channels is: 3

(添加Matplotlib可视化blob下的图像,代码如下:

     from matplotlib import pyplot as plt

OpenCV采用的是BGR,Matplotlib采用的是RGB,需要使用cv2.COLOR_BGR2RGB将BGR转换为RGB。

利用setInput函数将blob输入网络,利用forward函数输入网络输出层的名字来计算网络输出。本次计算中output_layers包含3个输出层的列表,所以outs的值也是一个包含3个矩阵(array)的列表(list)。
这个循环会输出以下内容:

     The 0 layer out shape is: (507, 85)The 1 layer out shape is: (2028, 85)The 2 layer out shape is: (8112, 85)

然后进行识别与标签处理,创建记录数据列表。
其中,class_ids记录类别名;confidences记录算法检测物体概率;boxes记录框的坐标。YOLOv3对于一个416×416的输入图像,在每个尺度的特征图的每个网格中设置3个先验框,总共有13×13×3 + 26×26×3 + 52×52×3 = 10647个预测。每一个预测是一个85(4+1+80)维向量,这个85维向量包含边框坐标(4个数值)、边框置信度(1个数值)、对象类别的概率(对于COCO数据集,有80种对象),所以我们通过detection[5:]获取detection的后80个数据(类似独热码),获取其最大值索引对应的coco.names类别。

在这里插入图片描述
在检测中发现出现了双框(或者多框)效果。OpenCV dnn模块自带了NMSBoxes()函数,可以使用NMS算法解决多框问题。NMS的目的是在邻域内保留同一检测目标置信度最大的框,在下方输出中可以发现对于邻域相同的目标检测只保留了confidence值最大的box索引,例如object 0 : tvmonitor与object 3 : tvmonitor概率分别为0.9334805607795715与0.9716598987579346,显然保留了object 3 : tvmonitor,在索引indexes中没有[0]元素,其余推断类似。

在这里插入图片描述

2.让不同类别物体的捕捉框颜色不同

代码:

import cv2
import numpy as np
from matplotlib import pyplot as plt# Load Yolo
net = cv2.dnn.readNet("yolov3.weights", "yolov3.cfg")
classes = []
with open("coco.names", "r") as f:classes = [line.strip() for line in f.readlines()]layer_names = net.getLayerNames()
output_layers = [layer_names[i[0] - 1] for i in net.getUnconnectedOutLayers()]colors = np.random.uniform(0, 255, size=(len(classes), 3)) / 255# Loading image
img = cv2.imread("demo1.jpg")
# img = cv2.resize(img, None, fx=0.4, fy=0.4)
height, width, channels = img.shape# Detecting objects
blob = cv2.dnn.blobFromImage(img, 1.0 / 255.0, (416, 416), (0, 0, 0), True, crop=False)net.setInput(blob)
outs = net.forward(output_layers)# Showing informations on the screen
class_ids = []
confidences = []
boxes = []fig = plt.gcf()
fig.set_size_inches(20, 10)
plt_img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
plt.imshow(plt_img)for out in outs:for detection in out:scores = detection[5:]class_id = np.argmax(scores)confidence = scores[class_id]if confidence > 0.5:# Object detectedcenter_x = int(detection[0] * width)center_y = int(detection[1] * height)w = int(detection[2] * width)h = int(detection[3] * height)# Rectangle coordinatesx = int(center_x - w / 2)y = int(center_y - h / 2)boxes.append([x, y, w, h])confidences.append(float(confidence))class_ids.append(class_id)indexes = cv2.dnn.NMSBoxes(boxes, confidences, 0.5, 0.4)for i in range(len(boxes)):if i in indexes:x, y, w, h = boxes[i]label = str(classes[class_ids[i]])color = colors[i]plt.gca().add_patch(plt.Rectangle((x, y), w,h, fill=False,edgecolor=color, linewidth=2))plt.text(x, y - 10, label, color = color, fontsize=20)plt.show()

运行结果:

在这里插入图片描述

3.不用Matplotlib实现目标检测

代码:

import cv2
import numpy as np# Load Yolo
net = cv2.dnn.readNet("yolov3.weights", "yolov3.cfg")
classes = []
with open("coco.names", "r") as f:classes = [line.strip() for line in f.readlines()]
layer_names = net.getLayerNames()
output_layers = [layer_names[i - 1] for i in net.getUnconnectedOutLayers()]
colors = np.random.uniform(0, 255, size=(len(classes), 3))# Loading image
img = cv2.imread("demo1.jpg")
height, width, channels = img.shape# Detecting objects
blob = cv2.dnn.blobFromImage(img, 0.00392, (416, 416), (0, 0, 0), True, crop=False)net.setInput(blob)
outs = net.forward(output_layers)# Showing informations on the screen
class_ids = []
confidences = []
boxes = []
for out in outs:for detection in out:scores = detection[5:]class_id = np.argmax(scores)confidence = scores[class_id]if confidence > 0.5:# Object detectedcenter_x = int(detection[0] * width)center_y = int(detection[1] * height)w = int(detection[2] * width)h = int(detection[3] * height)# Rectangle coordinatesx = int(center_x - w / 2)y = int(center_y - h / 2)boxes.append([x, y, w, h])confidences.append(float(confidence))class_ids.append(class_id)indexes = cv2.dnn.NMSBoxes(boxes, confidences, 0.5, 0.4)font = cv2.FONT_HERSHEY_SIMPLEX
for i in range(len(boxes)):if i in indexes:x, y, w, h = boxes[i]label = str(classes[class_ids[i]])color = colors[i]cv2.rectangle(img, (x, y), (x + w, y + h), color, 3)cv2.putText(img, label, (x, y - 20), font, 2, color, 3)cv2.namedWindow("Image",0)
cv2.resizeWindow("Image", 1600, 900)
cv2.imshow("Image", img)
cv2.waitKey(0)
cv2.destroyAllWindows()

输出结果:

在这里插入图片描述

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

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

相关文章

Android岗位技能实训室建设方案

一 、系统概述 Android岗位技能作为新一代信息技术的重点和促进信息消费的核心产业,已成为我国转变信息服务业的发展新热点:成为信息通信领域发展最快、市场潜力最大的业务领域。互联网尤其是移动互联网,以其巨大的信息交换能力和快速渗透能力…

leetcode做题笔记92. 反转链表 II

给你单链表的头指针 head 和两个整数 left 和 right &#xff0c;其中 left < right 。请你反转从位置 left 到位置 right 的链表节点&#xff0c;返回 反转后的链表 。 示例 1&#xff1a; 思路一&#xff1a;头插法 struct ListNode *reverseBetween(struct ListNode *h…

河北人事档案管理系统

河北人事档案管理系统是一个集数字化管理、高效服务、安全可靠于一体的人事档案管理平台&#xff0c;可以集中管理机关事业单位人事档案、农村党员档案、参保职工档案、流动人才档案等&#xff0c;并实现高效、便捷的查阅和调阅服务。 河北人事档案管理系统的建设主要是为了更好…

成集云 | 电子签署集成腾讯云企业网盘 | 解决方案

源系统成集云目标系统 方案介绍 电子签署是通过电子方式完成合同、文件或其他文件的签署过程。相较于传统的纸质签署&#xff0c;电子签署具有更高效、更便捷、更安全的优势。 在电子签署过程中&#xff0c;使用电子签名技术来验证签署者的身份并确保签署文件的完整性。电子…

华为OD七日集训第1期 - 按算法分类,由易到难,循序渐进,玩转OD(文末送书)

目录 一、适合人群二、本期训练时间三、如何参加四、7日集训第一期 ~ 华为OD初体验五、精心挑选21道高频100分经典题目&#xff0c;作为入门。第1天、逻辑分析第2天、字符串处理第3天、数据结构第4天、双指针第5天、递归回溯第6天、二分查找第7天、贪心算法 && 二叉树 …

dirsearch目录扫描工具的使用

文章目录 工具下载及环境准备查看帮助信息进行目录扫描 官方介绍 &#xff1a;An advanced command-line tool designed to brute force directories and files in webservers, AKA web path scanner 一个高级命令行工具&#xff0c;用于暴力破解网络服务器中的目录和文件&…

C++中List的实现

前言 数据结构中&#xff0c;我们了解到了链表&#xff0c;但是我们使用时需要自己去实现链表才能用&#xff0c;但是C出现了list将这一切皆变为现。list可以看作是一个带头双向循环的链表结构&#xff0c;并且可以在任意的正确范围内进行增删查改数据的容器。list容器一样也是…

【JVM】运行时数据区——自问自答

Q:Java 运行时数据区解构&#xff0c;哪些数据线程独占&#xff0c;哪些是线程共享&#xff1f;每个区域会产生GC和异常吗&#xff1f; 运行时数据区&#xff1a; 1、PC寄存器 2、堆区 3、JVM栈 4、Native栈 5、方法区 其中&#xff0c;PC寄存器、Native栈、JVM栈是线程独占的…

如何在pycharm中指定GPU

如何在pycharm中指定GPU 作者:安静到无声 个人主页 目录 如何在pycharm中指定GPU打开编辑配置点击环境变量添加GPU配置信息推荐专栏在Pycharm运行程序的时候,有时候需要指定GPU,我们可以采用以下方式进行设置: 打开编辑配置 点击环境变量 添加GPU配置信息 添加名称:CU…

geacon_pro配合catcs4.5上线Mac、Linux

我的个人博客: xzajyjs.cn 一些链接 Try师傅的catcs4.5项目: https://github.com/TryGOTry/CobaltStrike_Cat_4.5&#xff0c;最新版解压密码见&#xff1a;https://www.nctry.com/2708.html geacon_pro: https://github.com/testxxxzzz/geacon_pro BeaconTool.jar: https:/…

【LLM评估篇】Ceval | rouge | MMLU等指标

note 一些大模型的评估模型&#xff1a;多轮&#xff1a;MTBench关注评估&#xff1a;agent bench长文本评估&#xff1a;longbench&#xff0c;longeval工具调用评估&#xff1a;toolbench安全评估&#xff1a;cvalue&#xff0c;safetyprompt等 文章目录 note常见评测benchm…

ubuntu20搭建环境使用的一下指令

1.更新源 sudo vim etc/apt/sources.listdeb http://mirrors.aliyun.com/ubuntu/ xenial main deb-src http://mirrors.aliyun.com/ubuntu/ xenial maindeb http://mirrors.aliyun.com/ubuntu/ xenial-updates main deb-src http://mirrors.aliyun.com/ubuntu/ xenial-updates…

Redis实现共享Session

Redis实现共享Session 分布式系统中&#xff0c;sessiong共享有很多的解决方案&#xff0c;其中托管到缓存中应该是最常用的方案之一。 1、引入依赖 <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM…

openGauss学习笔记-44 openGauss 高级数据管理-存储过程

文章目录 openGauss学习笔记-44 openGauss 高级数据管理-存储过程44.1 语法格式44.2 参数说明44.3 示例 openGauss学习笔记-44 openGauss 高级数据管理-存储过程 存储过程是能够完成特定功能的SQL语句集。用户可以进行反复调用&#xff0c;从而减少SQL语句的重复编写数量&…

SpringBoot 学习(03): 弱语言的注解和SpringBoot注解的异同

弱语言代表&#xff1a;Hyperf&#xff0c;一个基于 PHP Swoole 扩展的常驻内存框架 注解概念的举例说明&#xff1b; 说白了就是&#xff0c;你当领导&#xff0c;破烂事让秘书帮你去安排&#xff0c;你只需要批注一下&#xff0c;例如下周要举办一场活动&#xff0c;秘书将方…

sql server安装报错 合成活动模板库(ATL) 失败

错误 “合成活动模板库(ATL) 规则失败“ 解决办法&#xff1a; 进入SQL Server 2008R2安装包目录找到文件&#xff1a;sqlsupport_msi&#xff0c;安装此文件之后&#xff0c;再安装SQL Server&#xff0c;便可解决该问题。C:\SQL Server 2008R2\new\SQL Server 2008R2\2052_CH…

java Spring Boot yml多环境拆分文件管理优化

上文 java Spring Boot yml多环境配置 我们讲了多环境开发 但这种东西都放在一起 还是非常容易暴露信息的 并且对维护来讲 也不是非常的友好 这里 我们在resources下创建三个文件 分别叫 application-pro.yml application-dev.yml application-test.yml 我们直接将三个环境 转…

Android 广播发送流程分析

在上一篇文章中Android 广播阻塞、延迟问题分析方法讲了广播阻塞的分析方法&#xff0c;但是分析完这个问题&#xff0c;自己还是有一些疑问&#xff1a; 广播为啥会阻塞呢&#xff1f;发送给接收器就行了&#xff0c;为啥还要等着接收器处理完才处理下一个&#xff1f;由普通…

JVM前世今生之JVM内存模型

JVM内存模型所指的是JVM运行时区域&#xff0c;该区域分为两大块 线程共享区域 堆内存、方法区&#xff0c;即所有线程都能访问该区域&#xff0c;随着虚拟机和GC创建和销毁 线程独占区域 虚拟机栈、本地方法栈、程序计数器&#xff0c;即每个线程都有自己独立的区域&#…

帆软大屏2.0企业制作

&#xfffc; 数字化观点中心 / 当前页 如何从0-1制作数据大屏&#xff0c;我用大白话给你解释清楚了 文 | 商业智能BI相关文章 阅读次数&#xff1a;18,192 次浏览 2023-06-08 11:51:49 好莱坞大片《摩天营救》中有这么一个场景&#xff1a; &#xfffc; 你可以看见反派大b…