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
相关推荐
九亿AI算法优化工作室&1 分钟前
SA模拟退火算法优化高斯回归回归预测matlab代码
人工智能·python·算法·随机森林·matlab·数据挖掘·模拟退火算法
Blossom.1186 分钟前
基于Python的机器学习入门指南
开发语言·人工智能·经验分享·python·其他·机器学习·个人开发
默 语1 小时前
10分钟打造专属AI助手!ToDesk云电脑/顺网云/海马云操作DeepSeek哪家强?
人工智能·电脑·todesk
Donvink3 小时前
【Dive Into Stable Diffusion v3.5】2:Stable Diffusion v3.5原理介绍
人工智能·深度学习·语言模型·stable diffusion·aigc·transformer
宇灵梦3 小时前
大模型金融企业场景落地应用
人工智能
lsrsyx3 小时前
中信银行太原长治路支行赴老年活动服务中心开展专题金融知识宣讲
大数据·人工智能
烟锁池塘柳04 小时前
【深度学习】Self-Attention机制详解:Transformer的核心引擎
人工智能·深度学习·transformer
Matrix_114 小时前
论文阅读:Self-Supervised Video Defocus Deblurring with Atlas Learning
人工智能·计算摄影
你觉得2057 小时前
天津大学第二讲:《深度解读DeepSeek:部署、使用、安全》|附PPT下载方法
大数据·人工智能·安全·机器学习·ai·知识图谱·内容运营
不加冰的红茶要热的7 小时前
【机器学习】什么是决策树?
人工智能·决策树·机器学习