神经风格迁移是一种图像合成技术,它通过混合两张不同的图像来生成一张新图像,这张新图像保留了一张图像的核心结构,同时使用另一张图像的风格进行装饰。这种技术在生成高质量现实主义艺术作品方面非常流行,并且在游戏和虚拟现实领域也有广泛的应用,尤其是随着Meta等公司的发展,这一技术成为了一个热门话题。
本文不会深入探讨神经风格迁移模型的工作机制和架构,但会提供一个基本的概览。该模型由两个网络构成,即特征提取器和风格迁移网络。卷积神经网络(CNN)在图像数据集上表现极佳,因为它们能够捕获空间信息,并通过使用滤波器或核对图像进行卷积来提取图像中的低级和高级特征。这也是CNN在图像分类任务中相较于其他神经网络架构表现卓越的主要原因之一。
特征提取模型通常是预训练的深度CNN,如Xception、ResNet50、VGG16、VGG19等。使用预训练的深度CNN作为特征提取器的原因在于,一些层学习提取图像中的内容,而另一些层学习图像中的纹理特征。风格迁移网络通常是一个自编码器,具有编码器-解码器架构,因为它接受图像输入并返回图像输出。
幸运的是,TensorFlow Hub提供了许多用于分类、回归、时间序列分析等各种任务的预训练模型,这是一个由TensorFlow维护的高质量预训练模型库。这些生产就绪的模型只需几行代码即可访问和微调。在本文中,将使用TensorFlow Hub中提供的预训练风格迁移模型来执行神经风格迁移。
如前所述,执行神经风格迁移时会使用两张图像。一张称为内容图像,另一张称为风格图像。内容图像是想要应用纹理或风格的图像。风格图像是从中提取纹理并将其转移到内容图像上以产生风格化图像的图像。
在本文中,将使用宠物照片作为内容图像,但可以是任何东西,比如自拍照、父母的照片或任何其他东西。这些是将要使用的风格图像,用于提取纹理并将其应用于内容图像以生成风格化图像。从Unsplash下载了这些图像,因为它们提供免费使用的高质量库存图像。
TensorFlow Hub是访问预训练模型所必需的。TensorFlow Hub可以像安装任何其他Python包一样安装在本地机器上。
!pip install --upgrade tensorflow_hub
以下是将在本文中用于实现神经风格迁移模型的模块。OpenCV将用于图像加载和基本图像处理。
import tensorflow_hub as hub
import tensorflow as tf
import cv2
import numpy as np
import matplotlib.pyplot as plt
from tensorflow.python.ops.numpy_ops import np_config; np_config.enable_numpy_behavior()
如前所述,将使用TensorFlow Hub中的预训练神经风格迁移模型。使用TensorFlow Hub中的预训练模型非常简单和方便。可以直接从TensorFlow Hub下载预训练模型并从磁盘加载它,或者可以直接提供预训练模型的URL。将使用URL来加载预训练模型。或者,可以从下载神经风格迁移模型。
model = hub.load('https://tfhub.dev/google/magenta/arbitrary-image-stylization-v1-256/2')
将使用OpenCV来读取和预处理图像。OpenCV使用BGR颜色格式而不是传统的RGB颜色格式,因此需要将颜色格式更改为RGB。还将对图像数组进行归一化以降低计算复杂性。
def load_img(path):
img = cv2.imread(path)
img = cv2.cvtColor(img, cv2.COLOR_BGR2RGB)
img = img/255.
return img
content_image = load_img('content.jpeg')
style_1 = load_img('style_1.png')
style_2 = load_img('style_2.png')
预训练的神经风格迁移模型只接受浮点32数据类型的图像作为张量。需要对内容和风格图像执行此转换。预训练模型在风格图像是边长为256像素的正方形图像时效果最佳,因为这是模型训练时每张图像的尺寸。因此,将调整风格图像到指定尺寸,并将其实现为浮点32类型的张量。预训练模型接受内容和风格图像作为输入参数,并在使用风格图像对内容图像执行神经风格迁移后返回输出图像。
def apply_style(content_image, style):
content_image = content_image.reshape(1, content_image.shape[0], content_image.shape[1], content_image.shape[2]).astype('float32')
content_image = tf.convert_to_tensor(content_image)
style = cv2.resize(style, (256,256))
style = style.reshape(1, style.shape[0], style.shape[1], style.shape[2]).astype('float32')
outputs = model(tf.constant(content_image), tf.constant(style))
stylized_image = outputs[0]
return stylized_image
让使用matplotlib可视化执行神经风格迁移后的输出图像。或者,可以将生成的图片保存到本地磁盘作为png或jpg文件。
img = apply_style(content_image, style_1)
plt.xticks([])
plt.yticks([])
plt.grid(False)
plt.imshow(img[0])
plt.show()
这是使用第一张风格图像的输出图像。
img = apply_style(content_image, style_2)
plt.xticks([])
plt.yticks([])
plt.grid(False)
plt.imshow(img[0])
plt.show()
这是使用第二张风格图像的输出图像。
在本文中,探讨了以下概念: