OpenCV 的 DNN(Deep Neural Network)

OpenCV 的 DNN(Deep Neural Network)模块是一个强大的工具,可以用来加载和运行预训练的深度学习模型,包括目标检测模型(如 YOLO、SSD 等)。它不需要额外的深度学习框架(如 PyTorch 或 TensorFlow),只需 OpenCV 本身即可推理,非常适合轻量级应用或与 OpenCV 的图像处理功能结合使用。

以下是关于 OpenCV DNN 模块的详细说明,以及如何使用它来实现目标检测(以 YOLOv3 为例)。


特点

  • 支持多种模型格式:可以加载 Caffe、TensorFlow、Darknet(YOLO)、ONNX 等格式的模型。
  • 跨平台:支持 CPU 和 GPU(需编译支持 CUDA)。
  • 轻量:无需安装额外的深度学习框架。
  • 与 OpenCV 集成:方便与图像处理、视频流等功能结合。

安装

确保你安装了 OpenCV 的 Python 包。如果需要 GPU 支持,需自行编译 OpenCV 并启用 CUDA。

bash 复制代码
pip install opencv-python  # 基本版本(CPU)
# 或
pip install opencv-contrib-python  # 包含更多功能

检查版本:

python 复制代码
import cv2
print(cv2.__version__)  # 例如 4.9.0

使用 OpenCV DNN 运行 YOLOv3 示例

以下是一个使用 OpenCV DNN 模块加载 YOLOv3 模型并进行目标检测的完整示例:

准备工作
  1. 下载 YOLOv3 的配置文件和权重文件:

    • yolov3.cfg:模型配置文件(从 Darknet GitHub 或官方网站下载)。
    • yolov3.weights:预训练权重文件(约 200MB)。
    • coco.names:COCO 数据集的类别名称文件(包含 80 个类,如 "person"、"car" 等)。

    你可以从以下链接获取:

sh 复制代码
 wget https://pjreddie.com/media/files/yolov3.weights
 wget https://github.com/pjreddie/darknet/raw/master/cfg/yolov3.cfg
 wget https://github.com/pjreddie/darknet/raw/master/data/coco.names

windows:

sh 复制代码
  # 下载 yolov3.weights
Invoke-WebRequest -Uri "https://pjreddie.com/media/files/yolov3.weights" -OutFile "yolov3.weights"

# 下载 yolov3.cfg
Invoke-WebRequest -Uri "https://github.com/pjreddie/darknet/raw/master/cfg/yolov3.cfg" -OutFile "yolov3.cfg"

# 下载 coco.names
Invoke-WebRequest -Uri "https://github.com/pjreddie/darknet/raw/master/data/coco.names" -OutFile "coco.names"
  1. 将这些文件保存在你的项目目录中。
代码示例
python 复制代码
import cv2
import numpy as np

# 加载 YOLOv3 模型
net = cv2.dnn.readNetFromDarknet('yolov3.cfg', 'yolov3.weights')
net.setPreferableBackend(cv2.dnn.DNN_BACKEND_OPENCV)
net.setPreferableTarget(cv2.dnn.DNN_TARGET_CPU)  # 或 DNN_TARGET_CUDA 如果有 GPU 支持

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

# 获取输出层名称
layer_names = net.getLayerNames()
output_layers = [layer_names[i - 1] for i in net.getUnconnectedOutLayers()]

# 打开摄像头
cap = cv2.VideoCapture(0)  # 0 表示默认摄像头

while True:
    # 读取视频帧
    ret, frame = cap.read()
    if not ret:
        break

    # 准备输入图像
    height, width = frame.shape[:2]
    blob = cv2.dnn.blobFromImage(frame, 1/255.0, (416, 416), swapRB=True, crop=False)
    net.setInput(blob)

    # 前向传播
    outputs = net.forward(output_layers)

    # 处理检测结果
    boxes = []
    confidences = []
    class_ids = []

    for output in outputs:
        for detection in output:
            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)

    # 非极大值抑制(NMS)去重
    indices = cv2.dnn.NMSBoxes(boxes, confidences, 0.5, 0.4)

    # 绘制检测结果
    for i in indices:
        box = boxes[i]
        x, y, w, h = box
        label = str(classes[class_ids[i]])
        confidence = confidences[i]
        color = (0, 255, 0)  # 绿色
        cv2.rectangle(frame, (x, y), (x + w, y + h), color, 2)
        cv2.putText(frame, f"{label} {confidence:.2f}", (x, y - 10), 
                    cv2.FONT_HERSHEY_SIMPLEX, 0.5, color, 2)

        # 判断是否检测到人
        if class_ids[i] == 0:  # COCO 数据集中 'person' 的 ID 是 0
            print("Person detected!")

    # 显示结果
    cv2.imshow('YOLOv3 Detection', frame)

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

# 释放资源
cap.release()
cv2.destroyAllWindows()

代码说明

  1. 加载模型

    • cv2.dnn.readNetFromDarknet 加载 Darknet 格式的 YOLOv3 模型。
    • 你可以选择 DNN_TARGET_CPUDNN_TARGET_CUDA(需编译支持)。
  2. 输入预处理

    • blobFromImage 将图像转换为 YOLO 所需的格式(416x416 是 YOLOv3 的默认输入大小)。
  3. 输出处理

    • YOLO 输出多个尺度(3 个输出层),需要解析边界框、置信度和类别。
    • 使用 NMS(非极大值抑制)去除重叠框。
  4. 判断检测到人

    • 检查 class_ids[i] == 0,因为 COCO 数据集中 "person" 的类别 ID 是 0。
  5. 可视化

    • cv2.rectanglecv2.putText 绘制边界框和标签。

优点

  • 无需额外深度学习框架,依赖少。
  • 与 OpenCV 的其他功能(如视频处理、图像滤波)无缝集成。
  • 支持多种模型格式,灵活性高。

缺点

  • 推理速度可能不如 PyTorch 或 TensorFlow 原生实现(尤其在 GPU 上)。
  • 不支持直接训练模型,仅用于推理。
  • 配置 GPU 支持需要手动编译 OpenCV。

支持的其他模型

除了 YOLO,你还可以用 OpenCV DNN 加载:

  • SSD (Single Shot MultiBox Detector):cv2.dnn.readNetFromCaffe
  • Faster R-CNN:从 TensorFlow 或 ONNX 加载。
  • ONNX 模型cv2.dnn.readNetFromONNX
相关推荐
综合热讯1 分钟前
股票融资融券交易时间限制一览与制度说明
大数据·人工智能·区块链
AEIC学术交流中心2 分钟前
【快速EI检索 | ICPS出版】2026年计算机技术与可持续发展国际学术会议(CTSD 2026)
人工智能·计算机网络
玄同7654 分钟前
Python Random 模块深度解析:从基础 API 到 AI / 大模型工程化实践
人工智能·笔记·python·学习·算法·语言模型·llm
风指引着方向5 分钟前
昇腾 AI 开发生产力工具:CANN CLI 的高级使用与自动化脚本编写
运维·人工智能·自动化
算法狗26 分钟前
大模型面试题:1B的模型和1T的数据大概要训练多久
人工智能·深度学习·机器学习·语言模型
23遇见11 分钟前
CANN与开源生态:如何融入并赋能主流AI框架的NPU后端支持
人工智能
工程师老罗12 分钟前
YOLOv1数据增强
人工智能·yolo
大模型真好玩14 分钟前
中美大模型“内战”都怎么打!一文详解Claude Opus 4.6和GPT-5.3 CodeX核心特性
人工智能·agent·deepseek
啊森要自信15 分钟前
CANN ops-cv:揭秘视觉算子的硬件感知优化与内存高效利用设计精髓
人工智能·深度学习·架构·transformer·cann
西部秋虫16 分钟前
迷你视频会议系统(FlashMeeting)
opencv·ffmpeg·视频会议·回声抑制