基于色卡的替换风格迁移

  本文研究了一种图像风格迁移方式,用制作滤镜色卡来进行颜色替换,以“你的名字”风格为例进行了实现。

首先感谢原文作者的思路!参考链接在这里:
天然呆久必然萌儿: 实现《你的名字》同款滤镜,python+opencv
Zihua Li只需 4 步,手把手教你如何实现滤镜功能

  图像风格迁移有一种非常朴素思路,那就是制作一张与基础色卡颜色映射的风格替换色卡(滤镜),这个替换色卡可以使用现有的滤镜将基础色卡转换生成,如果滤镜本身没有在色彩变换后添加其他复杂的操作的话得到的效果应该是非常好的。从“实现《你的名字》同款滤镜”原文最终放出的效果图来看非常的梦幻,但是原文色卡与给出的生成公式没有严格对齐,所以本文记录了笔者具体实现这一部分的过程。
  沿用作者的参数不变,rgb选取每4个单位隔一个点。共计64×64×64个像素点,首先将r,g可以排布为64×64,再将其扩展到8×8个,添加b值,就可以得到LevZelensky的色卡。

  那么我们有像素点坐标(i,j)和所存储RGB值的对应关系为:

1
2
3
4
5
6
r = (i % 64) * 4
g = (j % 64) * 4
b = (i // 64) * 32 + (j // 64) * 4
那么:
i = b // 4 // 8 * 64 + r // 4
j = b // 4 % 8 * 64 + g // 4

  准备标准色卡:

  在《手把手教你如何实现滤镜功能》中找到的标准色卡,读取后发现它并不是按照上述关系式进行构筑的,故而我首先按总结的式子刷新标准色卡。

1
2
3
4
5
6
7
8
9
10
11
12
13
from PIL import Image
import numpy as np
import matplotlib.image

img = np.array(Image.open('/home/jiawei/Pictures/lookup-table.png'))
# 修正标准色卡
for i in range(512):
for j in range(512):
r = (i % 64) * 4
g = (j % 64) * 4
b = (i // 64) * 32 + (j // 64) * 4
img[i, j] = (r, g, b)
matplotlib.image.imsave('/home/jiawei/Pictures/oricard.png', img)

  用标准色卡跑不同的风格得到滤镜对应的转换色卡,然后拿我们的待处理照片做逐点变换就可以完成风格转换啦。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
from PIL import Image
import numpy as np
import matplotlib.image
#待处理照片img,风格色卡style
img=np.array(Image.open('/home/jiawei/Pictures/timg.jpeg'))
style=np.array(Image.open('/home/jiawei/Pictures/pink.jpg'))
rows,cols,dims=img.shape
for i in range(rows):
for j in range(cols):
r, g, b=img[i,j]
m=b//4//8*64+r//4
n=b//4%8*64+g//4
img[i,j]=style[m,n]
matplotlib.image.imsave('/home/jiawei/Pictures/output.png',img)

  拿一张照片做个例子,用的几个滤镜分别为“你的名字”,“复古”,“粉红佳人”。

效果对比

附标准和三个风格色卡:
标准色卡
你的名字
复古
粉红佳人