4. 使用OpenCV DNN模块部署SSD模型

任务目标

在车载AI座舱场景中,使用OpenCV DNN模块加载预训练的SSD(Single Shot MultiBox Detector)模型,对摄像头视频流中的车辆、行人、交通标志等目标进行实时检测,并在画面中绘制检测框与类别标签。

环境与依赖

  • OpenCV ≥ 4.5.0(需包含dnn模块)
  • Python ≥ 3.7
  • 模型文件:MobileNetSSD_deploy.caffemodel(约23MB)与 MobileNetSSD_deploy.prototxt,可从OpenCV官方示例仓库获取
  • 类别标签文件:class_labels.txt(包含20类目标名称,每行一个)

完整实现代码

import cv2
import numpy as np

# 配置参数
PROTOTXT = "MobileNetSSD_deploy.prototxt"
MODEL = "MobileNetSSD_deploy.caffemodel"
LABELS_FILE = "class_labels.txt"
CONF_THRESHOLD = 0.5  # 置信度阈值

# 加载类别标签
with open(LABELS_FILE, "r") as f:
    CLASSES = [line.strip() for line in f.readlines()]

# 加载SSD模型
net = cv2.dnn.readNetFromCaffe(PROTOTXT, MODEL)

def detect_objects(frame):
    """对单帧图像执行SSD目标检测,返回绘制后的图像"""
    (h, w) = frame.shape[:2]
    # 构建blob并输入网络
    blob = cv2.dnn.blobFromImage(frame, 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 > CONF_THRESHOLD:
            idx = int(detections[0, 0, i, 1])
            box = detections[0, 0, i, 3:7] * np.array([w, h, w, h])
            (x1, y1, x2, y2) = box.astype("int")

            label = f"{CLASSES[idx]}: {confidence:.2f}"
            cv2.rectangle(frame, (x1, y1), (x2, y2), (0, 255, 0), 2)
            cv2.putText(frame, label, (x1, y1 - 10),
                        cv2.FONT_HERSHEY_SIMPLEX, 0.6, (0, 255, 0), 2)
    return frame

def main():
    # 打开摄像头(0为默认摄像头,车载场景可改为视频文件路径)
    cap = cv2.VideoCapture(0)
    if not cap.isOpened():
        print("错误:无法打开摄像头")
        return

    print("按 'q' 键退出检测")
    while True:
        ret, frame = cap.read()
        if not ret:
            print("错误:无法读取视频帧")
            break

        result = detect_objects(frame)
        cv2.imshow("Vehicle SSD Detection", result)

        if cv2.waitKey(1) & 0xFF == ord('q'):
            break

    cap.release()
    cv2.destroyAllWindows()

if __name__ == "__main__":
    main()

运行方式

  1. 将上述代码保存为 ssd_detection.py,确保模型文件、prototxt文件和标签文件位于同一目录。
  2. 创建 class_labels.txt,内容为SSD MobileNet模型输出的20类标签(每行一个):
    background, aeroplane, bicycle, bird, boat, bottle, bus, car, cat, chair, cow, diningtable, dog, horse, motorbike, person, pottedplant, sheep, sofa, train, tvmonitor
  3. 终端执行:python ssd_detection.py

验证方法

  • 启动验证:程序启动后摄像头画面窗口出现,标题为"Vehicle SSD Detection",说明模型加载成功。
  • 检测验证:将车辆、行人或常见物体置于摄像头视野内,观察是否出现绿色检测框及类别标签。当目标置信度超过0.5时,应能正确识别并标注。
  • 性能观察:画面无明显卡顿(帧率≥15 FPS),说明模型可在车载计算平台上实时运行。
  • 退出验证:按下键盘 q 键,程序正常退出且无报错。

关键说明

  • 模型输入尺寸固定为300×300,blobFromImage 中的缩放系数0.007843和均值127.5是SSD MobileNet的标准预处理参数,不可随意更改。
  • 检测结果 detections 的维度为 [1, 1, N, 7],其中N为最大检测框数量(此处为200),每个检测框包含:批次号、类别索引、置信度、x1、y1、x2、y2(归一化坐标)。
  • 若需处理视频文件而非摄像头,将 cv2.VideoCapture(0) 替换为视频文件路径即可,其余逻辑不变。