PaddleHub创意之艺术风格迁移

PaddleHub的图像生成

  • 想法
  • 迁移方法
  • 模型介绍
  • 将毕加索画风迁移到BadApple动画中
    • 每帧融合代码
    • 图片整合成视频

想法

毕加索的作品风格丰富多样,后人用“毕加索永远是年轻的”的说法形容毕加索多变的艺术形式。本人对艺术作品不懂,但是好奇当多种作品实现艺术风格迁移时,会是什么样子。

迁移方法

最近在浏览预训练PaddleHub时,发现了这个好玩的module——stylepro_artistic
模型介绍如下:
艺术风格迁移模型可以将给定的图像转换为任意的艺术风格。本模型StyleProNet整体采用全卷积神经网络架构(FCNs),通过encoder-decoder重建艺术风格图片。StyleProNet的核心是无参数化的内容-风格融合算法Style Projection,模型规模小,响应速度快。模型训练的损失函数包含style loss、content perceptual loss以及content KL loss,确保模型高保真还原内容图片的语义细节信息与风格图片的风格信息。预训练数据集采用MS-COCO数据集作为内容端图像,WikiArt数据集作为风格端图像。
此外官网还给出了一个示例:

更多的详细信息还可以查看相关文章https://arxiv.org/abs/2003.07694

模型介绍

该模型可以直接通过bash进行调用融合,也可以嗲用python的api接口进行调回可以查看官网
这里我介绍以下python接口,下面是其定义的接口:

def style_transfer(self,
                   images=None,
                   paths=None,
                   alpha=1,
                   use_gpu=False,
                   visualization=False,
                   output_dir='transfer_result'):

其中相关参数说明:

  • images (list[dict]): ndarray 格式的图片数据。每一个元素都为一个 dict,有关键字 content,
    styles,weights(可选),相应取值为:

    • content (numpy.ndarray): 待转换的图片,shape 为 [H, W, C],BGR格式;
    • styles (list[numpy.ndarray]) : 作为底色的风格图片组成的列表,各个图片数组的shape 都是 [H, W, C],BGR格式;
    • weights (list[float], optioal) : 各个 style 对应的权重。当不设置 weights 时,默认各个 style 有着相同的权重;
  • paths (list[str]): 图片的路径。每一个元素都为一个 dict,有关键字 content, styles,weights(可选),相应取值为:

    • content (str): 待转换的图片的路径;
    • styles (list[str]) : 作为底色的风格图片的路径;
    • weights (list[float], optioal) : 各个 style 对应的权重。当不设置 weights 时,各个 style 的权重相同;
  • alpha (float) : 转换的强度,[0, 1] 之间,默认值为1;

  • use_gpu (bool): 是否使用 GPU;

  • visualization (bool): 是否将结果保存为图片,默认为 False;

  • output_dir (str): 图片的保存路径,默认设为 transfer_result 。
    使用方法:

# 导入必要的包
import cv2
import paddlehub as hub
stylepro_artistic = hub.Module(name="stylepro_artistic")
result = stylepro_artistic.style_transfer(
        images=[{
            'content': cv2.imread('target.jpg'),
            'styles': [cv2.imread('style.jpg')], # 这里只选取了一个风格图片
            'weights':[1] # 由于上面只选取了一个图片,所以这里也智能有一个数字组成的数组
        }],
        alpha = 1.0,
        use_gpu = False,
        visualization=True,
        output_dir='transvideo_result')

这里说明以下paths的使用与上面相同的效果代码为:

import paddlehub as hub
stylepro_artistic = hub.Module(name="stylepro_artistic")
result = stylepro_artistic.style_transfer(
        paths=[{
            'content': 'target.jpg',
            'styles': ['style.jpg'], # 这里只选取了一个风格图片
            'weights':[1] # 由于上面只选取了一个图片,所以这里也智能有一个数字组成的数组
        }],
        alpha = 1.0,
        use_gpu = False,
        visualization=True,
        output_dir='transvideo_result')

可以发现这里只是少了图片打开的一个过程。
下面分析一下返回值:

[{'data': array([[[108, 166, 133],
        [ 62, 107,  84],
        [133, 169, 134],
        ...,
        [ 83, 141, 159],
        [ 85, 145, 169],
        [ 85, 142, 169]],

       [[106, 164, 132],
        [ 64, 109,  84],
        [134, 170, 136],
        ...,
        [ 91, 142, 161],
        [ 90, 144, 169],
        [ 90, 142, 170]],

       [[109, 164, 133],
        [ 65, 110,  86],
        [136, 171, 139],
        ...,
        [ 95, 141, 160],
        [100, 147, 173],
        [ 95, 144, 172]],

       ...,

       [[ 71,  71,  82],
        [ 72,  72,  83],
        [ 71,  66,  74],
        ...,
        [ 31,  30,  40],
        [ 84,  93, 113],
        [ 64,  77, 111]],

       [[ 71,  71,  83],
        [ 71,  71,  85],
        [ 70,  65,  75],
        ...,
        [ 30,  29,  39],
        [ 87,  96, 117],
        [ 69,  84, 119]],

       [[ 71,  71,  83],
        [ 72,  71,  85],
        [ 70,  64,  76],
        ...,
        [ 31,  30,  39],
        [ 87,  97, 118],
        [ 71,  83, 118]]], dtype=uint8), 
'save_path': 'transfer_result/ndarray_1588391023.5056114.jpg'}]

返回值是一个由字典元素形成的列表字典的key分别为’data‘和’save_path‘
data数值表示三通道的图片数据,我们可以直接显示这个图片的。

import matplotlib.pyplot as plt
plt.imshow(result[0]['data'])

PaddleHub创意之艺术风格迁移_第1张图片
save_path表示我们保存图片的位置,且仅当visualization为True时,此值存在。
最后一个比较大胆的想法。

将毕加索画风迁移到BadApple动画中

主要思路,首先我们通过cv2的视频读取功能,将视频的每一帧都进行与同一张照片的融合,最后将融合的图片再整合成视频,就搞定了,具体代码如下:

每帧融合代码

# 导入必要的包
import cv2
import paddlehub as hub
from tqdm import tqdm
stylepro_artistic = hub.Module(name="stylepro_artistic")
video = cv2.VideoCapture("work/badapple.mp4")
# 获取帧数/s
fps = video.get(cv2.CAP_PROP_FPS)
# 获取总帧数
frameCount = video.get(cv2.CAP_PROP_FRAME_COUNT)
# 获取视频的尺寸信息
size = (int(video.get(cv2.CAP_PROP_FRAME_WIDTH)), int(video.get(cv2.CAP_PROP_FRAME_HEIGHT)))
print("总共的帧数为:",frameCount)
success, frame = video.read() 
file_paths = []
index = 0
for i in tqdm(range(int(frameCount))):
    # 判断是否读取帧成功,且前33帧为黑屏帧,这里不做处理,加快进度
    if success and index > 33:
            result = stylepro_artistic.style_transfer(
                images=[{
                    'content': frame,
                    'styles': [cv2.imread('work/pics/8.jpg')]
                }],
                visualization=True,
                output_dir='transvideo_result')
            file_paths.append(result[0]['save_path'])
    elif success:
        filep = 'transvideo_result/'+str(index)+'.jpg'
        cv2.imwrite(filep, frame)
        file_paths.append(filep)
    success, frame = video.read()
    index += 1

图片整合成视频

import os
import cv2
import datetime
file_dict = {}
video = cv2.VideoCapture("work/badapple.mp4")
fps = video.get(cv2.CAP_PROP_FPS)
frameCount = video.get(cv2.CAP_PROP_FRAME_COUNT)
size = (int(video.get(cv2.CAP_PROP_FRAME_WIDTH)), int(video.get(cv2.CAP_PROP_FRAME_HEIGHT)))
for i in os.listdir('transvideo_result/'):
    file_dict['transvideo_result/'+i] = float(i.replace('ndarray_','').replace('.jpg',''))
file_dict = sorted(file_dict.items(),key = lambda x:x[1])
videoWriter = cv2.VideoWriter('trans.avi', cv2.VideoWriter_fourcc(*"MJPG"), fps, size)
flag = True
for i in file_dict:
    if flag:
        for j in range(34):
            videoWriter.write(cv2.imread('work/target/0.jpg'))
        flag = False
    videoWriter.write(cv2.imread(i[0]))
videoWriter.release()
cv2.destroyAllWindows()

此外为方便大家,我将AIStudio中的项目开源了。大家可以fork运行一下。项目地址为:
https://aistudio.baidu.com/aistudio/projectdetail/439779
最后大家可以看一下成品动画。

深度学习之BadApple遇上毕加索的画风

你可能感兴趣的:(PaddleHub,笔记,python,深度学习)