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

news2024/11/25 22:34:52

基于深度学习的运动目标检测(三)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 np

net = cv2.dnn.readNet("yolov3.weights", "yolov3.cfg")
classes = []
with open("coco.names", "r") as f:   #这里使用的是coco所训练的模型yolov3.cfg所以这里对应为coco.names
    classes = [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 plt
 
fig = 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 += 1
        ax = 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 += 1
        if i == 2:
            break
 

i = 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])
        break
    break
 



plt_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 = 0

for 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 += 1

plt.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 = 0

for 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 += 1

print(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.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)

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

     The image height is: 2250
     The image width is: 4000
     The 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 detected
            center_x = int(detection[0] * width)
            center_y = int(detection[1] * height)
            w = int(detection[2] * width)
            h = int(detection[3] * height)

            # Rectangle coordinates
            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)

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 detected
            center_x = int(detection[0] * width)
            center_y = int(detection[1] * height)
            w = int(detection[2] * width)
            h = int(detection[3] * height)

            # Rectangle coordinates
            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)

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.coloradmin.cn/o/903926.html

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

相关文章

多线程线程池

# 线程池的学习笔记总结图 图1: 图2: # 多线程的三种实现方式: 1.继承Thread类 2.实现Runnable类 3.实现Callable接口 # 线程的常见成员变量 # 线程的生命周期 # 线程的状态 # 线程池 # 自定义线程池 # 自定义线程池的使用情况的图解 一开始定义好的线…

安装Vue_dev_tools

Vue控制台出现Download the Vue Devtools extension for a better development experience: 下载Vue_dev_tools,这里给出网盘链接,有Vue2和Vue3的,dev_tools 以Google浏览器为例 点击设置(就是那三个点)->扩展程序->管理扩…

HummingBird 基于 Go 开源超轻量级 IoT 物联网平台

蜂鸟(HummingBird) 是 Go 语言实现的超轻量级物联网开发平台,包含设备接入、产品管理、物模型、告警中心、规则引擎等丰富功能模块。系统采用GoLang编写,占用内存极低, 单物理机可实现百设备的连接。 在数据存储上&…

华为OD机试 - 秘钥格式化 - 字符串处理(Java 2023 B卷 100分)

目录 专栏导读一、题目描述二、输入描述三、输出描述四、解题思路五、Java算法源码六、效果展示1、输入2、输出3、说明 华为OD机试 2023B卷题库疯狂收录中,刷题点这里 专栏导读 本专栏收录于《华为OD机试(JAVA)真题(A卷B卷&#…

Source Insight配置Cppcheck做静态测试(Windows)

1.安装cppcheck 先从cppcheck官方网站下载cppcheck的安装包。 注: (1)官网地址:https://sourceforge.net/projects/cppcheck (2)截止2023年8月,官方发布的最新版本是cppcheck-2.11-x64-Setup.…

解锁Spring AOP的神秘面纱

目录 Spring AOP的组成组成部分与常用注解举例理解 Spring AOP的实现添加 Spring AOP 框架⽀持定义切⾯和切点定义通知切点表达式说明 Spring AOP 实现原理JDK动态代理CGLIB动态代理 Spring AOP作为Spring框架的核心模块,为我们提供了一种优雅的方式来处理横切关注点…

Java-抽象类和接口(上)

如果一个类中没有包含足够的信息来描绘一个具体的对象,这样的类就是抽象类 在打印图形例子中, 我们发现, 父类 Shape 中的 draw 方法好像并没有什么实际工作, 主要的绘制图形都是由 Shape 的各种子类的 draw 方法来完成的. 像这种没有实际工作的方法, 我们可以把它…

OAuth2.0一 Spring Security OAuth2.0

这里主讲OAuth2.0 学习OAuth2前提: 掌握Spring Security Spring Security学习 一 OAuth2.0介绍 OAuth(Open Authorization)是一个关于授权(authorization)的开放网络标准,允许用户授权第三方应用访问他们…

数据结构<树和二叉树>顺序表存储二叉树实现堆排

✨Blog:🥰不会敲代码的小张:)🥰 🉑推荐专栏:C语言🤪、Cpp😶‍🌫️、数据结构初阶💀 💽座右铭:“記住,每一天都是一個新的開始&#x1…

【音视频原理】图像相关概念 ① ( 像素 | 分辨率 | 位深 )

文章目录 一、图像相关概念1、像素2、分辨率3、位深 一、图像相关概念 图像相关概念 : 像素 : 图片基本单位 ;分辨率 : 图像的像素尺寸 ;位深 : 记录每个像素点颜色时使用的位数 ;帧率 : 一秒钟传输图片的帧数 , 单位 fps , Frame Per Second ;码率 : 单位时间内视频的数据流量…

博弈论 | 斐波那契博弈

斐波那契博弈 博弈论是二人或多人在平等的对局中各自利用对方的策略变换自己的对抗策略,达到取胜目标的理论。博弈论是研究互动决策的理论。博弈可以分析自己与对手的利弊关系,从而确立自己在博弈中的优势,因此有不少博弈理论,可以帮助对弈者分析局势,从而采取相应策略,最终达…

系统架构设计专业技能 · 信息安全技术

系列文章目录 系统架构设计专业技能 网络技术(三) 系统架构设计专业技能 系统安全分析与设计(四)【系统架构设计师】 系统架构设计高级技能 软件架构设计(一)【系统架构设计师】 系统架构设计高级技能 …

Maven介绍与配置+IDEA集成Maven+使用Maven命令

目录 一、Maven简介 二、配置环境变量 三、IDEA集成Maven 1.配置本地仓库地址 2.集成Maven 3. pom.xml文件介绍 四、Maven命令 jar包太多、jar包相互依赖、不方便管理、项目编译还需要jar包,Maven工具来帮你! 一、Maven简介 Maven 是 Apache 软…

Python打包可执行文件-cx_Freeze

目录 简介 安装 问题处理 使用 打包 简介 之前有篇文章有使用pyinstaller打包.exe文件,但是没有详细介绍过,这次整理下 python入门-从安装环境配置(Anaconda)到做一个下班打卡提醒.exe小工具_瑶山的博客-CSDN博客 Python程序发布时,通常…

uniapp编写微信小程序和H5遇到的坑总结

uniapp编写微信小程序和H5遇到的坑总结 1、阻止事件冒泡2、二维码生成3、H5跨域配置4、H5时,地址栏上添加版本号5、H5时,tabBar遮挡部分内容6、uniapp使用webview通信6.1、uniapp编写的小程序嵌入h5之间的通信6.1.1、小程序向h5发送消息6.1.2、h5向小程序…

实验二 tftp 服务器环境搭建

tftp 服务器环境搭建 tftp(Trivial File Transfer Protocol)即简单文件传输协议是TCP/IP协议族中的一个用来在客户机与服务器之间进行简单文件传输的协议,提供不复杂、开销不大的文件传输服务。端口号为69 【实验目的】 掌握 tftp 环境搭…

【2023新教程】树莓派定时自动拍照并上传腾讯云对象存储COS

1 换源 仅适用于Release date: May 3rd 2023、Debian version: 11 (bullseye)这个树莓派OS版本,其他版本不保证有效。 首先使用如下命令,查看自己树莓派的架构。 uname -a结果如下: 如果红圈处显示为aarch64,使用命令sudo na…

Unity C# 引用池 ReferencePool

Unity C# 引用池 ReferencePool 1.目的 对于多次创建的数据使用new 关键字是十分消耗性能的,使用完成后由GC去自动释放,当一个类型的数据频繁创建可以使用引用池进行管理。 2.实现 项目目录 IReference 接口 要放入引用池的数据只需要继承这个接口…

2023.08.20 学习周报

文章目录 摘要文献阅读1.题目2.现有问题3.解决方案4.本文贡献5.方法5.1 利用长短期记忆网络学习时空演化特征5.2 构建用于气象辅助信息编码的堆叠自编码器5.3 使用多任务学习发现全市通用模式5.4 模型 6. 实验6.1 数据集6.2 实验设置6.3 实验结果 7.结论8.展望 大气污染物传输总…