OpenCV调用YOLOv4进行目标检测

目标检测就是对目标进行动态实时跟踪定位,常见的目标检测算法有 R-CNN、Fast R-CNN、Faster R-CNN、SSD、Yolo 等,其中 Yolo 的速度和精确度都比较高,且只需训练一次,使用起来比较方便。

这里我们就使用官方现成的模型来检测图片,看一看效果,先学会使用流程,以后再训练自己的模型。

注意:opencv-python 目前只有 4.4.0 版本适配了 YOLOv4


导入库

import numpy as np
import time
import cv2
  • 1
  • 2
  • 3

设置标签和标注颜色

LABELS = open("coco.names").read().strip().split("\n")
np.random.seed(666)
COLORS = np.random.randint(0, 255, size=(len(LABELS), 3), dtype="uint8")
  • 1
  • 2
  • 3

coco.names 内包含了很多目标标签,如 person、bicycle、car 等,且按一定顺序排列,里面基本包含了 Yolo 官方模型中可检测的对象。该文件可从以下链接中提取:https://gitee.com/public_sharing/ObjectDetection-YOLO/blob/master/coco.names

每个对象配备了不一样的颜色,以便在图片中标记时便于区分。


加载网络

# 导入 YOLO 配置和权重文件并加载网络:
net = cv2.dnn_DetectionModel('yolov4.cfg', 'yolov4.weights')
# 获取 YOLO 未连接的输出图层
layer = net.getUnconnectedOutLayersNames()
  • 1
  • 2
  • 3
  • 4

yolov4.cfg 和 yolov4.weights 文件就是官方提供的模型,下载链接:https://pan.baidu.com/s/1XrcPHdp2_4c-dKge2Guw4w 提取码:xsxb 。如果失效,可以直接百度搜索 Yolov4模型下载,有很多人都分享出来了。

cv2.dnn_DetectionModel 是 opencv 4.1.2 开始新增的方法,用于加载网络。以前是使用 cv2.dnn.readNetFromDarknet ,此处使用也可以达到同样的效果。

getUnconnectedOutLayersNames() 用于提取输出图层的名称,yolo 含有很多的图层,可以使用 getLayerNames() 将所有图层的名称提取出来。但在这里,我们只需要使用 yolo 的最后输出图层。


检测图片

# 导入图片
image = cv2.imread('timg.jpg')
# 获取图片尺寸
(H, W) = image.shape[:2]# 从输入图像构造一个 blob,然后执行 YOLO 对象检测器的前向传递,给我们边界盒和相关概率
blob = cv2.dnn.blobFromImage(image, 1/255.0, (416, 416),swapRB=True, crop=False)
net.setInput(blob)
start = time.time()
# 前向传递,获得信息
layerOutputs = net.forward(layer)
# 用于得出检测时间
end = time.time()
print("[INFO] YOLO took {:.6f} seconds".format(end - start))
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

blobFromImage 用于对图像进行预处理
cv2.dnn.blobFromImage(image[, scalefactor[, size[, mean[, swapRB[, crop[, ddepth]]]]]])

  • image:输入图像
  • scalefactor:图像各通道数值的缩放比例
  • size:输出图像的空间尺寸
  • mean:用于各通道减去的值,以降低光照的影响
  • swapRB:交换 RB 通道,默认为 False
  • crop:图像裁剪,默认为 False。当值为 True 时,先按比例缩放,然后从中心裁剪成 size 尺寸
  • ddepth:输出的图像深度,可选 CV_32F 或者 CV_8U

数据提取

boxes = []
confidences = []
classIDs = []# 循环提取每个输出层
for output in layerOutputs:# 循环提取每个框for detection in output:# 提取当前目标的类 ID 和置信度scores = detection[5:]classID = np.argmax(scores)confidence = scores[classID]# 通过确保检测概率大于最小概率来过滤弱预测if confidence > 0.5:# 将边界框坐标相对于图像的大小进行缩放,YOLO 返回的是边界框的中心(x, y)坐标,# 后面是边界框的宽度和高度box = detection[0:4] * np.array([W, H, W, H])(centerX, centerY, width, height) = box.astype("int")# 转换出边框左上角坐标x = int(centerX - (width / 2))y = int(centerY - (height / 2))# 更新边界框坐标、置信度和类 id 的列表boxes.append([x, y, int(width), int(height)])confidences.append(float(confidence))classIDs.append(classID)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25

3 个列表内保存的内容:

  • boxes:对象的边界框
  • confidences :YOLO 分配给对象的置信度值,较低的置信度值表示该对象可能不是网络认为的对象。上面的代码中将过滤掉小于 0.5 阈值的对象
  • classIDs:检测到的对象的类标签

这样每个被提取出的对象,都确定了标签和区域坐标就、位置。接下来就是在图片中标记出来,便于我们观看。


标记显示

# 非最大值抑制,确定唯一边框
idxs = cv2.dnn.NMSBoxes(boxes, confidences, 0.5, 0.3)
# 确定每个对象至少有一个框存在
if len(idxs) > 0:# 循环画出保存的边框for i in idxs.flatten():# 提取坐标和宽度(x, y) = (boxes[i][0], boxes[i][1])(w, h) = (boxes[i][2], boxes[i][3])# 画出边框和标签color = [int(c) for c in COLORS[classIDs[i]]]cv2.rectangle(image, (x, y), (x + w, y + h), color, 1, lineType=cv2.LINE_AA)text = "{}: {:.4f}".format(LABELS[classIDs[i]], confidences[i])cv2.putText(image, text, (x, y - 5), cv2.FONT_HERSHEY_SIMPLEX,0.5, color, 1, lineType=cv2.LINE_AA)
cv2.imshow("Tag", image)
cv2.waitKey(0)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

对于每个对象,Yolo 会框出 3 个左右的区域,我们只需要显示出最合适的区域。非最大值抑制,就是搜索出局部最大值,将置信度最大的框保存,其余剔除。

cv2.dnn.NMSBoxes(bboxes, scores, score_threshold, nms_threshold, eta=None, top_k=None)

  • bboxes:一组边框
  • scores:一组对应的置信度
  • score_threshold:置信度的阈值
  • nms_threshold:非最大抑制的阈值

之后将每个对象的方框和标签都画出来

结果展示:
在这里插入图片描述


完整代码

import numpy as np
import time
import cv2LABELS = open("coco.names").read().strip().split("\n")
np.random.seed(666)
COLORS = np.random.randint(0, 255, size=(len(LABELS), 3), dtype="uint8")
# 导入 YOLO 配置和权重文件并加载网络:
net = cv2.dnn_DetectionModel('yolov4.cfg', 'yolov4.weights')
# 获取 YOLO 未连接的输出图层
layer = net.getUnconnectedOutLayersNames()
image = cv2.imread('timg.jpg')
# 获取图片尺寸
(H, W) = image.shape[:2]
# 从输入图像构造一个 blob,然后执行 YOLO 对象检测器的前向传递,给我们边界盒和相关概率
blob = cv2.dnn.blobFromImage(image, 1/255.0, (416, 416),swapRB=True, crop=False)
net.setInput(blob)
start = time.time()
# 前向传递,获得信息
layerOutputs = net.forward(layer)
# 用于得出检测时间
end = time.time()
print("YOLO took {:.6f} seconds".format(end - start))boxes = []
confidences = []
classIDs = []# 循环提取每个输出层
for output in layerOutputs:# 循环提取每个框for detection in output:# 提取当前目标的类 ID 和置信度scores = detection[5:]classID = np.argmax(scores)confidence = scores[classID]# 通过确保检测概率大于最小概率来过滤弱预测if confidence > 0.5:# 将边界框坐标相对于图像的大小进行缩放,YOLO 返回的是边界框的中心(x, y)坐标,# 后面是边界框的宽度和高度box = detection[0:4] * np.array([W, H, W, H])(centerX, centerY, width, height) = box.astype("int")# 转换出边框左上角坐标x = int(centerX - (width / 2))y = int(centerY - (height / 2))# 更新边界框坐标、置信度和类 id 的列表boxes.append([x, y, int(width), int(height)])confidences.append(float(confidence))classIDs.append(classID)
# 非最大值抑制,确定唯一边框
idxs = cv2.dnn.NMSBoxes(boxes, confidences, 0.5, 0.3)
# 确定每个对象至少有一个框存在
if len(idxs) > 0:# 循环画出保存的边框for i in idxs.flatten():# 提取坐标和宽度(x, y) = (boxes[i][0], boxes[i][1])(w, h) = (boxes[i][2], boxes[i][3])# 画出边框和标签color = [int(c) for c in COLORS[classIDs[i]]]cv2.rectangle(image, (x, y), (x + w, y + h), color, 1, lineType=cv2.LINE_AA)text = "{}: {:.4f}".format(LABELS[classIDs[i]], confidences[i])cv2.putText(image, text, (x, y - 5), cv2.FONT_HERSHEY_SIMPLEX,0.5, color, 1, lineType=cv2.LINE_AA)
cv2.imshow("Tag", image)
cv2.waitKey(0)

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

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

相关文章

2024年3月电子学会青少年编程等级考试时间安排

1考试方式 1. 在线居家考试(全国); 2. 对于符合线下考试要求的考试服务网点,经地方实地调研报学会总部批准后,可组织线下考试。 2报名时间 报名时间:2023年12月21日-2024年3月12日16:00; 考…

Sql Server常用时间段查询汇总

前言 本文对应Sql Server 中常用的时间查询的进行一些汇总,例如查询当天的、本周的、本月的、本季度的,某个时间段内的时间。 实例 实例(我的)表名:mytable 字段名:mydate (一)、…

scan-cvs-user.sh

为什么80%的码农都做不了架构师?>>> scan-cvs-user.sh #! /bin/sh export LC_ALLzh_CN.UTF-8 cd /bin2/ sh scan-cvs-user-daily.sh > scan-cvs-user-daily.sh.log 2>&1 /usr/bin/mutt -s "scan-cvs-user-daily" scm-svr-mtrsc…

CV2 puttext不能显示中文问题

CV2 puttext不能显示中文问题,还是这个方法管用: 解决方法:将图片格式转化为PIL库的格式,用PIL的方法写入中文,然后在转化为CV的格式 但是采用如下方案会导致性能降低,毕竟多加了一次转化格式。 from P…

LINQ能不能用系列(二)LINQ to SQL 效率比对

前言 很多人听说过LINQ TO SQL与ADO.NET传统方式用于不同的环境,LINQ TO SQL与ADO.NET传统方式也没有可比性,就像公交车与私家车一样,虽然是车但用途完全不同,但很少有人去探究,究竟为什么他们不同,他们不…

libgdx游戏引擎开发笔记(十三)SuperJumper游戏例子的讲解(篇七)----各个物体的创建及其碰撞检测...

接着上一篇,我们完成后续的扫尾工作:游戏中个物体创建及其碰撞检测,分数保存,音效处理。1.World类:(加入所有物体,及其碰撞检测,代码里有详细注解)package com.zhf.mylibgdx; import…

oracle交流 提问,Oracle相关提问的智慧技巧

《很久以前的一篇对初学Oracle建议的文章》曾提到了提问的智慧,这个问题确实很值得说,我在学生时期,尤其是在本硕阶段中,作为非科班出身,要接触很多新的计算机技术,日常做的最多的,可能就是问问…

yolov5的flask部署python调用

yolov5 github:https://github.com/ultralytics/yolov5 跟踪:https://github.com/mikel-brostrom/Yolov5_DeepSort_Pytorch TensorRT:https://github.com/TrojanXu/yolov5-tensorrt NCNN:https://github.com/WZTENG/YOLOv5_NCNN …

Sql Server内置函数实现MD5加密

实例 MD5加密“123456”: HashBytes(MD5,123456) 结果:0xE10ADC3949BA59ABBE56E057F20F883E (提示:看完最后,结果要进行转换。) 函数 函数描述返回值 HashBytes HashBytes (加密方式, 待加密的值)加密方…

(转)关于X64位系统IIS7下支持32位asp.net程序

最近在windows2008 x64位系统下的IIS7下部署asp.net程序。 vs2005或vs2008默认的情况下是Any cpu 的也就是支持x86和x64两种系统的。可我的程序在引用了一个三方dll组件时引起了这样的错误: 错误“/test”应用程序中的服务器错误。 -------------------------------…

Ubuntu16.04 Caffe 编译安装步骤记录

历时一周终于在 ubuntu16.04 系统成功安装 caffe 并编译,网上有很多教程,但是某些步骤并没有讲解详尽,导致配置过程总是出现各种各样匪夷所思的问题,尤其对于新手而言更是欲哭无泪,在我饱受折磨后决定把安装步骤记录下…

oracle11g arm,想知道ARM11架构?这篇介绍告诉你

实际上,处理器采用的架构才是影响处理器性能的关键因素。手机中采用的ARM架构,从最早的ARM9到下一代的Cortex-A15,已经经历了多次的更新换代,每一次的升级都带来了性能的大幅提升,那么它们各自的性能到底怎么样呢?今天…

C# 调用IP库(QQWry.Dat)查询IP位置及自动升级IP库方法(附IP库下载地址及相关dll下载)

前言 C# 用IP地址(123.125.114.144)查询位置(北京市百度公司)的东西,非常好用也非常方便,可手动升级刷新IP库,一次编码永久收益,可支持winform、asp.net等程序。 本文使用的IP库为…

WCF简单教程(8) 安全 - Windows认证

第八篇:WCF安全WCF提供了非常丰富的加密机制与审核机制,以保证对外提供的服务安全可靠。本文是简单教程,所以只挑其中的一小部分来聊聊。先来看看最简单的Windows认证。所谓Windows认证,是指客户端访问时,要提供服务端…

常用Sql整理笔记

一、多行结果转换为一行,用逗号隔开。 mssql代码如下: 点击打开 -- 多行select tid from typeinfo where pid4-- 一行select STUFF((Select ,Convert(varchar(50),tid) FROM typeinfo where pid4 FOR XML PATH()),1,1,) as tid sqlite代码如下&#xff…

Ubuntu16.04 Caffe2 编译安装步骤记录

我的本机环境如下,任何的环境上的不一致可能会带来一些安装上的问题,所以这个教程只是一个简单的参考。 环境 操作系统: Ubuntu 16.04GPU型号: Tesla M40 24GBPython: 2.7 路径 /usr/bin/python即全局的python解释器 caffe2必备依赖的安装 sudo apt-g…

oracle中视图窗粉色的,Oracle 11g日常操作与维护手册

# /oracle/crs/bin/srvctl config nodeapps -a -n linux1RAC安装完以后,可以修改两个节点的VIP。前提是修改后的VIP必须没有被其他系统使用掉。正确的修改方法如下:步骤1:使用srvctl修改VIP进入/crs/bin目录下执行如下命令:# ./sr…

Go语言Web框架gwk介绍 (一)

今天看到Golang排名到前30名了,看来关注的人越来越多了,接下来几天详细介绍Golang一个web开发框架GWK。 现在博客园支持markdown格式发布文章么?后台的编辑器不太好用嘛。 GWK 简介 gwk(GO Web Server Kit)是GO语言的Web Server开发框架&…

3D手势姿态跟踪算法:手机端实时检测,多个手势同时捕捉

就在不久前,Google 人工智能实验室宣布,他们在「实时手部跟踪」方面取得了新的进展,并将这项新技术运用在了 MediaPipe 中,这也是 AI 计算机视觉任务的一大突破。这一技术不光可以在手机上实现实时捕捉性能,甚至可以同…

Windows服务的快速搭建与调试(C#图解)

目录 一、什么是Windows 服务? 二、创建Windows 服务与安装/卸载批处理。 三、调试Windows 服务。 正文 一、什么是Windows 服务? 答:Microsoft Windows 服务(即,以前的 NT 服务)使您能够创建在它们自…