物体检测实战:使用 OpenCV 进行 YOLO 对象检测
项目由4个目录和2个Python脚本组成,包括用于物体检测的Yolo-coco文件夹、用于评估的图像文件夹、用于评估的视频文件夹、评估结果文件夹,以及用于视频检测的yolovideo.py脚本。Yolo-coco文件夹包含YOLOv3模型、COCO类标签文件和训练权重文件。yolovideo.py脚本用于从视频中检测物体,主要包含导入库、定义参数、加载模型、读取视频流、处理视频帧并进行检测的代码。
$ tree
.
├── images
│ └── 11.jpg
├── output
│ └── output.avi
├── videos
│ └── overpass.mp4
├── yolo-coco
│ ├── coco.names
│ ├── yolov3.cfg
│ └── yolov3.weights
├── yolo.py
└── yolo_video.py
我们今天的项目由 4 个目录和两个 Python 脚本组成。
目录(按重要性排序)是:
yolo-coco目录:YOLOv3物体检测模型模型
images文件夹:存放用于评估的图像。
videos文件夹 :存放用于评估的视频
output: 评估后的结果。
yolo.py:评估图像
yolo_video.py :评估视频
===============================================================
新建文件yolo_objectdetection.py
import the necessary packages
import numpy as np
import argparse
import time
import cv2
import os
image_path=‘11.jpg’
yolo=‘yolo_coco’
confidence_t=0.5
threshold=0.3
加载训练 YOLO 模型的 COCO 类标签
labelsPath = os.path.sep.join([yolo, “coco.names”])
LABELS = open(labelsPath).read().strip().split(“\n”)
初始化一个颜色列表来表示每个类标签
np.random.seed(42)
COLORS = np.random.randint(0, 255, size=(len(LABELS), 3),
dtype=“uint8”)
YOLO 对象检测
print(“[INFO] loading YOLO from disk…”)
config_path = ‘./yolo_coco/yolov3.cfg’
weights_path = ‘./yolo_coco/yolov3.weights’
net = cv2.dnn.readNetFromDarknet(config_path, weights_path)
导入包。
定义全局参数:
image_path:定义图片的路径。
yolo:定义模型存放的路径
confidence_t:过滤弱检测的最小概率。
threshold:非最大值抑制阈值。
接下来,加载了所有的类 LABELS。然后,为每个标签分配随机颜色。
加载权重文件。
加载我们的输入图像并获取其空间维度
image = cv2.imread(image_path)
(H, W) = image.shape[:2]
从输入图像构建一个blob,然后执行一个前向传播
通过 YOLO 对象检测器,输出边界框和相关概率
blob = cv2.dnn.blobFromImage(image, 1 / 255.0, (416, 416),
swapRB=True, crop=False)
net.setInput(blob)
start = time.time()
获取网络输出层信息(所有输出层的名字),设定并前向传播
outInfo = net.getUnconnectedOutLayersNames()
得到各个输出层的、各个检测框等信息,是二维结构。
layerOutputs = net.forward(outInfo)
加载输入图像并提取其尺寸。
从 YOLO 模型取出输出层名称。
构建一个 blob(第 48 和 49 行)。
cv2.dnn.blobFromImage(image[, scalefactor[, size[, mean[, swapRB[, crop[, ddepth]]]]]])
作用:
对图像进行预处理,具体包括减去均值、按比例缩放、裁剪处理以及调整通道顺序等操作,最终输出一个四通道的blob结构,该blob可以视为一个N维数组,用于神经网络的输入。
参数:
- image:输入图像(1、3或者4通道)
可选参数
- scalefactor:图像各通道数值的缩放比例
- size:输出图像的空间尺寸,如size=(200,300)表示高h=300,宽w=200
mean:各通道减去的均值,用于减少光照带来的影响。例如,当image为bgr三通道图像时,mean=[104.0, 177.0, 123.0],表示b通道值减去104,g通道减去177,r通道减去123。
- swapRB:交换RB通道,默认为False.(cv2.imread读取的是彩图是bgr通道)
裁剪参数设置为False,表示不进行裁剪操作。当裁剪参数设置为True时,首先会按比例缩放图像,然后从中心位置裁剪至指定尺寸。
- ddepth:输出的图像深度,可选CV_32F 或者 CV_8U.
通过我们的 YOLO 网络执行前向传递
显示 YOLO 的推理时间
接下来我们实现图像的可视化操作:
分别初始化检测到的边界框、置信度和类 ID 的列表
boxes = []
confidences = []
classIDs = []
循环输出
for output in layerOutputs:
遍历每个检测结果
for detection in output:
提取物体检测的类ID和置信度(即概率)
scores = detection[5:]
classID = np.argmax(scores)
confidence = scores[classID]
过滤精度低的结果
if confidence > confidence_t:
延展边界框坐标,计算 YOLO 边界框的中心 (x, y) 坐标,然后是框的宽度和高度
该代码通过从detection数组中提取前四个元素并将其缩放为[ W, H, W, H ]的尺寸来生成box变量。
(centerX, centerY, width, height) = box.astype(“int”)
使用中心 (x, y) 坐标导出边界框的上角和左角
x = int(centerX - (width / 2))
y = int(centerY - (height / 2))
更新边界框坐标、置信度和类 ID 列表
boxes.append([x, y, int(width), int(height)])
confidences.append(float(confidence))
classIDs.append(classID)
使用非极大值抑制来抑制弱的、重叠的边界框
idxs = cv2.dnn.NMSBoxes(boxes, confidences, confidence_t,
threshold)
确保至少存在一个检测
if len(idxs) > 0:
遍历我们保存的索引
for i in idxs.flatten():
提取边界框坐标
(x, y) = (boxes[i][0], boxes[i][1])
(w, h) = (boxes[i][2], boxes[i][3])
在图像上绘制一个边界框矩形和标签
color = [int© 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)
初始化列表:
box :我们围绕对象的边界框。
置信度:YOLO 系统赋予目标对象的置信度值。较低的置信度值意味着目标可能并非网络所识别的那样。请记住查看命令行参数,我们将排除置信度低于0.5的对象。
classIDs :检测到的对象的类标签。
循环遍历每个 layerOutputs。
循环输出中的每个检测项。
提取 classID 和置信度。
过滤掉弱检测项。
到这里已经得到了高精度的检测项,然后:
延展边界框坐标,以便可以在原始图像上正确显示它们。
该算法用于计算边界框的位置和尺寸。YOLO 采用以下形式表示边界框坐标:(中心点坐标,宽度和高度)。
使用此信息计算出边界框的左上角 (x, y) 坐标。
更新 box 、 confidences 和 classIDs 列表。
然后使用NMS过滤冗余和无关的边界框。
接下主要将结果绘制到图片上。
运行结果:

===============================================================
我们现在已经掌握了如何将YOLO应用于单个图像。接下来,我们将在视频流或摄像头中进行进一步探索。
新建 yolo_video.py 文件并插入以下代码:
import numpy as np
import imutils
import time
import cv2
import os
yolo = ‘yolo_coco’
confidence_t = 0.5
threshold = 0.3
output = ‘output.avi’
导入需要的包
定义全局参数:
yolo:定义模型存放的路径
confidence_t:过滤弱检测的最小概率。
threshold:非最大值抑制阈值。
output:输出的视频结果
导入YOLO训练数据集的COCO类标签
labelsPath = os.path.sep.join([yolo, “coco.names”])
LABELS = open(labelsPath).read().strip().split(“\n”)
初始化颜色列表
np.random.seed(42)
COLORS = np.random.randint(0, 255, size=(len(LABELS), 3), dtype=“uint8”)
配置 YOLO 权重和模型配置的路径
weightsPath = os.path.sep.join([yolo, “yolov3.weights”])
configPath = os.path.sep.join([yolo, “yolov3.cfg”])
在COCO数据集(支持80个类别)上训练的YOLO模型加载,并获取YOLO输出层的名称信息。
net = cv2.dnn.readNetFromDarknet(configPath, weightsPath)
获取网络输出层信息(所有输出层的名字),设定并前向传播
outInfo = net.getUnconnectedOutLayersNames()
初始化视频流、指向输出视频文件的指针和帧尺寸
vs = cv2.VideoCapture(0)
writer = None
(W, H) = (None, None)
获取文件的总帧数。
try:
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
这段代码的步骤:
读取类别。
给每个类别初始化颜色。
设置YOLO权重文件的路径。
加载YOLO权重文件。
获取输出层信息。
初始化VideoCapture对象。
初始化视频编写器和帧尺寸。
获取总帧数,以便估计处理整个视频需要多长时间。
loop over frames from the video file stream
自我简述,我于1993年毕业于上海交通大学,曾在小公司工作过,后曾在华为、OPPO等知名企业工作过,自1998年加入阿里巴巴,迄今已工作至今。
普遍发现,大多数Python工程师在渴望提升专业能力时,常见的学习方式包括自主学习和参加培训课程。然而,高昂的学费往往让人望而却步。自学虽能积累经验,但缺乏系统性,学习效果往往不佳且耗时较长。容易在技术瓶颈面前停滞不前。
为了收集整理一套2024年Python开发全套学习资料,我本人的初衷也很简单,就是希望能够帮助那些想自学提升但又不知道从何学起的朋友,同时减轻他们的负担。






不仅为零基础学习者准备的基础课程,还为资深开发者深入学习的高级课程,几乎涵盖了前端开发知识点的95%以上,系统化地构建了完整的知识体系!
因为文件较大,仅对目录大纲进行部分截图展示,每个节点包含有大厂面经、学习笔记、源码讲义、实战项目、讲解视频,并会持续更新。
如果你觉得这些内容对你有帮助,可以扫码获取!!!(备注:Python)
一套学习资料,其初衷也很简单,旨在帮助那些想自学提升却不知从何入手的朋友,同时减轻大家的学习负担。
[外链图片转存中…(img-cuCHoaS4-1713800751144)]
[外链图片转存中…(img-MbEsNEfn-1713800751145)]
[外链图片转存中…(img-vH8dyCfb-1713800751146)]
[外链图片转存中…(img-Sv6tR70s-1713800751148)]


课程资源既涵盖了适合小白入门学习的零基础材料,也提供了3年以上经验专业人员深入提升的高级内容,覆盖了95%以上的前端知识点,系统性强。
因为文件较大,我们仅对目录大纲进行部分截图展示,每个节点都涵盖大厂面经、学习笔记、源码讲义、实战项目及讲解视频,同时后续内容也会持续更新。
如果你觉得这些内容对你有帮助,可以扫码获取!!!(备注:Python)

