Python 官方文档:入门教程 => 点击学习
本篇内容主要讲解“利用python实现图片风格迁移”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“利用Python实现图片风格迁移”吧!1. 什么是图片的风格迁移?所谓图片风格迁移,是指利用程序算
本篇内容主要讲解“利用python实现图片风格迁移”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“利用Python实现图片风格迁移”吧!
所谓图片风格迁移,是指利用程序算法学习著名画作的风格,然后再把这种风格应用到另外一张图片上的技术。
举个例子,见上图。左边是我们的原始图片(也称内容图像):小编在苏州甪直古镇的一座小桥上拍下的一张照片。
中间是我们的风格图片:挪威表现派画家爱德华·蒙克的代表作《呐喊》(The Scream)。
右边是将爱德华·蒙克的《呐喊》的风格应用于原始图片后生成的风格化结果图。仔细观察,图片是如何保留了流水、房屋、房屋在水中的倒影,甚至远处树木的内容,但却运用了《呐喊》的风格,就好像爱德华·蒙克在我们的景色中运用了他高超的绘画技巧一样!
问题是,我们应该定义一个什么样的神经网络来执行图片的风格迁移?
这可能吗?
答案是:可以的。我将在下一节简单讨论如何基于神经网络来实现图片风格的迁移。
Gatys等人在2015年发表了第一篇基于深度学习的风格迁移算法文章,原文链接为https://arxiv.org/abs/1508.06576,随后文章收录于2016年的CVPR顶会。
有趣的是,他们提出了一种完全不需要新网络架构的风格迁移算法,其使用的网络构架是在前人的VGG19基础上稍加改造而成的,而且网络参数也使用预训练(通常在ImageNet上)网络的参数。我们来看下它的原理:
我们知道,卷积神经网络(CNN)具有很强的图像特征(feature/representation)提取能力,如上图所示。
对于内容图片,深层网络(d和e)提取的是高维特征,同时也丢弃了细节信息;浅层网络(a, b和c)提取的是低维特征,图片的细节大多都保留下来了。
对于风格图片,通过包含多层的特征相关性(Gram矩阵),可获得多尺度图像风格的重构,捕获其纹理信息。这样构建的网络可以忽略图像的具体细节,保留风格。
为了将内容图片和风格图片融合在一起(见下图),我们应该使风格化结果图(初始为一张白噪声图片)的特征同时与内容图片和风格图片的特征之间的距离最小化,最终获取我们所需的风格化结果图。
因此生成目标图片的损失函数可定义为:
其中α和β分别是内容图片和风格图片的特征所占的权重,通过最小化这个损失函数就可以获得我们想要的结果。来看个动态示意图:
值得注意的是,这里优化的参数不再是网络的权重ω和偏差b,而是初始输入的一张白噪声图片。
虽然上述方法可产生非常漂亮的风格迁移效果,但是速度很慢。
2016年,Johnson等人基于Gatys等人的工作,提出了一种速度可提高三个数量级的风格迁移算法。虽然算法的速度很快,但最大的缺点是不能像Gatys等人那样随意选择你的风格图片。针对每张风格图片,你都需要训练一个网络来重现这个风格。一旦网络模型训练好之后,你就可将它应用于你想要的任何内容图片了。
这篇博客我们将使用Johnson等人的方法,其算法实现和预训练模型可参考Https://GitHub.com/jcjohnson/fast-neural-style。
下面利用OpenCV来快速实现图片的风格迁移,我将其封装成一个叫 style_transfer()
的函数,其使用说明可参考函数内部的注释。目前只有11个预训练模型可用。
1. `## 载入所需库`2. `import cv2`3. `import time` 4. `def style_transfer(pathIn='',`5. `pathOut='',`6. `model='',`7. `width=None,`8. `jpg_quality=80):`9. `'''`10. `pathIn: 原始图片的路径`11. `pathOut: 风格化图片的保存路径`12. `model: 预训练模型的路径`13. `width: 设置风格化图片的宽度,默认为None, 即原始图片尺寸`14. `jpg_quality: 0-100,设置输出图片的质量,默认80,越大图片质量越好`15. `'''`16. `## 读入原始图片,调整图片至所需尺寸,然后获取图片的宽度和高度`17. `img = cv2.imread(pathIn)`18. `(h, w) = img.shape[:2]`19. `if width is not None:`20. `img = cv2.resize(img, (width, round(width*h/w)), interpolation=cv2.INTER_CUBIC)`21. `(h, w) = img.shape[:2]` 23. `## 从本地加载预训练模型`24. `print('加载预训练模型......')`25. `net = cv2.dnn.readNetFromTorch(model)` 26. `## 将图片构建成一个blob:设置图片尺寸,将各通道像素值减去平均值(比如ImageNet所有训练样本各通道统计平均值)`27. `## 然后执行一次前馈网络计算,并输出计算所需的时间`28. `blob = cv2.dnn.blobFromImage(img, 1.0, (w, h), (103.939, 116.779, 123.680), swapRB=False, crop=False)`29. `net.setInput(blob)`30. `start = time.time()`31. `output = net.forward()`32. `end = time.time()`33. `print("风格迁移花费:{:.2f}秒".fORMat(end - start))` 35. `## reshape输出结果, 将减去的平均值加回来,并交换各颜色通道`36. `output = output.reshape((3, output.shape[2], output.shape[3]))`37. `output[0] += 103.939`38. `output[1] += 116.779`39. `output[2] += 123.680`40. `output = output.transpose(1, 2, 0)` 42. `## 输出风格化后的图片`43. `cv2.imwrite(pathOut, output, [int(cv2.IMWRITE_JPEG_QUALITY), jpg_quality])`
来测试一下:
1. `>>> models = glob.glob('.*.t7')`2. `>>> models ## 列出所有可用的预训练模型`3. `['.\\models\\eccv16\\composition_vii.t7',`4. `'.\\models\\eccv16\\la_muse.t7',`5. `'.\\models\\eccv16\\starry_night.t7',`6. `'.\\models\\eccv16\\the_wave.t7',`7. `'.\\models\\instance_norm\\candy.t7',`8. `'.\\models\\instance_norm\\feathers.t7',`9. `'.\\models\\instance_norm\\la_muse.t7',`10. `'.\\models\\instance_norm\\mosaic.t7',`11. `'.\\models\\instance_norm\\starry_night.t7',`12. `'.\\models\\instance_norm\\the_scream.t7',`13. `'.\\models\\instance_norm\\udnie.t7']` 15. `>>> pathIn = './img/img01.jpg'`16. `>>> pathOut = './result/result_img01.jpg'`17. `>>> model = './models/instance_norm/the_scream.t7'`18. `>>> style_transfer(pathIn, pathOut, model, width=500)`19. `加载预训练模型......`20. `风格迁移花费:1.18秒` 22. `>>> pathIn = './img/img02.jpg'`23. `>>> pathOut = './result/result_img02.jpg'`24. `>>> model = './models/instance_norm/starry_night.t7'`25. `>>> style_transfer(pathIn, pathOut, model, width=500)`26. `加载预训练模型......`27. `风格迁移花费:3.17秒` 29. `>>> pathIn = './img/img03.jpg'`30. `>>> pathOut = './result/result_img03.jpg'`31. `>>> model = './models/instance_norm/the_scream.t7'`32. `>>> style_transfer(pathIn, pathOut, model, width=500)`33. `加载预训练模型......`34. `风格迁移花费:0.90秒` 36. `>>> pathIn = './img/img04.jpg'`37. `>>> pathOut = './result/result_img04.jpg'`38. `>>> model = './models/eccv16/the_wave.t7'`39. `>>> style_transfer(pathIn, pathOut, model, width=500)`40. `加载预训练模型......`41. `风格迁移花费:2.68秒` 43. `>>> pathIn = './img/img05.jpg'`44. `>>> model = './models/instance_norm/mosaic.t7'`45. `>>> style_transfer(pathIn, pathOut, model, width=500)`46. `加载预训练模型......`47. `风格迁移花费:1.23秒`
从运行结果可知,在CPU上,一张图片的风格迁移所花的时间大概也就几秒。如果使用GPU,完全可以实时对视频/摄像头进行风格迁移处理。
自Gatys等人第一次(2015年)实现基于深度学习的风格迁移以来,风格迁移技术仍一直在发展,如今在速度和质量上都有了很大提高。目前的一些进展可以通过下面的链接来了解:
https://github.com/jcjohnson/fast-neural-style
https://github.com/DmitryUlyanov/texture_nets
https://github.com/luanfujun/deep-painterly-harmonization
https://junyanz.github.io/CycleGAN/
他们的一些作品:
风格迁移
外来图片的融合
图片季节的变换
图片背景的虚化
角色互换
到此,相信大家对“利用Python实现图片风格迁移”有了更深的了解,不妨来实际操作一番吧!这里是编程网网站,更多相关内容可以进入相关频道进行查询,关注我们,继续学习!
--结束END--
本文标题: 利用Python实现图片风格迁移
本文链接: https://lsjlt.com/news/228734.html(转载时请注明来源链接)
有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341
2024-03-01
2024-03-01
2024-03-01
2024-02-29
2024-02-29
2024-02-29
2024-02-29
2024-02-29
2024-02-29
2024-02-29
回答
回答
回答
回答
回答
回答
回答
回答
回答
回答
0