15 目标检测之YOLO与SSD

目标检测是计算机视觉中的一个重要任务,涉及到在图片或视频中识别和定位多个对象。近年来,随着深度学习技术的快速发展,基于深度学习的目标检测方法得到了广泛的应用。其中,YOLO(You Only Look Once)和 SSD(Single Shot MultiBox Detector)是两个非常流行且高效的方法。在本篇教程中,我们将详细探讨这两种检测算法,包括它们的原理、实现以及如何在 OpenCV 中使用它们。

YOLO(You Only Look Once)

YOLO 是一种基于卷积神经网络(CNN)的实时目标检测系统。这种方法的主要思想是将整个图像作为网络的输入,并在单个前向传播中同时进行目标的定位和分类。与传统的目标检测方法不同,YOLO 将检测问题转化为回归问题。

YOLO 的工作原理

YOLO 将输入图像划分为 S x S 的网格,每个网格负责预测一个边界框和对应的类概率。每个网格单元输出的信息包括:

  • 边界框的中心坐标 $(x, y)$
  • 边界框的宽度和高度 $(w, h)$
  • 某个类的置信度 $P(Class)$

最终,YOLO 会通过 Non-Maximum Suppression(NMS)来整理重叠的边界框,保留最高置信度的边框,得到最终的检测结果。

在 OpenCV 中实现 YOLO

下面是如何在 OpenCV 中使用 YOLO 进行目标检测的简单示例。

1. 下载 YOLO 模型

首先,你需要下载 YOLO 的权重和配置文件。你可以从 YOLO 官方 GitHub 页面下载:

  • yolov3.weights
  • yolov3.cfg
  • coco.names(类名文件)

2. 代码示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
import cv2
import numpy as np

# 加载 YOLO 模型
net = cv2.dnn.readNet("yolov3.weights", "yolov3.cfg")
layer_names = net.getLayerNames()
output_layers = [layer_names[i[0] - 1] for i in net.getUnconnectedOutLayers()]

# 加载类名
with open("coco.names", "r") as f:
classes = [line.strip() for line in f.readlines()]

# 加载图片
img = cv2.imread("image.jpg")
height, width, _ = img.shape

# 创建输入Blob
blob = cv2.dnn.blobFromImage(img, 0.00392, (416, 416), (0, 0, 0), True, crop=False)
net.setInput(blob)

# 进行前向传播
outs = net.forward(output_layers)

# 解析输出
boxes = []
confidences = []
class_ids = []

for out in outs:
for detection in out:
scores = detection[5:]
class_id = np.argmax(scores)
confidence = scores[class_id]
if confidence > 0.5: # 设置阈值
# 获取边界框坐标
center_x = int(detection[0] * width)
center_y = int(detection[1] * height)
w = int(detection[2] * width)
h = int(detection[3] * height)

# 边界框的左上角坐标
x = int(center_x - w / 2)
y = int(center_y - h / 2)

boxes.append([x, y, w, h])
confidences.append(float(confidence))
class_ids.append(class_id)

# 应用非极大抑制
indexes = cv2.dnn.NMSBoxes(boxes, confidences, 0.5, 0.4)

# 绘制检测结果
for i in range(len(boxes)):
if i in indexes:
x, y, w, h = boxes[i]
label = str(classes[class_ids[i]])
confidence = confidences[i]
cv2.rectangle(img, (x, y), (x + w, y + h), (0, 255, 0), 2)
cv2.putText(img, f"{label} {round(confidence, 2)}", (x, y + 30), cv2.FONT_HERSHEY_PLAIN, 2, (0, 255, 0), 3)

# 显示结果
cv2.imshow("Image", img)
cv2.waitKey(0)
cv2.destroyAllWindows()

在上面的代码中,我们使用 OpenCV 的 dnn 模块来加载 YOLO 模型,进行目标检测并绘制出检测到的边界框和标签。

SSD(Single Shot MultiBox Detector)

SSD 是另一种流行的目标检测方法,能够以较高的速度和准确性进行检测。与 YOLO 相似,SSD 也将目标检测问题视为一个回归问题。

SSD 的工作原理

SSD 在不同的特征图上进行检测,并使用默认边界框进行预测。它通过在多层特征图上进行卷积操作,提取多尺度信息以提高检测效果。SSD 可以在添加较少的计算负担的情况下,达到较高的召回率和精度。

在 OpenCV 中实现 SSD

与 YOLO 类似,你同样可以在 OpenCV 中使用 SSD 模型进行目标检测。在运行 SSD 的代码之前,请确保你已经下载了对应的模型文件,比如 SSD MobileNet 或其他类型的 SSD 模型。

代码示例

import cv2

# 加载 SSD 模型
net = cv2.dnn.readNetFromCaffe("deploy.prototxt", "mobilenet.caffemodel")

# 加载图片
img = cv2.imread("image.jpg")
height, width, _ = img.shape

# 创建输入Blob
blob = cv2.dnn.blobFromImage(img, 0.007843, (300, 300), 127.5)
net.setInput(blob)

# 进行前向传播
detections = net.forward()

# 解析输出
for i in range(detections.shape[2]):
    confidence = detections[0, 0, i, 2]
    if confidence > 0.5:  # 设置阈值
        class_id = int(detections[0, 0, i, 1])
        box = detections[0, 0, i, 3:7] * np.array([width, height, width, height])
        (startX, startY, endX, endY) = box.astype("int")

        # 绘制检测结果
        label

15 目标检测之YOLO与SSD

https://zglg.work/opencv-tutorial/15/

作者

IT教程网(郭震)

发布于

2024-08-13

更新于

2024-08-13

许可协议

分享转发

交流

更多教程加公众号

更多教程加公众号

加入星球获取PDF

加入星球获取PDF

打卡评论