OpenCV 的 cv2.dnn
模块是 OpenCV 的 深度神经网络(Deep Neural Network)模块,用于在 无需安装 TensorFlow/PyTorch 的情况下,执行多种深度学习模型的推理任务。
一、cv2.dnn
能做什么?
可以用 cv2.dnn
加载来自主流框架的模型,支持的格式包括:
框架 | 函数 | 格式 |
---|---|---|
Caffe | readNetFromCaffe() | .prototxt + .caffemodel |
TensorFlow | readNetFromTensorflow() | .pb 或 .pbtxt |
ONNX | readNetFromONNX() | .onnx |
Darknet(YOLO) | readNetFromDarknet() | .cfg + .weights |
TorchScript(PyTorch) | readNet() | .pt |
二、典型用法(以 YOLOv3 为例)
import cv2
# 加载模型
net = cv2.dnn.readNetFromDarknet("yolov3.cfg", "yolov3.weights")
net.setPreferableBackend(cv2.dnn.DNN_BACKEND_OPENCV)
# 加载图像并转为 blob
image = cv2.imread("dog.jpg")
blob = cv2.dnn.blobFromImage(image, 1/255.0, (416, 416), swapRB=True, crop=False)
# 设定输入并前向传播
net.setInput(blob)
layer_names = net.getUnconnectedOutLayersNames()
outputs = net.forward(layer_names)
# 输出是多组目标的置信度和坐标
for output in outputs:
for detection in output:
scores = detection[5:]
class_id = scores.argmax()
confidence = scores[class_id]
if confidence > 0.5:
print(f"检测到类别 {class_id},置信度:{confidence:.2f}")
三、核心函数一览
函数 | 说明 |
---|---|
cv2.dnn.readNet() | 通用模型加载函数 |
readNetFromTensorflow() | 加载 TensorFlow 模型 |
readNetFromCaffe() | 加载 Caffe 模型 |
readNetFromDarknet() | 加载 YOLO 模型 |
readNetFromONNX() | 加载 ONNX 格式模型 |
blobFromImage() | 图像预处理:缩放、归一化、尺寸统一 |
setInput() | 设置模型输入 |
forward() | 前向传播,得到输出 |
cv2.dnn.blobFromImage()
在目标检测中的作用与用法
场景:使用 OpenCV + YOLOv3 进行目标检测
blobFromImage()
的主要功能是将图像 预处理成神经网络所需的输入格式(称为 blob):
-
归一化图像(比如除以 255)
-
调整尺寸(比如改为 416×416)
-
减去均值(如果模型有均值要求)
-
转换通道顺序(BGR→RGB)
示例代码:使用 blobFromImage() 处理输入
import cv2
import numpy as np
# 读取图像
image = cv2.imread("dog.jpg")
(H, W) = image.shape[:2]
# 将图像变成 DNN 所需的输入 blob
blob = cv2.dnn.blobFromImage(image,
scalefactor=1/255.0,
size=(416, 416),
mean=(0, 0, 0),
swapRB=True,
crop=False)
print("Blob shape:", blob.shape)
# 输出应为 (1, 3, 416, 416):1张图、3通道、高宽416
# 加载 YOLOv3 模型
net = cv2.dnn.readNetFromDarknet("yolov3.cfg", "yolov3.weights")
# 传入模型
net.setInput(blob)
outputs = net.forward(net.getUnconnectedOutLayersNames())
分析参数解释
blobFromImage(image,
scalefactor=1/255.0, # 像素归一化
size=(416, 416), # 输入尺寸
mean=(0, 0, 0), # 均值减去,无偏置
swapRB=True, # OpenCV 默认是 BGR,所以需交换
crop=False) # 不裁剪图像
为什么需要 blob?
深度学习模型通常要求:
-
图像尺寸统一
-
通道为 CHW 格式(而 OpenCV 默认是 HWC)
-
归一化数值
-
RGB 顺序
blobFromImage()
一步完成这些变换。否则你必须手动完成:
# 手动方式(不推荐)
image = cv2.resize(image, (416, 416))
image = image[:, :, ::-1] # BGR -> RGB
image = image.transpose(2, 0, 1) # HWC -> CHW
image = image.astype(np.float32) / 255.0
blob = np.expand_dims(image, axis=0)
可视化处理后图像(调试用)
# 还原 blob 图像用于显示(仅用于调试,不建议做预测)
blob_img = blob[0].transpose(1, 2, 0) # CHW -> HWC
blob_img = (blob_img * 255).astype(np.uint8)
cv2.imshow("Blob Image", blob_img)
cv2.waitKey(0)
cv2.destroyAllWindows()
四、显示预测结果(以人脸检测为例)
image = cv2.imread("face.jpg")
blob = cv2.dnn.blobFromImage(image, 1.0, (300, 300), (104.0, 177.0, 123.0))
net.setInput(blob)
detections = net.forward()
for i in range(detections.shape[2]):
confidence = detections[0, 0, i, 2]
if confidence > 0.5:
box = detections[0, 0, i, 3:7] * np.array([w, h, w, h])
(startX, startY, endX, endY) = box.astype("int")
cv2.rectangle(image, (startX, startY), (endX, endY), (0, 255, 0), 2)
五、应用场景
-
人脸检测(如
opencv_face_detector
) -
图像分类(如 MobileNet、ResNet)
-
实时目标检测(如 YOLOv3/v4、SSD)
-
姿态识别、车道检测、OCR 等