在本章节代码编写中,发现之前的代码所处的环境是python3,因此导致了cv2.dnn.readNetFromDarknet()在代码运行中导致了i[0]的获值失败,故总结如下:

cv2.dnn.readNetFromDarknet()在python3上遇到的问题_李大狗的读研日记-CSDN博客问题描述:代码如下net = cv2.dnn.readNetFromDarknet(configPath,weightsPath)#获取YOLO每一层的名称#getLayerNames():获取网络所有层的名称。ln = net.getLayerNames()# 获取输出层的名称: [yolo-82,yolo-94,yolo-106]# getUnconnectedOutLayers():获取输出层的索引ln = [ln[i[0] - 1] for i in net.getUnconnhttps://blog.csdn.net/qq_39237205/article/details/121344325

正片如下


在这里我们进行的目标检测是基于OPenCV的利用yoloV3进行目标检测,不涉及yoloV3的模型结构、理论及训练过程,只是利用训练好的模型进行目标检测,整个流程如下:

基于OPenCV中的DNN模块

  • 加载已训练好的yolov3模型及其权重参数
  • 将要处理的图像转换成输入到模型中的blobs
  • 利用模型对目标进行检测
  • 遍历检测结果
  • 应用非极大值抑制
  • 绘制最终检测结果,并存入到ndarray中,供目标追踪使用。

代码如下:

1.加载yolov3模型及其权重参数

# 1.加载可以识别物体的名称,将其存放在LABELS中,一共有80种,在这我们只使用car
labelsPath = "./yolo-coco/coco.names"
LABELS = open(labelsPath).read().strip().split("\n")# 设置随机数种子,生成多种不同的颜色,当一个画面中有多个目标时,使用不同颜色的框将其框起来
np.random.seed(42)
COLORS = np.random.randint(0, 255, size=(200, 3),dtype="uint8")# 加载已训练好的yolov3网络的权重和相应的配置数据
weightsPath = "./yolo-coco/yolov3.weights"
configPath = "./yolo-coco/yolov3.cfg"# 加载好数据之后,开始利用上述数据恢复yolo神经网络
net = cv2.dnn.readNetFromDarknet(configPath, weightsPath)
# 获取YOLO中每一网络层的名称:['conv_0', 'bn_0', 'relu_0', 'conv_1', 'bn_1', 'relu_1', 'conv_2', 'bn_2', 'relu_2'...]
ln = net.getLayerNames()
# 获取输出层在网络中的索引位置,并以列表的形式:['yolo_82', 'yolo_94', 'yolo_106']
ln = [ln[i[0] - 1] for i in net.getUnconnectedOutLayers()]

2.要处理的图像转换成输入到模型中的blobs

# 2. 读取图像
frame = cv2.imread("./images/car1.jpg")
# 视频的宽度和高度,即帧尺寸
(W, H) = (None, None)
if W is None or H is None:(H, W) = frame.shape[:2]# 根据输入图像构造blob,利用OPenCV进行深度网路的计算时,一般将图像转换为blob形式,对图片进行预处理,包括缩放,减均值,通道交换等
# 还可以设置尺寸,一般设置为在进行网络训练时的图像的大小
blob = cv2.dnn.blobFromImage(frame, 1 / 255.0, (416, 416), swapRB=True, crop=False)

3.利用模型对目标进行检测

# 3.将blob输入到前向网络中,并进行预测
net.setInput(blob)
start = time.time()
# yolo前馈计算,获取边界和相应的概率
# 输出layerOutsputs介绍:
# 是YOLO算法在图片中检测到的bbx的信息
# 由于YOLO v3有三个输出,也就是上面提到的['yolo_82', 'yolo_94', 'yolo_106']
# 因此layerOutsputs是一个长度为3的列表
# 其中,列表中每一个元素的维度是(num_detection, 85)
# num_detections表示该层输出检测到bbx的个数
# 85:因为该模型在COCO数据集上训练,[5:]表示类别概率;[0:4]表示bbx的位置信息;[5]表示置信度
layerOutputs = net.forward(ln)

4.遍历检测结果,获得检测框

# 下面对网络输出的bbx进行检查:
# 判定每一个bbx的置信度是否足够的高,以及执行NMS算法去除冗余的bbxboxes = []  # 用于存放识别物体的框的信息,包括框的左上角横坐标x和纵坐标y以及框的高h和宽w
confidences = []  # 表示识别目标是某种物体的可信度
classIDs = []  # 表示识别的目标归属于哪一类,['person', 'bicycle', 'car', 'motorbike'....]# 4. 遍历每一个输出层的输出
for output in layerOutputs:# 遍历某个输出层中的每一个目标for detection in output:scores = detection[5:]  # 当前目标属于某一类别的概率classID = np.argmax(scores)  # 目标的类别IDconfidence = scores[classID]  # 得到目标属于该类别的置信度# 只保留置信度大于0.3的边界框,若图片质量较差,可以将置信度调低一点if confidence > 0.3:# 将边界框的坐标还原至与原图片匹配,YOLO返回的是边界框的中心坐标以及边界框的宽度和高度box = detection[0:4] * np.array([W, H, W, H])(centerX, centerY, width, height) = box.astype("int") # 使用 astype("int") 对上述 array 进行强制类型转换,centerX:框的中心点横坐标, centerY:框的中心点纵坐标,width:框的宽度,height:框的高度x = int(centerX - (width / 2))  # 计算边界框的左上角的横坐标y = int(centerY - (height / 2))  # 计算边界框的左上角的纵坐标# 更新检测到的目标框,置信度和类别IDboxes.append([x, y, int(width), int(height)])  # 将边框的信息添加到列表boxesconfidences.append(float(confidence))  # 将识别出是某种物体的置信度添加到列表confidencesclassIDs.append(classID) # 将识别物体归属于哪一类的信息添加到列表classIDs

5.非极大值抑制

# 5. 非极大值抑制
idxs = cv2.dnn.NMSBoxes(boxes, confidences, 0.5, 0.3)

6.最终检测结果,绘制,并存入到ndarray中,供目标追踪使用

# 6. 获得最终的检测结果
dets = []  # 存放检测框的信息,包括左上角横坐标,纵坐标,右下角横坐标,纵坐标,以及检测到的物体的置信度,用于目标跟踪
if len(idxs) > 0:  # 存在检测框的话(即检测框个数大于0)for i in idxs.flatten():  #  循环检测出的每一个box# yolo模型可以识别很多目标,因为我们在这里只是识别车,所以只有目标是车的我们进行检测,其他的忽略if LABELS[classIDs[i]] == "car":(x, y) = (boxes[i][0], boxes[i][1])  # 得到检测框的左上角坐标(w, h) = (boxes[i][2], boxes[i][3])  # 得到检测框的宽和高cv2.rectangle(frame, (x, y), (x+w, y+h), (0,255,0), 2)  # 将方框绘制在画面上dets.append([x, y, x + w, y + h, confidences[i]])  # 将检测框的信息的放入dets中
# 设置数据类型,将整型数据转换为浮点数类型,且保留小数点后三位
np.set_printoptions(formatter={'float': lambda x: "{0:0.3f}".format(x)})
# 将检测框数据转换为ndarray,其数据类型为浮点型
dets = np.asarray(dets)plt.imshow(frame[:,:,::-1])

在视频中进行目标检测:

labelsPath = "./yolo-coco/coco.names"
LABELS = open(labelsPath).read().strip().split("\n")# 设置随机数种子,生成多种不同的颜色,当一个画面中有多个目标时,使用不同颜色的框将其框起来
np.random.seed(42)
COLORS = np.random.randint(0, 255, size=(200, 3),dtype="uint8")# 加载已训练好的yolov3网络的权重和相应的配置数据
weightsPath = "./yolo-coco/yolov3.weights"
configPath = "./yolo-coco/yolov3.cfg"# 加载好数据之后,开始利用上述数据恢复yolo神经网络
net = cv2.dnn.readNetFromDarknet(configPath, weightsPath)
# 获取YOLO中每一网络层的名称:['conv_0', 'bn_0', 'relu_0', 'conv_1', 'bn_1', 'relu_1', 'conv_2', 'bn_2', 'relu_2'...]
ln = net.getLayerNames()
# 获取输出层在网络中的索引位置,并以列表的形式:['yolo_82', 'yolo_94', 'yolo_106']
ln = [ln[i[0] - 1] for i in net.getUnconnectedOutLayers()]"""
视频处理类
"""# 初始化vediocapture类,参数指定打开的视频文件,也可以是摄像头
vs = cv2.VideoCapture('./input/test_1.mp4')
# 视频的宽度和高度,即帧尺寸
(W, H) = (None, None)
# 视频文件写对象
writer = Nonetry:# 确定获取视频帧数的方式prop = cv2.cv.CV_CAP_PROP_FRAME_COUNT if imutils.is_cv2() \else cv2.CAP_PROP_FRAME_COUNT# 获取视频的总帧数total = int(vs.get(prop))# 打印视频的帧数print("[INFO] {} total frames in video".format(total))
except:print("[INFO] could not determine # of frames in video")print("[INFO] no approx. completion time can be provided")total = -1# 循环读取视频中的每一帧画面
while True:# 读取帧:grabbed是bool,表示是否成功捕获帧,frame是捕获的帧(grabbed, frame) = vs.read()# 若未捕获帧,则退出循环if not grabbed:break# 若W和H为空,则将第一帧画面的大小赋值给他if W is None or H is None:(H, W) = frame.shape[:2]# 根据输入图像构造blob,利用OPenCV进行深度网路的计算时,一般将图像转换为blob形式,对图片进行预处理,包括缩放,减均值,通道交换等# 还可以设置尺寸,一般设置为在进行网络训练时的图像的大小blob = cv2.dnn.blobFromImage(frame, 1 / 255.0, (416, 416), swapRB=True, crop=False)# 将blob输入到前向网络中net.setInput(blob)start = time.time()# yolo前馈计算,获取边界和相应的概率layerOutputs = net.forward(ln)"""输出layerOutsputs介绍:是YOLO算法在图片中检测到的bbx的信息由于YOLO v3有三个输出,也就是上面提到的['yolo_82', 'yolo_94', 'yolo_106']因此layerOutsputs是一个长度为3的列表其中,列表中每一个元素的维度是(num_detection, 85)num_detections表示该层输出检测到bbx的个数85:因为该模型在COCO数据集上训练,[5:]表示类别概率;[0:4]表示bbx的位置信息;[5]表示置信度"""end = time.time()"""下面对网络输出的bbx进行检查:判定每一个bbx的置信度是否足够的高,以及执行NMS算法去除冗余的bbx"""boxes = []  # 用于存放识别物体的框的信息,包括框的左上角横坐标x和纵坐标y以及框的高h和宽wconfidences = []  # 表示识别目标是某种物体的可信度classIDs = []  # 表示识别的目标归属于哪一类,['person', 'bicycle', 'car', 'motorbike'....]# 遍历每一个输出层的输出for output in layerOutputs:# 遍历某个输出层中的每一个目标for detection in output:scores = detection[5:]  # 当前目标属于某一类别的概率"""# scores = detection[5:] ---> [0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.#                                 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.#                               0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0. 0.#                                 0. 0. 0. 0. 0. 0. 0. 0.]# scores的大小应该是1*80,因为在训练yolo模型时是80类目标"""classID = np.argmax(scores)  # 目标的类别IDconfidence = scores[classID]  # 得到目标属于该类别的置信度# 只保留置信度大于0.3的边界框,若图片质量较差,可以将置信度调低一点if confidence > 0.3:# 将边界框的坐标还原至与原图片匹配,YOLO返回的是边界框的中心坐标以及边界框的宽度和高度box = detection[0:4] * np.array([W, H, W, H])(centerX, centerY, width, height) = box.astype("int") # 使用 astype("int") 对上述 array 进行强制类型转换,centerX:框的中心点横坐标, centerY:框的中心点纵坐标,width:框的宽度,height:框的高度x = int(centerX - (width / 2))  # 计算边界框的左上角的横坐标y = int(centerY - (height / 2))  # 计算边界框的左上角的纵坐标# 更新检测到的目标框,置信度和类别IDboxes.append([x, y, int(width), int(height)])  # 将边框的信息添加到列表boxesconfidences.append(float(confidence))  # 将识别出是某种物体的置信度添加到列表confidencesclassIDs.append(classID) # 将识别物体归属于哪一类的信息添加到列表classIDs# 上一步中已经得到yolo的检测框,但其中会存在冗余的bbox,即一个目标对应多个检测框,所以使用NMS去除重复的检测框# 利用OpenCV内置的NMS DNN模块实现即可实现非最大值抑制 ,所需要的参数是边界 框、 置信度、以及置信度阈值和NMS阈值# 第一个参数是存放边界框的列表,第二个参数是存放置信度的列表,第三个参数是自己设置的置信度,第四个参数是关于threshold(阈值# 返回的idxs是一个一维数组,数组中的元素是保留下来的检测框boxes的索引位置idxs = cv2.dnn.NMSBoxes(boxes, confidences, 0.5, 0.3)dets = []  # 存放检测框的信息,包括左上角横坐标,纵坐标,右下角横坐标,纵坐标,以及检测到的物体的置信度,用于目标跟踪if len(idxs) > 0:  # 存在检测框的话(即检测框个数大于0)for i in idxs.flatten():  #  循环检测出的每一个box# yolo模型可以识别很多目标,因为我们在这里只是识别车,所以只有目标是车的我们进行检测,其他的忽略if LABELS[classIDs[i]] == "car":(x, y) = (boxes[i][0], boxes[i][1])  # 得到检测框的左上角坐标(w, h) = (boxes[i][2], boxes[i][3])  # 得到检测框的宽和高dets.append([x, y, x + w, y + h, confidences[i]])  # 将检测框的信息的放入dets中# 设置数据类型,将整型数据转换为浮点数类型,且保留小数点后三位np.set_printoptions(formatter={'float': lambda x: "{0:0.3f}".format(x)})# 将检测框数据转换为ndarray,其数据类型为浮点型dets = np.asarray(dets)

总结

基于OPenCV的DNN模块利用yoloV3模型进行目标检测:

  • 加载已训练好的yolov3模型及其权重参数
  • 将要处理的图像转换成输入到模型中的blobs
  • 利用模型对目标进行检测
  • 遍历检测结果,应用非极大值抑制
  • 绘制最终检测结果,并存入到ndarray中,供目标追踪使用。

yolo.py 【实现对图片的目标检测】

# encoding:utf-8import imutils
import time
import cv2
import numpy as np
import matplotlib.pyplot as plt
#利用yolov3模型进行目标检测
#加载模型相关信息
#加载可以检测的目标的类型#labelPath:类别标签文件的路径
labelPath = "./yolo-coco/coco.names"# 加载类别标签文件
LABELS = open(labelPath).read().strip().split("\n")#生成多种不同的颜色的检测框 用来标注物体
np.random.seed(42)
COLORS = np.random.randint(0,255,size=(200,3),dtype='uint8')#加载预训练的模型:权重 配置信息、进行恢复模型
#weights_path:模型权重文件的路径
weightsPath = "./yolo-coco/yolov3.weights"
#configPath:模型配置文件的路径
configPath = "./yolo-coco/yolov3.cfg"net = cv2.dnn.readNetFromDarknet(configPath,weightsPath)
#获取YOLO每一层的名称
#getLayerNames():获取网络所有层的名称。
ln = net.getLayerNames()
# 获取输出层的名称: [yolo-82,yolo-94,yolo-106]
# getUnconnectedOutLayers():获取输出层的索引
ln = [ln[i[0] - 1] for i in net.getUnconnectedOutLayers()]#图像的读取
frame = cv2.imread('./images/car1.jpg')
(W,H)=(None,None)
(H,W)=frame.shape[:2]# 将图片构建成一个blob,设置图片尺寸,然后执行一次前向传播
# YOLO前馈网络计算,最终获取边界框和相应概率
blob = cv2.dnn.blobFromImage(frame,1/255.0,(416,416),swapRB=True,crop=False)
#将blob送入网络
net.setInput(blob)
start = time.time()
#前向传播,进行预测,返回目标框的边界和响应的概率
layerOutouts = net.forward(ln)
end = time.time()#存放目标的检测框
boxes = []
#置信度
confidences = []
#目标类别
classIDs = []# 迭代每个输出层,总共三个
for output in layerOutouts:#遍历每个检测结果for detection in output:# 提取类别ID和置信度#detction:1*85 [5:]表示类别,[0:4]bbox的位置信息 [5]置信度、可信度scores = detection[5:]classID = np.argmax(scores)confidence= scores[classID]# 只保留置信度大于某值的边界框if confidence >0.3:# 将边界框的坐标还原至与原图片相匹配,记住YOLO返回的是边界框的中心坐标以及边界框的宽度和高度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)# 更新目标框,置信度(概率)以及类别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)
#检测框的结果:左上角坐标、右下角坐标
dets = []# 确保至少有一个边界框
if len(idxs)>0:# 迭代每个边界框for i in idxs.flatten():# 提取边界框的坐标if LABELS[classIDs[i]] == "car":(x,y)=(boxes[i][0],boxes[i][1])(w,h)=(boxes[i][2],boxes[i][3])cv2.rectangle(frame,(x,y),(x+w,y+h),(0,255,0),2)dets.append([x,y,x+w,y+h,confidences[i]])
# 类型设置
np.set_printoptions(formatter={'float': lambda x: "{0:0.3f}".format(x)})
dets = np.asarray(dets)#显示
plt.imshow(frame[:,:,::-1])
plt.show()

结果显示:

智慧交通day02-车流量检测实现12:基于yoloV3的目标检测相关推荐

  1. yolov3为什么对大目标检测不好_【目标检测简史】进击的YOLOv3,目标检测网络的巅峰之作...

    YOLOv3的前世今生 2013年,R-CNN横空出世,目标检测DL世代大幕拉开. 各路豪杰快速迭代,陆续有了SPP,fast,faster版本,至R-FCN,速度与精度齐飞,区域推荐类网络大放异彩. ...

  2. 基于yolov3的目标检测与LPRnet字符识别的车牌识别(CCPD2020新能源车牌数据集)

    文章目录 前言 一.程序思路 二.使用步骤 1.配置环境 2.文件结构 3.准备数据集 4.训练 有问题欢迎指正 前言 项目放这:车牌识别 基于python和pytorch平台,使用CCPD2020新 ...

  3. 目标检测—基于Yolov3的目标检测项目实战(学习笔记)

    最近在学习tensorflow,尝试运行学习了github上基于yolov3的一个目标检测项目,此算法可对视频.图片.摄像头实时进行检测,本文主要讲述了,在windows电脑上,复现这一目标检测项目的 ...

  4. MATLAB基于形态学的目标检测(一)简单图形统计

    (目标检测)MATLAB基于形态学的目标检测(一)简单图形统计 一.生成测试图像 二.连通区域目标统计 三.结合形态学 总结 by HPC_ZY 本文主要介绍二值形态学在目标检测上的用法, 就不讲形态 ...

  5. 深度神经网络在基于视觉的目标检测中的应用

    简 介: 目标检测是计算机视觉的一个重要应用方向,深度神经网络的提出极大地帮助基于视觉的目标检测提高了准确度.自2014年以来,深度神经网络在基于视觉的目标检测中被广泛应用,出现了多种算法.本文分别讨 ...

  6. 基于YOLOv4的目标检测系统(附MATLAB代码+GUI实现)

    摘要:本文介绍了一种MATLAB实现的目标检测系统代码,采用 YOLOv4 检测网络作为核心模型,用于训练和检测各种任务下的目标,并在GUI界面中对各种目标检测结果可视化.文章详细介绍了YOLOv4的 ...

  7. 基于YOLOv5的目标检测系统详解(附MATLAB GUI版代码)

    摘要:本文重点介绍了基于YOLOv5目标检测系统的MATLAB实现,用于智能检测物体种类并记录和保存结果,对各种物体检测结果可视化,提高目标识别的便捷性和准确性.本文详细阐述了目标检测系统的原理,并给 ...

  8. 自动驾驶采标系列三:基于图像的目标检测技术

        标注猿的第54篇原创        一个用数据视角看AI世界的标注猿    上一篇文章我们从"环境感知"数据的采集设备上进行了详细说明,已经了解了相应设备采集的数据及采集前 ...

  9. 10分钟内基于gpu的目标检测

    10分钟内基于gpu的目标检测 Object Detection on GPUs in 10 Minutes 目标检测仍然是自动驾驶和智能视频分析等应用的主要驱动力.目标检测应用程序需要使用大量数据集 ...

最新文章

  1. mysql添加外键报错:ERROR 1215 (HY000): Cannot add foreign key constrain
  2. 王者荣耀服务器响应超时,“团战”打游戏,为什么你的网络信号总是连接超时?...
  3. Windows PE 第十三章 PE补丁技术
  4. Java容器集合类的区别用法
  5. 授权码模式-获取令牌
  6. 【MySql】MySql存储,游标,循环的简单使用
  7. Global.asax 文件
  8. 各国“未雨绸缪”致网络安全陷入困境 安全防御诱发“防御性入侵”
  9. 201771010112罗松《面向对象程序设计(java)》第十周学习总结
  10. Flexsim 强化学习
  11. VueUse中文文档Vue官方工具库
  12. 弹弹堂手游语音服务器怎么连接,腾讯弹弹堂手游空间怎么进去 互动玩法攻略介绍...
  13. FDTD PDMS光学参数txt文档
  14. python 拆分pdf
  15. 三星6818LED驱动的编写
  16. javascript广告漂浮效果代码
  17. 高级中学计算机配置标准,江苏省高级中学艺术装备标准
  18. 学习总结1-跟开涛学SpringMVC
  19. 地铁AFC付出体式格局近况及移动付出安好性探究
  20. 怎么把安卓手机便签小工具添加到手机桌面显示呢?

热门文章

  1. Flask爱家租房--发布新房源(保存房屋基本信息)
  2. python email模块详解_python模块之email: 电子邮件编码解码 (一、解码邮件)
  3. 如何root安卓手机_安卓Root+卡开机画面救砖教程丨以一加手机为例
  4. php mysql删除失败_php+MySQL实战案例【七】数据编辑、删除
  5. tornado学习笔记day02-进阶与提升
  6. 解决:关于Git无法提交 index.lock File exists的问题
  7. 机器学习之必知开源数据集
  8. boost Mutex
  9. 博客地址 RSS地址
  10. 驱动框架3——在内核中添加或去除某个驱动