【OpenCV-Python实战项目】08-YOLO-V3实时目标检测

0.介绍

(1)YOLO是一个开源的目标检测算法,兼顾准确率和运行速度,本笔记主要用YOLO-V3进行图像 or 摄像头视频或者下载视频的目标检测。
(2)检测流程:

  • 1)opencv读取视频流或图像;
  • 2)创建YOLO-V3网络模型并导入权重文件;
  • 3)用模型进行检测并输出检测数值,最后绘制显示在图像上;

(3)YOLO-V3的网络配置文件以及对应的模型权重文件下载:YOLO配置以及权重文件下载链接
注意:FPS表示视频显示帧率,即一秒中图像数量,越大表示视频显示越流畅,下载的模型为YOLOv3-320,下载cfg模型配置文件(加载网络结构)+weights(模型权重文件)两个。

在这里插入图片描述

此外由于该模型是在COCO上面下载的,一共有80类,需要导入其类别文件,方面后续绘制出类别名称,类别如下:

在这里插入图片描述

1.基础功能实现

(1)用法说明:
1)先加载类别文件,然后构建模型并导入训练好的权重,代码片段如下:

classNames= []
classFile='coco.names'
with open(classFile,'rt') as f:
    classNames=f.read().rstrip('\n').split('\n')

modelConfiguration='yolov3.cfg'
modekWeights='yolov3.weights'
net=cv2.dnn.readNetFromDarknet(modelConfiguration,modekWeights)
net.setPreferableBackend(cv2.dnn.DNN_BACKEND_OPENCV)#to use opencv
net.setPreferableTarget(cv2.dnn.DNN_TARGET_CPU)#to use cpu

2)对输入网络的数据进行预处理,比如裁剪到网络支持的尺寸等

#blobFromImage主要是用来对图片进行预处理:分别是影像,缩放系数、输入图片的尺寸,图片整体减去的平均值,crop
blob = cv2.dnn.blobFromImage(image, scalefactor=1.0, size, mean, swapRB=True,crop=False,ddepth = CV_32F )

3)将预处理好的数据喂入网络并从网络输出层得到结果,但是由于YOLO-V3是输出有三层,因此如下为得到输出三层的名称,然后提取出对应的结果步骤:

outputNames=[layerNames[i-1] for i in net.getUnconnectedOutLayers()]
outputs=net.forward(outputNames) #三层的输出结果,shape分别是:
outputs[0].shape=(300,85)outputs[1].shape=(1200,85),outputs[2].shape=(4800,85),

其中每一行85个数,前四个数表示x,y,w,h,检测置信度,最后80表示80个类别每个类别的得分,遍历提取即可。
在这里插入图片描述
4) 非极大值抑制用于过滤掉同一个物体出现了不同大小的检测框

(2)完整代码:

import cv2
import numpy as np


cap=cv2.VideoCapture('object.mp4')# 可以设置为0,默认打开摄像头

classNames= []
classFile='coco.names'
with open(classFile,'rt') as f:
    classNames=f.read().rstrip('\n').split('\n')

modelConfiguration='yolov3.cfg'
modekWeights='yolov3.weights'
net=cv2.dnn.readNetFromDarknet(modelConfiguration,modekWeights)
net.setPreferableBackend(cv2.dnn.DNN_BACKEND_OPENCV)#to use opencv
net.setPreferableTarget(cv2.dnn.DNN_TARGET_CPU)#to use cpu


def findObjects(outputs,img):
    hT,wT,cT=img.shape
    bbox=[] 
    classIds=[]
    confs=[]

    for output in outputs:#3层结果
        for det in output:#每层检测结果
            scores=det[5:]  
            classId=np.argmax(scores)
            conf=scores[classId]
            if conf>0.5:
                w,h=int(det[2]*wT),int(det[3]*hT)
                x,y=int((det[0]*wT)-w/2),int((det[1]*hT)-h/2)#注意减去
                bbox.append([x,y,w,h])
                classIds.append(classId)
                confs.append(float(conf))

        indices=cv2.dnn.NMSBoxes(bbox,confs,0.5,0.4)

        for i in indices:
            # print(i)

            box=bbox[i]
            x,y,w,h=box
            label=classNames[classIds[i]]
            confidence=confs[i]
            cv2.rectangle(img,(x,y),(x+w,y+h),(255,0,255),2)
            cv2.putText(img,f'{label} {confidence}',(x,y-10),cv2.FONT_HERSHEY_SIMPLEX,0.5,(255,0,255),2)
 


while True:
    success,img=cap.read()
    # blobFromImage主要是用来对图片进行预处理:分别是影像,缩放系数、输入图片的尺寸,图片整体减去的平均值,crop
    blob=cv2.dnn.blobFromImage(img,1/255,(320,320),[0,0,0],1,crop=False)

    net.setInput(blob)

    layerNames=net.getLayerNames()
    # print(type(layerNames))
    # print(layerNames[0])
    # print(type(net.getUnconnectedOutLayers()))#获取输出层的索引
 
    outputNames=[layerNames[i-1] for i in net.getUnconnectedOutLayers()]
    # print(outputNames)
    outputs=net.forward(outputNames)
    # print(outputs[0].shape)#第一个表示检测的盒子数,85表示一堆值,如x,y,w,h,confidence,80表示类别数
    # print(outputs[1].shape)
    # print(outputs[2].shape)
    # print(outputs[0][0])
    findObjects(outputs,img)

    cv2.imshow('Video',img)
    
    if cv2.waitKey(1) & 0xFF==ord('q'):
        break
    

(3)效果预览:
在这里插入图片描述

2.工程应用

2.1 封装类

2.2 只检测指定类别的物体

(1)说明

(2)完整代码

import cv2
import numpy as np


cap=cv2.VideoCapture('object.mp4')# 可以设置为0,默认打开摄像头

classNames= []
classFile='coco.names'
with open(classFile,'rt') as f:
    classNames=f.read().rstrip('\n').split('\n')

modelConfiguration='yolov3.cfg'
modekWeights='yolov3.weights'
net=cv2.dnn.readNetFromDarknet(modelConfiguration,modekWeights)
net.setPreferableBackend(cv2.dnn.DNN_BACKEND_OPENCV)#to use opencv
net.setPreferableTarget(cv2.dnn.DNN_TARGET_CPU)#to use cpu

# detectLabels为指定只检测的物体名称列表
def findObjects(outputs,img,detectLabels=classNames):
    hT,wT,cT=img.shape
    bbox=[] 
    classIds=[]
    confs=[]

    for output in outputs:#3层结果
        for det in output:#每层检测结果
            scores=det[5:]  
            classId=np.argmax(scores)
            conf=scores[classId]
            if conf>0.5:
                w,h=int(det[2]*wT),int(det[3]*hT)
                x,y=int((det[0]*wT)-w/2),int((det[1]*hT)-h/2)#注意减去
                bbox.append([x,y,w,h])
                classIds.append(classId)
                confs.append(float(conf))

        indices=cv2.dnn.NMSBoxes(bbox,confs,0.5,0.4)

        for i in indices:
            # print(i)

            box=bbox[i]
            x,y,w,h=box
            label=classNames[classIds[i]]
            confidence=confs[i]
            if label in detectLabels:
                cv2.rectangle(img,(x,y),(x+w,y+h),(255,0,255),2)
                cv2.putText(img,f'{label} {confidence}',(x,y-10),cv2.FONT_HERSHEY_SIMPLEX,0.5,(255,0,255),2)
 


while True:
    success,img=cap.read()
    # blobFromImage主要是用来对图片进行预处理:分别是影像,缩放系数、输入图片的尺寸,图片整体减去的平均值,crop
    blob=cv2.dnn.blobFromImage(img,1/255,(320,320),[0,0,0],1,crop=False)

    net.setInput(blob)

    layerNames=net.getLayerNames()
 
    outputNames=[layerNames[i-1] for i in net.getUnconnectedOutLayers()]
    # print(outputNames)
    outputs=net.forward(outputNames)

    findObjects(outputs,img,['person'])

    cv2.imshow('Video',img)
    
    if cv2.waitKey(1) & 0xFF==ord('q'):
        break
    

(3)效果预览(只检测行人)
在这里插入图片描述
未完待续!!!

3.参考

(1)B站视频-08-YOLO-V3实时目标检测视频教程
(2)gitee代码仓库
(3)教程源地址cv zone(1)(2)均来自此正式教程。

  • 7
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
PythonOpenCV结合使用YOLO(You Only Look Once)可以实现目标检测和物体识别的功能。YOLO是一种基于深度学习的目标检测算法,它可以实时地在图像或视频中检测和定位多个对象。 要在Python中使用YOLO,首先需要安装OpenCVYOLO的相关库。可以使用pip命令来安装它们: ``` pip install opencv-python pip install opencv-contrib-python ``` 接下来,需要下载YOLO的权重文件和配置文件。YOLO有几个不同版本,可以根据需求选择不同的模型。一般来说,比较常用的是YOLOv3YOLOv4。 下载YOLOv3的权重文件和配置文件: ``` wget https://pjreddie.com/media/files/yolov3.weights wget https://github.com/pjreddie/darknet/blob/master/cfg/yolov3.cfg wget https://github.com/pjreddie/darknet/blob/master/data/coco.names ``` 下载YOLOv4的权重文件和配置文件: ``` wget https://github.com/AlexeyAB/darknet/releases/download/darknet_yolo_v3_optimal/yolov4.weights wget https://github.com/AlexeyAB/darknet/blob/master/cfg/yolov4.cfg wget https://github.com/AlexeyAB/darknet/blob/master/data/coco.names ``` 下载完毕后,可以使用下面的代码加载模型并进行目标检测: ```python import cv2 # 加载模型 net = cv2.dnn.readNet("yolov3.weights", "yolov3.cfg") # 加载类别标签 classes = [] with open("coco.names", "r") as f: classes = [line.strip() for line in f.readlines()] # 加载图像 image = cv2.imread("image.jpg") # 进行目标检测 blob = cv2.dnn.blobFromImage(image, 1/255, (416, 416), swapRB=True, crop=False) net.setInput(blob) outs = net.forward(net.getUnconnectedOutLayersNames()) # 解析检测结果 for out in outs: for detection in out: scores = detection[5:] classId = np.argmax(scores) confidence = scores[classId] if confidence > 0.5: centerX = int(detection[0] * width) centerY = int(detection[1] * height) w = int(detection[2] * width) h = int(detection[3] * height) x = int(centerX - w / 2) y = int(centerY - h / 2) cv2.rectangle(image, (x, y), (x + w, y + h), (0, 255, 0), 2) cv2.putText(image, classes[classId], (x, y - 5), cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 255, 0), 2) # 显示结果 cv2.imshow("Image", image) cv2.waitKey(0) cv2.destroyAllWindows() ``` 这段代码会加载YOLO模型和类别标签,然后读取一张图像,进行目标检测,并在图像中绘制检测结果的边界框和类别标签。最后,显示图像并等待按键退出。 请注意,上述代码只提供了一个基本的示例,实际应用中可能需要根据具体需求进行更多的调整和优化。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值