一文带你学会使用YOLO及Opencv完成图像及视频流目标检测(上)|附源码

计算机视觉领域中,目标检测一直是工业应用上比较热门且成熟的应用领域,比如人脸识别、行人检测等,国内的旷视科技、商汤科技等公司在该领域占据行业领先地位。相对于图像分类任务而言,目标检测会更加复杂一些,不仅需要知道这是哪一类图像,而且要知道图像中所包含的内容有什么及其在图像中的位置,因此,其工业应用比较广泛。那么,今天将向读者介绍该领域中表现优异的一种算算法——“你只需要看一次”(you only look once,yolo),提出该算法的作者风趣幽默可爱,其个人主页及论文风格显示了其性情,目前该算法已是第三个版本,简称YoLo V3。闲话少叙,下面进入教程的主要内容。
在本教程中,将学习如何使用YOLO、OpenCV和Python检测图像和视频流中的对象。主要内容有:

  • 简要讨论YOLO算法;
  • 使用YOLO、OpenCV、Python进行图像检测;
  • 使用YOLO、OpenCV、Python进行视频流检测;
  • 讨论YOLO算法的优点和缺点;

什么是YOLO?


图1: YOLO目标检测器简化示意图

当涉及基于深度学习的对象检测时,常用的三类算法有:

  • R-CNN家族系列算法:R-CNN、fast R-CNN以及faster R-CNN;
  • 单发检测器(SSD);
  • YOLO算法;
    R-CNN算法是最早的基于深度学习的目标检测器之一,其结构是两级网络:
  • 首先需要诸如选择性搜索之类的算法来提出可能包含对象的候选边界框;
  • 然后将这些区域传递到CNN算法进行分类;

R-CNN算法存在的问题在于其仿真很慢,并且不是完整的端到端的目标检测器。
Fast R-CNN算法对原始R-CNN进行了相当大的改进,即提高准确度并减少执行正向传递所花费的时间,但是,该模型仍然依赖于外部区域搜索算法。
直到2015年,[faster R-CNN]()才成为真正的端到端深度学习目标检测器,删除了选择性搜索的要求,而是依赖于(1)完全卷积的区域提议网络(RPN)和(2)可以预测对象边界框和“对象”分数(量化它是一个区域的可能性的分数)。然后将RPN的输出传递到R-CNN组件以进行最终分类和标记。
R-CNN系列算法的检测结果一般都非常准确,但R-CNN系列算法最大的问题在仿真速度——非常慢,即使是在GPU上也仅获得5 FPS。
为了提高基于深度学习的目标检测器的速度,单次检测器(SSD)和YOLO都使用单级检测器策略(one stage)。这类算法将对象检测视为回归问题,获取给定的输入图像并同时学习边界框坐标和相应的类标签概率。通常,单级检测器往往不如两级检测器准确,但其速度明显更快。YOLO是单级检测器中一个很好的算法。
YOLO算法于2015年提出,在GPU上获得了  45 FPS性能,此外,同时也提出了一个较小的变体称为“Fast YOLO”,在GPU上达到155 FPS的性能。
YOLO经历了许多次的迭代,包括YOLOv2,能够检测超过9,000个目标。直到最近提出的YOLOv3算法,YOLOv3模型比之前的版本要复杂得多,但它是YOLO系列目标检测器中最好的一款。
本文使用YOLOv3,并在COCO数据集上进行训练。
COCO数据集由80个标签组成,可以使用此链接找到YOLO在COCO数据集上训练的内容的完整列表。

项目结构

在终端中使用tree命令,可以很方便快捷地生成目标树:

$ tree
.
├── images
│   ├── baggage_claim.jpg
│   ├── dining_table.jpg
│   ├── living_room.jpg
│   └── soccer.jpg
├── output
│   ├── airport_output.avi
│   ├── car_chase_01_output.avi
│   ├── car_chase_02_output.avi
│   └── overpass_output.avi
├── videos
│   ├── airport.mp4
│   ├── car_chase_01.mp4
│   ├── car_chase_02.mp4
│   └── overpass.mp4
├── yolo-coco
│   ├── coco.names
│   ├── yolov3.cfg
│   └── yolov3.weights
├── yolo.py
└── yolo_video.py

从上面可以看出,项目包括4个文件夹和2个Python脚本。
目录(按重要性顺序)是:

  • yolo - coco /  :YOLOv3对象检测器预先(在COCO数据集上)训练得到最终的权重文件,可以在Darknet团队主页找到对应的文件;
  • images / :此文件夹包含四个静态图像,之后将执行对象检测以进行测试和评估;
  • videos/ :使用YOLO对图像进行目标检测器后,将实时处理视频。该文件夹中包含四个示例视频可供测试;
  • 输出/  :输出已由YOLO处理并带有边界框和类名称注释的视频可以放在此文件夹中;

此外还有两个Python脚本——yolo .py和 yolo_video.py ,第一个脚本用于图像处理,第二个脚本用于视频处理。下面进入实战内容,你准备好了吗?

将YOLO应用于图像对象检测

首先将YOLO目标检测器应用于图像中,首先打开项目中的 yolo .py并插入以下代码:

# import the necessary packages
import numpy as np
import argparse
import time
import cv2
import os

# construct the argument parse and parse the arguments
ap = argparse.ArgumentParser()
ap.add_argument("-i", "--image", required=True,
    help="path to input image")
ap.add_argument("-y", "--yolo", required=True,
    help="base path to YOLO directory")
ap.add_argument("-c", "--confidence", type=float, default=0.5,
    help="minimum probability to filter weak detections")
ap.add_argument("-t", "--threshold", type=float, default=0.3,
    help="threshold when applying non-maxima suppression")
args = vars(ap.parse_args())

在使用之前,需要为此脚本安装 3.4.2+版本以上的OpenCV,可以直接使用
pip install opencv-python==3.4.2安装,你也可以在这里找到OpenCV安装教程,这里注意一点,OpenCV 4目前处于测试阶段,这里建议去安装OpenCV 3.4.2+。
首先,导入所需的数据包——OpenCV和NumPy。现在解析四个命令行参数,命令行参数在运行时处理,允许我们从终端更改脚本的输入。如果你对其不熟悉,建议阅读相关的内容。命令行参数包括:

  • -- image  :输入图像的路径;
  • -- yolo  :YOLO文件路径,脚本将加载所需的YOLO文件,以便在图像上执行对象检测;
  • -- confidence  :过滤弱检测的最小概率,默认值设置为0.5,但该值也可以随意设置;
  • -- threshold  :非最大值抑制阈值,默认值设置为 0.3,可以在此处阅读有关非最大值抑制的更多信息。

解析之后,args变量是一个包含命令行参数的键值对的字典。下面为每个标签设置随机颜色:

# load the COCO class labels our YOLO model was trained on
labelsPath = os.path.sep.join([args["yolo"], "coco.names"])
LABELS = open(labelsPath).read().strip().split("\n")

# initialize a list of colors to represent each possible class label
np.random.seed(42)
COLORS = np.random.randint(0, 255, size=(len(LABELS), 3),
    dtype="uint8")

上述加载所有类 LABELS,其类型是列表,保存的是类别名称,然后将随机颜色分配给每个标签  。下面设置YOLO权重和配置文件的路径,然后从磁盘加载YOLO文件:

# derive the paths to the YOLO weights and model configuration
weightsPath = os.path.sep.join([args["yolo"], "yolov3.weights"])
configPath = os.path.sep.join([args["yolo"], "yolov3.cfg"])

# load our YOLO object detector trained on COCO dataset (80 classes)
print("[INFO] loading YOLO from disk...")
net = cv2.dnn.readNetFromDarknet(configPath, weightsPath)

从磁盘加载YOLO文件后,并利用OpenCV中的cv2.dnn.readNetFromDarknet函数从中读取网络文件及权重参数,此函数需要两个参数configPath 和 weightsPath,这里再次强调,:OpenCV 的版本至少是3.4.2及以上才能运行此代码,因为它需要加载YOLO所需的更新的 dnn模块。
下面加载图像并处理:

# load our input image and grab its spatial dimensions
image = cv2.imread(args["image"])
(H, W) = image.shape[:2]

# determine only the *output* layer names that we need from YOLO
ln = net.getLayerNames()
ln = [ln[i[0] - 1] for i in net.getUnconnectedOutLayers()]

# construct a blob from the input image and then perform a forward
# pass of the YOLO object detector, giving us our bounding boxes and
# associated probabilities
blob = cv2.dnn.blobFromImage(image, 1 / 255.0, (416, 416),
    swapRB=True, crop=False)
net.setInput(blob)
start = time.time()
layerOutputs = net.forward(ln)
end = time.time()

# show timing information on YOLO
print("[INFO] YOLO took {:.6f} seconds".format(end - start))

在该代码中:

  • 加载输入 图像并获得其尺寸;
  • 确定YOLO模型中的输出图层名称;
  • 从图像构造一个 blob结构;

如果你对blob和cv2.dnn.blobFromImage有疑问,可以看这篇博客进一步的了解。
当blob准备好了后,我们就会

  • 通过YOLO网络进行前向传递;
  • 显示YOLO的推理时间;
    现在采取措施来过滤和可视化最终的结果。首先,让我们初步化一些处理过程中需要的列表:
# initialize our lists of detected bounding boxes, confidences, and
# class IDs, respectively
boxes = []
confidences = []
classIDs = []

这些列表包括:

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

下面用YOLO layerOutputs中的数据填充这些列表 :

# loop over each of the layer outputs
for output in layerOutputs:
    # loop over each of the detections
    for detection in output:
        # extract the class ID and confidence (i.e., probability) of
        # the current object detection
        scores = detection[5:]
        classID = np.argmax(scores)
        confidence = scores[classID]

        # filter out weak predictions by ensuring the detected
        # probability is greater than the minimum probability
        if confidence > args["confidence"]:
            # scale the bounding box coordinates back relative to the
            # size of the image, keeping in mind that YOLO actually
            # returns the center (x, y)-coordinates of the bounding
            # box followed by the boxes‘ width and height
            box = detection[0:4] * np.array([W, H, W, H])
            (centerX, centerY, width, height) = box.astype("int")

            # use the center (x, y)-coordinates to derive the top and
            # and left corner of the bounding box
            x = int(centerX - (width / 2))
            y = int(centerY - (height / 2))

            # update our list of bounding box coordinates, confidences,
            # and class IDs
            boxes.append([x, y, int(width), int(height)])
            confidences.append(float(confidence))
            classIDs.append(classID)

在这个块中:

  • 循环遍历每个 layerOutputs
  • 循环每个detection中 output
  • 提取 classID和 confidence
  • 使用 confidence滤除弱检测;

过滤掉了不需要的检测结果后,我们将:

  • 缩放边界框坐标,以便我们可以在原始图像上正确显示它们;
  • 提取边界框的坐标和尺寸,YOLO返回边界框坐标形式: (centerX ,centerY ,width,height);
  • 使用此信息导出边界框的左上角(x,y)坐标;
  • 更新boxes, confidences ,classIDs列表。
    有了这些数据后,将应用“非最大值抑制”(non-maxima suppression,nms):
# apply non-maxima suppression to suppress weak, overlapping bounding
# boxes
idxs = cv2.dnn.NMSBoxes(boxes, confidences, args["confidence"],
    args["threshold"])

YOLO算法并没有应用非最大值抑制,这里需要说明一下。应用非最大值抑制可以抑制明显重叠的边界框,只保留最自信的边界框,NMS还确保我们没有任何冗余或无关的边界框。
利用OpenCV内置的NMS DNN模块实现即可实现非最大值抑制 ,所需要的参数是边界 框、 置信度、以及置信度阈值和NMS阈值。
最后在图像上绘制检测框和类文本:

# ensure at least one detection exists
if len(idxs) > 0:
    # loop over the indexes we are keeping
    for i in idxs.flatten():
        # extract the bounding box coordinates
        (x, y) = (boxes[i][0], boxes[i][1])
        (w, h) = (boxes[i][2], boxes[i][3])

        # draw a bounding box rectangle and label on the image
        color = [int(c) for c in COLORS[classIDs[i]]]
        cv2.rectangle(image, (x, y), (x + w, y + h), color, 2)
        text = "{}: {:.4f}".format(LABELS[classIDs[i]], confidences[i])
        cv2.putText(image, text, (x, y - 5), cv2.FONT_HERSHEY_SIMPLEX,
            0.5, color, 2)

# show the output image
cv2.imshow("Image", image)
cv2.waitKey(0)

假设存在至少一个检测结果,就循环用非最大值抑制确定idx 。然后,我们使用随机类颜色在图像上绘制边界框和文本 。最后,显示结果图像,直到用户按下键盘上的任意键。
下面进入测试环节,打开一个终端并执行以下命令:

$ python yolo.py --image images/baggage_claim.jpg --yolo yolo-coco
[INFO] loading YOLO from disk...
[INFO] YOLO took 0.347815 seconds


图2:YOLO用于检测机场中的人员和行李

从上图可以看到,YOLO不仅检测了输入图像中的每个人,还检测了手提箱。此外,可以从图像的右上角看到,YOLO还检测到女士肩上的手提包。
我们试试另一个例子:

$ python yolo.py --image images/living_room.jpg --yolo yolo-coco
[INFO] loading YOLO from disk...
[INFO] YOLO took 0.340221 seconds


图3: YOLO用于检测人、狗、电视和椅子

YOLO还可以检测电视显示器和椅子,令我惊讶的是YOLO能够检测到椅子,因为它是手工制作的老式“婴儿高脚椅”。
有趣的是,YOLO认为我手中有一个遥控器,它实际上不是遥控器——玻璃反射的VHS录,仔细盯着这个地方看,它实际上看起来非常像遥控器。
以下示例图像演示了YOLO对象检测器的局限性和弱点:

$ python yolo.py --image images/dining_table.jpg --yolo yolo-coco
[INFO] loading YOLO from disk...
[INFO] YOLO took 0.362369 seconds


图4: YOLO用于检测餐桌

虽然YOLO正确检测到葡萄酒瓶、餐桌和花瓶,但只有两个酒杯中的一个被正确检测到。
下面尝试最后一幅图像:

$ python yolo.py --image images/soccer.jpg --yolo yolo-coco
[INFO] loading YOLO from disk...
[INFO] YOLO took 0.345656 seconds


图5:使用YOLO检测足球运动员和足球

YOLO能够正确地检测球场上的每个球员,包括足球本身。请注意,尽管区域高度模糊且部分遮挡,但仍会检测到背景中的人。
以上内容就是图像检测部分的全部内容,下一节将介绍视频流中对象检测以及YOLO算法的总结。

原文链接
本文为云栖社区原创内容,未经允许不得转载。

原文地址:https://www.cnblogs.com/yunqishequ/p/9994195.html

时间: 2024-10-07 07:27:54

一文带你学会使用YOLO及Opencv完成图像及视频流目标检测(上)|附源码的相关文章

【原创】.NET平台机器学习组件-Infer.NET连载(二)简单贝叶斯分类器的例子—【附源码和自制帮助文档】

Infer.NET机器学习翻译系列文章将进行连载,感兴趣的朋友请收藏或关注 你还可以参考本博客其他.NET开源项目的相关文章: [原创]彩票预测算法:离散型马尔可夫链模型          Newlife XCode组件资源目录汇总[2013年版] [原创]开源.NET下的XML数据库介绍及入门          [原创].NET开源压缩组件介绍与入门 [开源].NET开源表达式计算组件介绍与使用          [原创]开源Word读写组件DocX介绍与入门 [原创]Matlab.NET混编

【C#附源码】数据库文档生成工具支持(Excel+Html)

[2015] 很多时候,我们在生成数据库文档时,使用某些工具,可效果总不理想,不是内容不详细,就是表现效果一般般.很多还是word.html的.看着真是别扭.本人习惯用Excel,所以闲暇时,就简单的编写了数据库文档生成工具,供大家交流学习之用,与程序员共勉.     该工具为C#控制台,以NPOI为基础,操作Excel.简单方便,简单配置.两次回车,OK!即可生成清晰的数据库文档.另外,支持生成HTML文档.源码大小7MB,OS上传不了,放到百度云盘里了:http://pan.baidu.co

FlexPaper实现文档在线浏览(附源码)

园子里也有关于FlexPaper的文章,但都不怎么详细. 没有较全的参数说明.就连官方网站都没有.没法,最后只得将swf文件反编译后查看了源码才将里面的参数全部弄出来. 好了,废话不多说,开始正题. 1. 概述 FlexPaper是一个开源轻量级的在浏览器上显示各种文档的组件,被设计用来与PDF2SWF一起使用, 使在浏览器中显示PDF成为可能,而这个过程并无需PDF软件环境的支持. 另外也可以通过将一些例如Word.PPT等文档转成PDF,然后实现在线浏览. 2. 实现步骤 文档(PDF,Wo

一款可支持物流查询带营销功能的小程序商城 附源码

零基础快速部署一款可支持物流查询带营销功能的小程序商城只要有基础的计算机能力都可以开发自己的小程序商城,让技术门槛降低,服务更多用户,创造无限价值!只需三步,就可开发自己的小程序商城,带拼团砍价秒杀分销优惠券等强大功能一.注册小程序账号,认证小程序.开通微信支付商户付款功能https://mp.weixin.qq.com二.下载安装小程序商城源码,部署服务器http://github.crmeb.net/u/crmeb三.后台配置 小程序基本参数,小程序域名,支付配置,下载小程序开发工具,提交源

基于jQuery slide插件的轮播大图,带标题及简介,附源码

1.首先看效果 2.源码 1)index.html <!DOCTYPE html> <html lang="en"> <head>     <meta charset="UTF-8">     <title></title> </head> <body> <!-- Demo start --> <!-- css --> <link rel=&

一个winform带你玩转rabbitMQ(三) 附源码

第一章. 安装,简介和初探 第二章. exchange,queue,binding介绍 订阅发布 工作队列(消费者集群) 本章收尾 介绍API CommandLine 以及其他功能 源码地址 https://github.com/dubing/MaoyaRabbit RabbitMQ API RabbitMQ Server提供了丰富的http api. 举个列子 需要HTTP基本身份验证.默认的用户名/密码为guest/guest. 这些返回值得意义我从官网搬来解释,为了避免翻译的问题导致大家理

带你玩转rabbitMQ 附源码

RabbitMQ API RabbitMQ Server提供了丰富的http api. 举个列子 需要HTTP基本身份验证.默认的用户名/密码为guest/guest. 这些返回值得意义我从官网搬来解释,为了避免翻译的问题导致大家理解的误差这里直接给出原文 cluster_name The name of the entire cluster, as set with rabbitmqctl set_cluster_name. erlang_full_version A string with

在eclipse中查看sources源码和JavaDoc帮助文档

今天学习Netty的过程中,从官网下载的netty里面的内容如下: 其中jar文件夹里面的内容如下: 可以看到每一个具体的jar包就对应有一个sources.jar包,然后所有的帮助文档在javaDoc文件下面的jar包里面 那怎么查看一个类的源码和帮助文档呢??? 当我们在没有进行相应的配置前,当我们双击一个类时,会报类找不到 这时我们可以点击"Attach Source-",配置sources所在的路径 然后就可以了. 不过一般呢,我们可以这样配置: ①右键目标jar包,选择Pro

深度学习之目标检测常用算法原理+实践精讲 YOLO / Faster RCNN / SSD / 文本检测 / 多任务网络

深度学习之目标检测常用算法原理+实践精讲 YOLO / Faster RCNN / SSD / 文本检测 / 多任务网络 资源获取链接:点击这里 第1章 课程介绍 本章节主要介绍课程的主要内容.核心知识点.课程涉及到的应用案例.深度学习算法设计通用流程.适应人群.学习本门课程的前置条件.学习后达到的效果等,帮助大家从整体上了解本门课程的整体脉络. 1-1 课程导学 第2章 目标检测算法基础介绍 本章节主要介绍目标检测算法的基本概念.传统的目标检测算法.目前深度学习目标检测主流方法(one-sta