赞
踩
(1)YOLO是一个开源的目标检测算法,兼顾准确率和运行速度,本笔记主要用YOLO-V3进行图像 or 摄像头视频或者下载视频的目标检测。
(2)检测流程:
(3)YOLO-V3的网络配置文件以及对应的模型权重文件下载:YOLO配置以及权重文件下载链接
注意:FPS表示视频显示帧率,即一秒中图像数量,越大表示视频显示越流畅,下载的模型为YOLOv3-320,下载cfg模型配置文件(加载网络结构)+weights(模型权重文件)两个。
此外由于该模型是在COCO上面下载的,一共有80类,需要导入其类别文件,方面后续绘制出类别名称,类别如下:
(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)效果预览:
(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)效果预览(只检测行人)
未完待续!!!
(1)B站视频-08-YOLO-V3实时目标检测视频教程
(2)gitee代码仓库
(3)教程源地址cv zone(1)(2)均来自此正式教程。
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。