【进阶OpenCV】 (11)--DNN板块--实现风格迁移

embedded/2024/10/22 8:50:10/

文章目录

  • DNN板块
    • 一、DNN特点
    • 二、DNN函数流程
    • 三、实现风格迁移
      • 1. 图像预处理
      • 2. 加载星空模型
      • 3. 输出处理
  • 总结

DNN板块

DNN模块是 OpenCV 中专门用来实现 DNN(Deep Neural Networks,深度神经网络) 模块的相关功能,其作用是载入别的深度学习框架(如 TensorFlow、Caffe、Torch 等)中已经训练好的模型,然后用该模型完成预测等工作。

DNN进行风格迁移是一项基于深度学习技术的图像处理方法,它允许将一张图片(风格图)中的风格、纹理迁移到另一张图片(内容图)上,同时保留内容图原有的主体结构。

一、DNN特点

  • 轻量: OpenCV 的深度学习模块只实现了模型推理功能,不涉及模型训练,这使得相关程序非常精简,加速了安装和编译过程。
  • 外部依赖性低:重新实现一遍深度学习框架使得 DNN 模块对外部依赖性极低,极大地方便了深度学习应用的部署。
  • 方便:在原有 OpenCV 开发程序的基础上,通过 DNN 模块可以非常方便地加入对神经网络推理的支持。
  • 集成:若网络模型来自多个框架,如一个来自 TensorFlow,另外一个来自 Caffe,则 DNN 模块可以方便地对网络进行整合。
  • 通用性:DNN 模块提供了统一的接口来操作网络模型,内部做的优化和加速适用于所有网络模型格式,支持多种设备和操作系统。

二、DNN函数流程

在这里插入图片描述

  • 图像预处理

将需要处理的图像转换成可以传入人工神经网络的数据形式

DNN 模块中的函数 blobFromlmage 完成图像预处理,从原始图像构建一个符合人工神经网络输入格式的四维块。它通过调整图像尺寸和裁图像、减均值、按比例因子缩放、交换 B 通道和R通道等可选操作完成对图像的预处理,得到符合人工神经网络输入的目标值。

三、实现风格迁移

基本原理:风格迁移的实现通常基于卷积神经网络(CNNs),尤其是预训练的卷积神经网络(如VGG网络)。使用这些网络,可以提取内容图像的内容特征和风格图像的风格特征。这通常涉及到在网络的不同层次上计算特征表示。然后,定义一个损失函数,该函数包括内容损失和风格损失两个部分。内容损失用于确保生成图像与内容图像相似,而风格损失则用于确保生成图像的风格与风格图像匹配。通过最小化损失函数,使用梯度下降或其他优化方法来调整生成图像的像素值,使损失最小化,从而导致生成图像逐渐融合内容和风格。

接下来我们尝试将以下图片转化为星空风格

在这里插入图片描述

1. 图像预处理

对于图像的预处理,我们需要通过cv2.dnn.blobFromImage()函数来将图像转换成可以传入人工神经网络的数据形式:

blob = cv2.dnn.blobFromImage(image, scalefactor, size, mean, swapRB=True, crop=False)

参数

-- image (必需):要转换的图像,通常是一个通过 OpenCV 读取的彩色或灰度图像。
-- scalefactor (必需):图像缩放因子。这个值用于调整图像的像素值范围,通常设置为 1.0(不缩放)。
-- size (必需):输出 blob 的空间尺寸(宽度,高度)。这个值应该与你要使用的预训练模型的输入尺寸相匹配。
-- mean (可选):从每个通道中减去的均值。这通常用于数据标准化,以便模型能够更好地处理输入数据。对于预训练的模型,这个值通常是固定	的,并且可以在模型的文档中找到。
-- swapRB (可选):是否交换红色和蓝色通道。
-- crop (可选):是否在预处理过程中裁剪图像。

预处理

import cv2
"""-----图片预处理-----"""
# 读取输入图像
image = cv2.imread('tu.jpg')
# 显示输入图像
cv2.imshow('yuan_tu',image)
cv2.waitKey(0)(h,w) = image.shape[:2] # 获取图像尺寸
blob = cv2.dnn.blobFromImage(image,1,(w,h),(0,0,0),swapRB = True,crop = False)

2. 加载星空模型

通过cv2.dnn.readNet()函数加载模型,通过**net.setInput()设置输入,然后通过net.forward()**进行前向传播得到输出:

net = cv2.dnn.readNet(r'model\starry_night.t7') # 得到一个pytorch训练后的星空模型# 设置神经网络的输入
net.setInput(blob)
# 对输入图片进行前向传播,得到输出结果
out = net.forward()

3. 输出处理

将输出结果转换为合适的格式,out是四维的:B*C*H*W(B:batch图像数量(通常为1);C:channels通道数;H:height高度;W:width宽度)。

所以我们需要重塑形状(忽略第一维),4维变3维,调整输出out的形状,模型推理输出out是四维BCHW形式的,调整为三维CHW形式。

# 重塑形状
out_new = out.reshape(out.shape[1],out.shape[2],out.shape[3])
# 对输入的数组(或图像)进行归一化处理,使其数值范围在指定的范围内
cv2.normalize(out_new,out_new,norm_type=cv2.NORM_MINMAX)
# 转置输出结果的维度,将通道维度移动到了最后,因为OpenCV期望图像以HWC格式显示。
result = out_new.transpose(1,2,0)
# 显示转换后的图像
cv2.imshow('Stylized Image',result)
cv2.waitKey(0)
cv2.destroyAllWindows()

在这里插入图片描述

总结

本篇介绍了,如何通过DNN板块进行风格迁移。

注意!!!:进行风格迁移时,需要将传入的图片转换成可以传入人工神经网络的数据形式。且输出时进行转置,将通道维度移动到了最后,因为OpenCV期望图像以HWC格式显示。


http://www.ppmy.cn/embedded/129512.html

相关文章

判断大小端

这个代码可以用来判断电脑字节序储存方(电脑储存方式由硬件决定),下面我们来看代码 那么今天分享就到这里,谢谢大家!

基于SpringBoot+Vue+uniapp微信小程序的社区门诊管理系统的详细设计和实现(源码+lw+部署文档+讲解等)

项目运行截图 技术框架 后端采用SpringBoot框架 Spring Boot 是一个用于快速开发基于 Spring 框架的应用程序的开源框架。它采用约定大于配置的理念,提供了一套默认的配置,让开发者可以更专注于业务逻辑而不是配置文件。Spring Boot 通过自动化配置和约…

【Linux】:线程概念

朋友们、伙计们,我们又见面了,本期来给大家带来线程概念相关代码和知识点,如果看完之后对你有一定的启发,那么请留下你的三连,祝大家心想事成! C 语 言 专 栏:C语言:从入门到精通 数…

【计算机网络】localhost,127.0.0.1 和 0.0.0.0傻傻分不清?这篇文章带你认识

一句话总结,127.0.0.1 用于本地测试,只能由本机访问,localhost 是映射到127.0.0.1 的域名;而 0.0.0.0 用于使服务对所有网络接口可见,可以被其他计算机访问。 关系解释 127.0.0.1 这是一个特殊的IP地址,…

java List<Map<String, Object>> 转 List<JSONObject> 的几种方式

目录 方法一&#xff1a;使用传统循环 方法二&#xff1a;使用 Java 8 的流&#xff08;Stream&#xff09;API 方法三&#xff1a;使用 Guava 库 总结 将 List<Map<String, Object>> 转换为 List<JSONObject> 有多种方法。以下是几种常见的方法&#xf…

Docker设置日志滚动

问题描述 Docker 容器中的进程会将打印到控制台(console)的日志保存到容器的目录下&#xff0c;默认的 Docker 配置不带有日志的回滚。会在自己的容器目录下往同一个日志文件中不停写入&#xff0c;最后会导致磁盘空间占满的问题。 解决方案 方案一&#xff1a;全局范围内修…

时间数据可视化基础实验——Python实现

【实验名称】 实验一:时间数据的可视化 【实验目的】 1.掌握时间数据在大数据中的应用 2.掌握时间数据可视化图表表示 3. 利用python程序实现堆叠柱形图的可视化 【实验原理】

Web前端-JavaScript输入输出语法

一、输出语法 1.语法一 作用:向body内输出内容 注意:如果输出的内容写的是标签&#xff0c;也会被解析成网页元素 例如&#xff1a; <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><meta name"viewpor…