基于opencv的yolov3模型实现目标检测

一、概述

        本文是使用pycharm,利用opencv的dnn模块实现yolov3的目标检测。本人是初学者,为了记录自己的学习过程和对该项目理解更加深刻才写的,可能有许多不足的地方,欢迎各位大佬批评指正,如果本文章有侵权,请联系我。

二、yolov3模型简单介绍

yolov3是由大佬JosephRedmon和AliFarhadi发明提出来的,它包含了FPN、anchor锚框和darknet-53等优秀的算法。其他具体网络结构与原理本文不赘述,如果想要了解该网络的具体原理可以参考yolov3的论文。地址:https://arxiv.org/pdf/1804.02767

三、准备工作

首先需要到yolo的官网下载weight和cfg。

官网地址为:https://pjreddie.com/darknet/yolo/#google_vignette

然后需要下载coco.names数据集

地址:分享文件:coco.names
链接:https://pan.xunlei.com/s/VO4rrAnkPngJkALRsafKzULeA1#
提取码:brn8
coco所对应标签有

person
bicycle
car
motorbike
aeroplane
bus
train
truck
boat
traffic light
fire hydrant
stop sign
parking meter
bench
bird
cat
dog
horse
sheep
cow
elephant
bear
zebra
giraffe
backpack
umbrella
handbag
tie
suitcase
frisbee
skis
snowboard
sports ball
kite
baseball bat
baseball glove
skateboard
surfboard
tennis racket
bottle
wine glass
cup
fork
knife
spoon
bowl
banana
apple
sandwich
orange
broccoli
carrot
hot dog
pizza
donut
cake
chair
sofa
pottedplant
bed
diningtable
toilet
tvmonitor
laptop
mouse
remote
keyboard
cell phone
microwave
oven
toaster
sink
refrigerator
book
clock
vase
scissors
teddy bear
hair drier
toothbrush

四、代码以及效果图

前面的准备好了,开始上代码了

"""
author: XiaoShu
date: 2024-08-22
"""
import cv2
import numpy as np
import time

# video = '1.mp4'
# cap = cv2.VideoCapture(video)  # 视频识别
cap = cv2.VideoCapture(0)  # 调用本地摄像头进行识别
classPath = 'coco.names'
classNames = []
confThreshold = 0.5
nmsThreshold = 0.3
ctime = 0
ftime = 0

with open(classPath, 'rt') as f:
    classNames = f.read().rstrip('\n').split('\n')

modelConfiguration = 'yolov3.cfg'
modelWeights = 'yolov3.weights'

# 创建自己的网络,加载DNN模型
net = cv2.dnn.readNetFromDarknet(modelConfiguration, modelWeights)  # 读取模型配置和权重模型
net.setPreferableBackend(cv2.dnn.DNN_BACKEND_CUDA)  # 声明opencv是作为后端
net.setPreferableTarget(cv2.dnn.DNN_TARGET_CUDA)  # 声明使用cpu



def findObjects(outputs, img):
    hT, wT, cT = img.shape  # 把图片的高、宽、通道分别赋值到hT, wT, cT
    bbox = []  # 边界框列表
    classIds = []  # 类别列表
    confs = []  # 置信度列表
    for output in outputs:  # 遍历三个输出层
        for det in output:
            scores = det[5:]  # 删除前面五个值,前五个值分别是图片中物体的宽、长、原点坐标的百分比
            classId = np.argmax(scores)
            confidence = scores[classId]
            if confidence > confThreshold:  # 如果置信大于置信阈值
                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(confidence))
    
    indices = cv2.dnn.NMSBoxes(bbox, confs, confThreshold, nmsThreshold)  # 非最大抑制的名义删除重复框,
    
    for i in indices:
        box = bbox[i]
        x, y, w, h = box[0], box[1], box[2], box[3]
        cv2.rectangle(img, (x, y), (x + w, y + h), (0, 0, 255), 2)
        cv2.putText(img, f'{classNames[classIds[i]]} {int(confs[i] * 100)}%',
                    (x, y - 10), cv2.FONT_HERSHEY_SIMPLEX, 0.6, (255, 0, 255), 2)


# 调用电脑摄像头进行识别或者视频识别, 空格退出
while True:
    res, img = cap.read()
    """函数说明:blob = cv2.dnn.blobFromImage(image, scalefactor=1.0, size, mean, swapRB=True,crop=False,ddepth = CV_32F )
输入:
image:需要进行处理的图像。
scalefactor:执行完减均值后,需要缩放图像,默认是1。
size:输出图像的空间尺寸,如size=(200,300)表示高h=300,宽w=200。
mean:要减去的均值,可以是R,G,B均值三元组,或者是一个值,每个通道都减这值。如果执行减均值,通道顺序是R、G、B。 如果,输入图像通道顺序是B、G、R,那么请确保swapRB = True,交换通道。
swapRB:OpenCV认为图像通道顺序是B、G、R,而减均值时顺序是R、G、B,为了解决这个矛盾,设置swapRB=True即可。
crop:图像裁剪,默认为False.当值为True时,先按比例缩放,然后从中心裁剪成size尺寸。
ddepth:输出blob的深度,可选CV_32F or CV_8U。
返回值:
返回一个4通道的blob(blob可以简单理解为一个N维的数组,用于神经网络的输入。
"""
    blob = cv2.dnn.blobFromImage(img, 1 / 255, (320, 320), [0, 0, 0], 1, crop=False)
    # blob = cv2.dnn.blobFromImage(img, 1 / 255, (320, 320), [0, 0, 0], 1, crop=True)
    net.setInput(blob)  # blob作为图片输入
    layersNames = net.getLayerNames()  # 获取网络所有图层的名称
    out_layer_names = []
    for i in net.getUnconnectedOutLayers():
        out_layer_names.append(layersNames[i - 1])
    outputs = net.forward(out_layer_names)  # 向前预测
    findObjects(outputs, img)
    ctime = time.time()
    fps = 1 / (ctime - ftime)
    ftime = ctime
    cv2.putText(img, f"FPS:{int(fps)}", (30, 50), cv2.FONT_HERSHEY_DUPLEX, 1, (255, 0, 0), 2)
    cv2.imshow('img', img)
    if cv2.waitKey(1) == ord(' '):
        break
cap.release()
cv2.destroyAllWindows()

# # 图片识别, 空格退出
# img1 = cv2.imread('1.jfif')
# blob = cv2.dnn.blobFromImage(img1, 1 / 255, (320, 320), [0, 0, 0], 1, crop=True)
# net.setInput(blob)  # blob作为图片输入
# layersNames = net.getLayerNames()  # 获取网络所有图层的名称
# out_layer_names = []
# for i in net.getUnconnectedOutLayers():
#     out_layer_names.append(layersNames[i - 1])
# outputs = net.forward(out_layer_names)  # 向前预测
# findObjects(outputs, img1)
# cv2.imshow('img', img1)
# if cv2.waitKey(0) == ord(' '):
#     exit()
# cv2.destroyAllWindows()

图片检测

视频检测

调用本地摄像头进行识别

  • 4
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
OpenCV YOLOv3是一种基于深度学习的目标检测算法,可以用于检测图像中的物体。你可以使用OpenCV的DNN模块来加载YOLOv3的网络配置和训练的权重文件,并构建一个网络来进行目标检测。\[2\] 使用OpenCV的DNN模块加载YOLOv3的网络配置和权重文件非常方便,而且可以轻松地整合到现有的OpenCV程序中。这样就不需要担心Darknet源代码的编译和构建。此外,OpenCV的DNN模块在CPU上的运算速度比Darknet+OpenMP快9倍。举个例子,当用了OpenMP的Darknet在CPU上处理一张图片需要2秒,而OpenCV实现只需要0.22秒。同时,OpenCV也支持Python,而Darknet只支持C语言。因此,使用OpenCV的DNN模块可以提供支持Darknet的编程接口。\[3\] 如果你想了解更多关于OpenCV YOLOv3的信息,可以参考这篇文章:https://www.learnopencv.com/deep-learning-based-object-detection-using-yolov3-with-opencv-python-c/。\[1\] #### 引用[.reference_title] - *1* *3* [基于OpenCVYOLOv3深度学习的目标检测](https://blog.csdn.net/qq_27158179/article/details/81915740)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* [opencv调用yolov3模型进行目标检测,以实例进行代码详解](https://blog.csdn.net/qq_32761549/article/details/90402438)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值