计算机视觉进阶教学之DNN模块
目录
一、DNN模块
1.DNN模块是什么
2.DNN 模块的特点
3.DNN 模块使用的主要函数及流程
二、代码实现
1. 导入库和读取图像
2. 图像预处理(转换为神经网络输入格式)
3. 加载风格迁移模型
4. 模型推理与结果处理
5.DNN摄像头实现
一、DNN模块
1.DNN模块是什么
DNN模块是 OpenCV 中专门用来实现 DNN(Deep Neural Networks,深度神经网络) 模块的相关功能,其作用是载入别的深度学习框架(如 TensorFlow、Caffe、Torch 等)中已经训练好的模型,然后用该模型完成预测等工作。
2.DNN 模块的特点
● 轻量: OpenCV 的深度学习模块只实现了模型推理功能,不涉及模型训练,这使得相关程序非常精简,加速了安装和编译过程。
● 外部依赖性低:重新实现一遍深度学习框架使得 DNN 模块对外部依赖性极低,极大地方便了深度学习应用的部署。
● 方便:在原有 OpenCV 开发程序的基础上,通过 DNN 模块可以非常方便地加入对神经网络推理的支持。
● 集成:若网络模型来自多个框架,如一个来自 TensorFlow,另外一个来自 Caffe,则 DNN 模块可以方便地对网络进行整合。
● 通用性:DNN 模块提供了统一的接口来操作网络模型,内部做的优化和加速适用于所有网络模型格式,支持多种设备和操作系统。
3.DNN 模块使用的主要函数及流程
图像预处理的功能:
将需要处理的图像转换成可以传入人工神经网络的数据形式。 DNN 模块中的函数blobFromlmage 完成图像预处理,从原始图像构建一个符合人工神经网络输入格式的四维块。 它通过调整图像尺寸和裁图像、减均值、按比例因子缩放、交换 B 通道和R通道等可选操作完成对图像的预处理,得到符合人工神经网络输入的目标值。
二、代码实现
这段代码使用 OpenCV 的 dnn 模块实现了图像风格迁移功能,具体是将输入图像转换为梵高《星月夜》的艺术风格。
1. 导入库和读取图像
import cv2
# 读取输入图像
image = cv2.imread('xiaolizi.jpg')
# 将图像缩小一半(fx和fy是缩放因子)
image = cv2.resize(image, dsize=None, fx=0.5, fy=0.5)
# 显示原始图像
cv2.imshow('yuan tu', image)
cv2.waitKey(0) # 等待用户按键继续
这部分代码加载图像并进行初步处理,将图像缩小以提高处理速度,并显示原始图像。
2. 图像预处理(转换为神经网络输入格式)
(h, w) = image.shape[:2] # 获取图像高度和宽度
# 将图像转换为神经网络需要的blob格式
blob = cv2.dnn.blobFromImage(image, scalefactor=1, # 像素值缩放因子size=(w, h), # 输出图像尺寸mean=(0, 0, 0), # 每个通道减去的均值(这里不减去任何值)swapRB=False, # 是否交换B和R通道(OpenCV默认BGR格式)crop=False # 是否裁剪图像
)
cv2.dnn.blobFromImage()
是关键函数,它将普通图像转换为深度学习模型所需的输入格式:
- 输出是一个四维数组(B, C, H, W)
- B: 批次大小(这里为 1)
- C: 通道数(彩色图像为 3)
- H, W: 图像高度和宽度
3. 加载风格迁移模型
# 加载预训练的风格迁移模型(这里使用的是星空风格模型)
net = cv2.dnn.readNet("model\starry_night.t7") # 这是一个PyTorch训练的模型
OpenCV 的 dnn 模块支持多种深度学习框架的模型,这里加载的是一个 Torch 格式(.t7)的预训练风格迁移模型,能够将普通图像转换为《星月夜》风格。
这个可以从网上自己去下载
4. 模型推理与结果处理
# 将预处理好的blob输入到网络
net.setInput(blob)
# 进行前向传播,得到输出结果
out = net.forward()# 处理输出结果
# 重塑形状:将4维(B, C, H, W)转换为3维(C, H, W)
out_new = out.reshape(out.shape[1], out.shape[2], out.shape[3])
# 归一化处理:将像素值调整到[0,1]范围
cv2.normalize(out_new, out_new, norm_type=cv2.NORM_MINMAX)
# 转置维度:将(C, H, W)转换为(H, W, C),符合OpenCV的图像格式
result = out_new.transpose(1, 2, 0)# 显示风格迁移后的图像
cv2.imshow('Stylized Image', result)
cv2.waitKey(0)
整体流程总结
- 读取并预处理输入图像(缩放)
- 将图像转换为神经网络所需的 blob 格式
- 加载预训练的风格迁移模型
- 进行模型推理得到风格化结果
- 处理输出结果使其符合图像显示格式
- 显示原始图像和风格化后的图像
5.DNN摄像头实现
# coding: utf-8
import cv2
def cv_show(name, img):cv2.imshow(name, img)cv2.waitKey(60)cap = cv2.VideoCapture(0) # 确保摄像头是可以启动的状态
if not cap.isOpened(): # 打开失败print("Cannot open camera")exit()while True:flag = 0 # 用于标识 当前是否检测到文档ret, image = cap.read() # 从摄像头读取每一帧图像,如果正确读取帧,ret为True,image为读取到的帧图像orig = image.copy() # 对每一帧做副本if not ret: # 读取失败,则退出循环print("不能读取摄像头")breakcv_show("image", image) # 展示读取到的帧画面(h, w) = image.shape[:2]blob = cv2.dnn.blobFromImage(image, scalefactor=1, size=(w, h), mean=(0, 0, 0), swapRB=False, crop=False)net = cv2.dnn.readNet("model\starry_night.t7")net.setInput(blob)out = net.forward()out_new = out.reshape(out.shape[1], out.shape[2], out.shape[3])# 对输入的数据(或图像)进行归一化处理,使其数值范围在指定的范围内cv2.normalize(out_new, out_new, norm_type=cv2.NORM_MINMAX)# 转置输出结果的维度result = out_new.transpose(1, 2, 0)# 显示转换后的图像cv2.imshow('Stylized Image', result)cv2.waitKey(60)
整体功能总结
这段代码实现了一个实时风格迁移效果:
- 打开摄像头并捕获实时画面
- 同时显示原始画面和经过《星月夜》风格迁移处理的画面
- 每帧画面显示 60 毫秒,形成流畅的视频效果