专栏首页快学Python梦幻风图片?我用Python分分钟做出来!!

梦幻风图片?我用Python分分钟做出来!!

每日一句:人生苦短,快学Python!

本期我们利用卷积神经网络制作一个处理图片的小工具,最终效果对比如下:

原图:

效果图(多张,可以左右滑动):

具体原理简单来说就是,训练一个神经网络,每层网络逐步提取越来越高级的图像特征,通过分析一些特定层的输出发现,当它识别到了一些特定的模式,就会将这些特征显著地增强,而且层数越高,识别的模式就越复杂。

然后网络将识别到的复杂特征组合起来形成完整的解释,并将这些信息反向传播到网络,每个神经元再显示出它想增强的模式或特征。通过以上过程,我们就可以迫使神经网络在图片中产生一些原本不存在的内容,即达到了梦幻的效果~

下面是实战演练环节。

本文代码在以下环境通过测试:

python == 3.6.13

numpy == 1.16.4
scipy == 1.2.1
Pillow == 8.2.0
matplotlib == 3.3.4
tensorflow == 1.2.0

首先,导入相关的库

import numpy as np
import PIL.Image
import scipy.misc
import tensorflow as tf

忽略无关的警告

import os
os.environ['TF_CPP_MIN_LOG_LEVEL'] = '2'

定义网络模型

# 导入inception模型
# tensorflow提供了以“.pb”为扩展名的文件,可以事先将模型导入到pb文件中,在需要的时候导出
model_fn = 'tensorflow_inception_graph.pb'

# 创建图和会话
graph = tf.Graph()
sess = tf.InteractiveSession(graph=graph)
with tf.gfile.FastGFile(model_fn, 'rb') as f:
    graph_def = tf.GraphDef()
    graph_def.ParseFromString(f.read())

# 定义输入图像的占位符
t_input = tf.placeholder(np.float32, name='input')

# 图像预处理——减均值
# 训练inception模型时做了减均值预处理,此处也需减同样的均值以保持一致
imagenet_mean = 117.0

# 图像预处理——增加维度
# 图像数据格式一般是(height,width,channels),为同时将多张图片输入网络而在前面增加一维,变为(batch,height,width,channel)
t_preprocessed = tf.expand_dims(t_input - imagenet_mean, 0)

# 导入模型并将预处理图像送入网络中
tf.import_graph_def(graph_def, {'input': t_preprocessed})

找出卷积层

layers = [op.name for op in graph.get_operations() if op.type == 'Conv2D']
# 输出卷积层层数和卷积层名称
print('Number of layers', len(layers))
print(layers)

运行之前的内容可以得到如下输出:

Number of layers 59
['import/conv2d0_pre_relu/conv', 'import/conv2d1_pre_relu/conv', 'import/conv2d2_pre_relu/conv', 'import/mixed3a_1x1_pre_relu/conv', 'import/mixed3a_3x3_bottleneck_pre_relu/conv', 
.......
.......
'import/mixed5b_3x3_pre_relu/conv', 'import/mixed5b_5x5_bottleneck_pre_relu/conv', 'import/mixed5b_5x5_pre_relu/conv', 'import/mixed5b_pool_reduce_pre_relu/conv', 'import/head0_bottleneck_pre_relu/conv', 'import/head1_bottleneck_pre_relu/conv']

是不是很有规律呢?没错,忽略一些次要词语,剩下的12个词就是咱们要用的部分,分别为:

'conv2d0', 'conv2d1', 'conv2d2', 'mixed3a', 'mixed3b', 'mixed4a', 'mixed4b', 'mixed4c', 'mixed4d', 'mixed4e','mixed5a', 'mixed5b'

这12个词,便是预训练模型里的12个卷积层,不同的卷积层对图片进行处理,我们可以得到风格不同的图片。后面会用到这部分内容。

接下来是相关函数的定义:

(篇幅原因,这里这罗列部分函数,完整代码下载方式见文末)

# 判断文件夹是否存在,若不存在则创建
def mkdir(path):
    folder = os.path.exists(path)
    if not folder:
        os.makedirs(path)

# 把numpy.ndarray保存成图像文件
def savearray(img_array, img_name):
    scipy.misc.toimage(img_array).save(img_name)

# 调整图像尺寸
def resize(img, hw):
    min = img.min()
    max = img.max()
    img = (img - min) / (max - min) * 255
    img = np.float32(scipy.misc.imresize(img, hw))
    img = img / 255 * (max - min) + min
    return img

# 原始图像尺寸可能很大,从而导致内存耗尽,每次只对 tile_size * tile_size 大小的图像计算梯度,避免内存问题
def calc_grad_tiled(img, t_grad, tile_size=512):

接下来便是主程序部分。关于这部分的图片风格定义,其实是笔者将许多张图片分别用12个卷积层进行处理,然后把处理结果拿给一位艺术细胞和审美能力比较良好的小姐姐,让她帮忙将风格相似的图片整理在一起,并给对应风格取一个文艺又小清新的名字,也就是说,尽管每次选择同样的风格,但是结果还是会有细微的差别,这就是惊喜了。总之,,在此再次感谢她~

# 打印提示信息
print('嗨,我是你的小小魔法师,我可以为你的图片生成超级梦幻的效果~')
print('请将待处理的图片放入"preprocess_image"文件夹中,复制当前要处理的图片名称')

# 图片风格定义及选择
pattern_name = input('\n请选择图像风格:1.失真印象;2.青铜秘纹;3.克鲁苏之眼;4.迷幻乐园;5.随机(输入对应数字即可):')

if pattern_name == '1':
    name_list = ['conv2d0', 'conv2d1', 'conv2d2']
    name = name_list[np.random.randint(0, 3)]
elif pattern_name == '2':
    name_list = ['mixed3a', 'mixed3b']
    name = name_list[np.random.randint(0, 2)]
elif pattern_name == '3':
    name_list = ['mixed4a', 'mixed4b', 'mixed4c']
    name = name_list[np.random.randint(0, 3)]
elif pattern_name == '4':
    name_list = ['mixed4d', 'mixed4e', 'mixed5a', 'mixed5b']
    name = name_list[np.random.randint(0, 4)]
elif pattern_name == '5':
    name_list = (
        'conv2d0', 'conv2d1', 'conv2d2', 'mixed3a', 'mixed3b', 'mixed4a', 'mixed4b', 'mixed4c', 'mixed4d', 'mixed4e',
        'mixed5a', 'mixed5b')
    name = name_list[np.random.randint(0, 12)]
else:
    print('请看清楚规则!!')

# 获取卷积层对应的通道数
layer_output = graph.get_tensor_by_name('import/%s:0' % name)
# 读取预处理的图片
image_name = input('\n请输入图片名称(附带图片格式,例如:test.jpg):')
file_path = 'preprocess_image/' + image_name
img0 = PIL.Image.open(file_path)
img0 = np.float32(img0)

# 定义图片输出路径
mkdir('processed_image')
file_save_path = 'processed_image/' + image_name.split(sep='.')[0] + '_' + name + '.jpg'

print('\n图片处理过程需要1~2分钟,请耐心等待……')
# 调用render_deepdream函数渲染
render_deepdream(tf.square(layer_output), img0, iter_n=10, step=1.0)
print('\n已完成!生成的图片保存在“processed_image”文件夹下')

至此,图片处理部分结束。

打包

最后,我们可以将它进行简单的打包,这样没有安装python或者配置tensorflow的人也可以使用这个小工具~

我们使用conda创建虚拟环境,用pyinstaller这个库来打包。如果想详细了解Python打包,可以看我之前的文章《别再问我Python打包成exe了!(终极版)

为什么非要创建一个虚拟环境呢?

这是因为在打包的时候,会将当前环境里所有已安装的包打包进去,如果当前环境里已经安装了很多当前代码用不到的库,这样打包好的可执行文件就显得十分臃肿,非常占地方。

接下来我将详细展示打包过程~

没有安装conda的朋友可以先装一个Anaconda或者Mini Conda,因为用它做环境管理真的太方便了。

首先,打开终端,新建一个虚拟环境:

conda create -n tensorflow python=3.6

这里tensorflow是虚拟环境的名称,也可以按照自己的意愿自定义,python=3.6用于指定虚拟环境中python解释器的版本。

创建成功后,使用以下命令激活虚拟环境:

conda activate tensorflow

虚拟环境就相当于重新安装了一个python,此时环境中除了pip和setuptools没有其他的包。因此我们先安装需要用的几个包,这里不要忘了安装pyinstaller这个包。

pip install pyinstaller

pip install numpy==1.16.4
pip install pillow==8.2.0
pip install scipy==1.2.1
pip install matplotlib==3.3.4
pip install tensorflow==1.2.0

接下来,在终端使用命令切换到代码所在目录:

cd D:\Dreamscape\

然后就可以使用pyinstaller进行打包:

pyinstaller -F Dreamscape.py 

-F表示打包成一个单独的文件,Dreamscape.py是主程序名称。

打包成功之后,会在当前目录生成文件夹,可执行文件在dist目录下,注意,exe文件应该和其他依赖文件放在一起,如下图所示:

什么,才67.8MB??其实笔者还删掉了一些不必要的依赖库,才使得打包的exe比较小。因为tensorflow本来就是一个超级大的库,在执行该代码时候部分依赖项用不到,但是笔者也不清楚具体哪个用不到。于是使用pip list列出了该环境下的所有库,然后挨个删除,看程序能否正常能够运行,不能运行就再装回来。。。功夫不负有心人,最终,还是成功地删掉了几个库。

至此,我们完成了该小工具的制作。下面是笔者测试过程中的一些比较成功的作品:

效果图(多张,可以左右滑动):

那么,失败的作品该长啥样呢?

原图:

效果图:

原本魅力无限的迷人小姐姐,硬是被玩坏了。。。

剧终……


Tips:如果想要获得更加细致的图像,可以修改渲染函数里的iter_n参数,增大迭代次数,或者减小step,也可以二者同时调整,使得网络学习到输入图像的更多特征。当然了,这样也会增加图像处理时长……

render_deepdream(tf.square(layer_output), img0, iter_n=10, step=1.0)

本文分享自微信公众号 - 快学Python(kxpython),作者:愆、朱小五

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2021-08-07

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • 加拿大奇幻电影节2018进行中|13部VR影片齐亮相,恐怖冒险一次体验够!

    7月12日至8月1日,被业界誉为“北美最大的类型电影节”的加拿大奇幻电影节(Fantasia International Film Festival,以下简称“...

    VRPinea
  • 用AI指挥另一个AI,GAN+CLIP的组合成了“CG艺术家”

    不需要改变数据集,只需要给CLIP下达的命令中把“虚幻引擎”几个字加上,再让CLIP去指挥GAN,图像就立马变成了高大上的CG艺术风。

    量子位
  • qt王者荣耀皮肤抽奖器

    说一下过程吧,第一步,就是先准备好皮肤的图片,皮肤的图片在王者荣耀的官网是可以下载的,但是过百的下载量确实有点大了,动了个小心思,网上找了一个用py写的爬虫...

    花狗Fdog
  • 是的,你没有猜错!今天是VR电影时间~

    VRPinea
  • AI 技术讲座精选:数学不好,也可以学习人工智能(三)

    【AI100 导读】学习人工智能到底要不要学好数学,这俨然已经成了一个争议话题了?之前 AI100 刊发了本系列的前两篇文章,也发表了作者子白的《放弃幻想,搞 ...

    AI科技大本营
  • 威尼斯电影节今晚开幕,你猜今年的VR单元大奖花落谁家?

    VRPinea
  • 2018,丁磊的野心静悄悄

    别的CEO现身为自家无人挖掘机站台,丁磊却润物细无声每天八次出现在网易严选的推送中。

    镁客网
  • 不同的编程语言是怎么卖牛排的?网友:绝了!

    C++:服务员牵来一头牛,给了顾客主厨刀、削皮刀、剔骨刀、片刀、砍刀、美工刀……堆满在桌上,笑道,请享用!顾客一脸懵逼,但看到邻桌的老大爷用挥舞双截棍的姿势使用...

    顶级程序员
  • 20个令人惊叹的深度学习应用(Demo+Paper+Code)

    唐旭 发自 RUC 量子位 报道 | 公众号 QbitAI 从计算机视觉到自然语言处理,在过去的几年里,深度学习技术被应用到了数以百计的实际问题中。诸多案例也已...

    量子位
  • 让GAN随音乐律动

    一位外国小哥开发的Python工具,能让GAN生成的图像随音乐律动,几个小时内就在reddit上收获了1.5k个赞。

    公众号机器学习与生成对抗网络
  • 帮你偷懒的靠谱幻灯工具

    PPT是微软办公软件PowerPoint的文件扩展名。因为大家做幻灯都习惯了用PowerPoint,所以渐渐地就把“幻灯”和“PPT”混为一谈了。

    王树义
  • 逛完客厅、厨房、阳台,不如来看看VR游戏的最新动态?

    相信不少读者今年都度过了一个不一样的春节,每天都在焦急地关注着新型冠状病毒的影响,盼望着开工、开学的日子;也有在思考着奶茶、海底捞、小龙坎、炸鸡、汉堡、蛋挞.....

    VRPinea
  • 【AI产品】深扒美图秀秀中掳获万千少女芳心的“AI秘籍”

    上一期我们一起体验了抖音里的各项黑科技,见证了抖音以短视频为载体,基于人脸关键点检测、图像语义分割、风格迁移、表情识别、图像分类等计算机视觉技术为用户提供了专业...

    用户1508658
  • GitHub 上有意思的项目推荐

    前端GoGoGo
  • 梦幻成仙,诛灭外挂:《梦幻诛仙手游》的阻击外挂之旅

    腾讯大部分手游上线前都会进行手游安全测试,《王者荣耀》、《穿越火线:枪战王者》等六星级游戏更是每一个版本都主动寻求手游漏洞扫描,《梦幻诛仙手游》同样也是如此。

    WeTest质量开放平台团队
  • 六问 WeTest 手游测试团队:如何助《梦幻诛仙手游》诛灭外挂

    目前,腾讯WeTest手游安全测试服务已经通过腾讯云全面开放,服务广大的游戏项目。

    腾讯游戏云
  • 极简风格的演讲型幻灯片设计

    极简风格(Minimalism),就是将设计省略到最小限度,只留下真正引人注意的内容,这样一种表现风格。通过极简风格,可以将设计的意图与目的更准确的传达出来。

    CSDN技术头条
  • 我真的太想当明星了!

    ? 青春有你 创造营2020 偶像练习生 …… 随着选秀节目的热播 站在聚光灯下成为了许多人的梦想 与此同时,另一群人正在虎视眈眈地注视着他们 一场“造梦骗...

    腾讯举报中心
  • 艾美奖掀起一阵VR风,哪种VR影片更受评委喜爱?

    VRPinea

扫码关注云+社区

领取腾讯云代金券