本文仅供学习交流使用,如侵立删!demo下载见文末

环境:
python:3.6.7
tensorflow=2.2.0
torch=1.5.1+cpu
torchvision=0.6.0+cpu
Pillow=8.1.2

效果:


输入原图和风格图生成迁移图片

# -*- coding: utf-8 -*-
import cv2
import timedef style_transfer(pathIn='',pathOut='',model='',width=None,jpg_quality=80):'''pathIn: 原始图片的路径pathOut: 风格化图片的保存路径model: 预训练模型的路径width: 设置风格化图片的宽度,默认为None, 即原始图片尺寸jpg_quality: 0-100,设置输出图片的质量,默认80,越大图片质量越好'''# 读入原始图片,调整图片至所需尺寸,然后获取图片的宽度和高度img = cv2.imread(pathIn)(h, w) = img.shape[:2]if width is not None:img = cv2.resize(img, (width, round(width * h / w)), interpolation=cv2.INTER_CUBIC)(h, w) = img.shape[:2]# 从本地加载预训练模型print('加载预训练模型......')net = cv2.dnn.readNetFromTorch(model)# 将图片构建成一个blob:设置图片尺寸,将各通道像素值减去平均值(比如ImageNet所有训练样本各通道统计平均值)# 然后执行一次前馈网络计算,并输出计算所需的时间blob = cv2.dnn.blobFromImage(img, 1.0, (w, h), (103.939, 116.779, 123.680), swapRB=False, crop=False)net.setInput(blob)start = time.time()output = net.forward()end = time.time()print("风格迁移花费:{:.2f}秒".format(end - start))# reshape输出结果, 将减去的平均值加回来,并交换各颜色通道output = output.reshape((3, output.shape[2], output.shape[3]))output[0] += 103.939output[1] += 116.779output[2] += 123.680output = output.transpose(1, 2, 0)# 输出风格化后的图片cv2.imwrite(pathOut, output, [int(cv2.IMWRITE_JPEG_QUALITY), jpg_quality])


CNN模型训练

import __future__
import torch
import torchvision.models as models
import torchvision.transforms as transforms
import time
import os
from PIL import Imagedevice = torch.device("cuda" if torch.cuda.is_available() else "cpu")
'''
环境:
python:3.6.7
tensorflow==2.2.0
torch==1.5.1+cpu
torchvision==0.6.0+cpu
Pillow==8.1.2
'''class GramMatrix(torch.nn.Module):def forward(self, input):b, n, h, w = input.size()features = input.view(b * n, h * w)G = torch.mm(features, features.t())return G.div(b * n * h * w)class StyleLoss(torch.nn.Module):def __init__(self, style_feature, weight):super(StyleLoss, self).__init__()self.style_feature = style_feature.detach()self.weight = weightself.gram = GramMatrix()self.criterion = torch.nn.MSELoss()def forward(self, combination):# output = combinationstyle_feature = self.gram(self.style_feature.clone() * self.weight)combination_features = self.gram(combination.clone() * self.weight)self.loss = self.criterion(combination_features, style_feature)return combinationclass StyleTransfer:def __init__(self, content_image, style_image, style_weight=5, content_weight=0.025):# Weights of the different loss componentsself.vgg19 = models.vgg19()self.vgg19.load_state_dict(torch.load('vgg19-dcbb9e9d.pth'))self.img_ncols = 1280self.img_nrows = 720self.style_weight = style_weightself.content_weight = content_weight# 处理原图和风格图片self.content_tensor, self.content_name = self.process_img(content_image)self.style_tensor, self.style_name = self.process_img(style_image)self.conbination_tensor = self.content_tensor.clone()def process_img(self, img_path):img = Image.open(img_path)img_name = img_path.split('/')[-1][:-4]loader = transforms.Compose([transforms.Resize((self.img_nrows, self.img_ncols)),transforms.ToTensor()])img_tensor = loader(img)img_tensor = img_tensor.unsqueeze(0)return img_tensor.to(device, torch.float), img_namedef deprocess_img(self, x, index):unloader = transforms.ToPILImage()x = x.cpu().clone()img_tensor = x.squeeze(0)img = unloader(img_tensor)result_folder = f'{self.content_name}_and_{self.style_name}'os.path.exists(result_folder) or os.mkdir(result_folder)filename = f'{result_folder}/rersult_{index}.png'img.save(filename)print(f'save {filename} successfully!')print()def get_loss_and_model(self, vgg_model, content_image, style_image):vgg_layers = vgg_model.features.to(device).eval()style_losses = []content_losses = []model = torch.nn.Sequential()style_layer_name_maping = {'0': "style_loss_1",'5': "style_loss_2",'10': "style_loss_3",'19': "style_loss_4",'28': "style_loss_5",}content_layer_name_maping = {'30': "content_loss"}for name, module in vgg_layers._modules.items():model.add_module(name, module)if name in content_layer_name_maping:content_feature = model(content_image).clone()content_loss = ContentLoss(content_feature, self.content_weight)model.add_module(f'{content_layer_name_maping[name]}', content_loss)content_losses.append(content_loss)if name in style_layer_name_maping:style_feature = model(style_image).clone()style_loss = StyleLoss(style_feature, self.style_weight)style_losses.append(style_loss)model.add_module(f'{style_layer_name_maping[name]}', style_loss)return content_losses, style_losses, modeldef get_input_param_optimizer(self, input_img):input_param = torch.nn.Parameter(input_img.data)optimizer = torch.optim.LBFGS([input_param])return input_param, optimizerdef main_train(self, epoch=10):print('Load model preprocessing')combination_param, optimizer = self.get_input_param_optimizer(self.conbination_tensor)content_losses, style_losses, model = self.get_loss_and_model(self.vgg19, self.content_tensor,self.style_tensor)cur, pre = 10, 10for i in range(1, epoch + 1):start = time.time()def closure():combination_param.data.clamp_(0, 1)optimizer.zero_grad()model(combination_param)style_score = 0content_score = 0for cl in content_losses:content_score += cl.lossfor sl in style_losses:style_score += sl.lossloss = content_score + style_scoreloss.backward()return style_score + content_scoreloss = optimizer.step(closure)cur, pre = loss, curend = time.time()print(f'|using:{int(end - start):2d}s |epoch:{i:2d} |loss:{loss.data}')if pre <= cur:print('Early stopping!')breakcombination_param.data.clamp_(0, 1)

本文仅供学习交流使用,如侵立删!

Python CNN风格迁移相关推荐

  1. python图片风格迁移毕设_神经风格迁移是如何运作的概述及Python实现

    神经风格迁移是如何运作的概述及Python实现 作者:PHPYuan 时间:2019-03-26 03:40:37 深度学习可以捕获一个图像的内容并将其与另一个图像的风格相结合,这种技术称为神经风格迁 ...

  2. python图片风格迁移毕设_Python简单实现图像风格迁移

    下载W3Cschool手机App,0基础随时随地学编程导语 T_T之前似乎发过类似的文章,那时候是用Keras实现的,现在用的PyTorch,而且那时候发的内容感觉有些水,于是我决定... 好吧我确实 ...

  3. cnn风格迁移_快速图像风格迁移思想在无线通信中的另类应用:算法拟合

    在本文中,并不是介绍最新的一些论文,而是回顾自己在很早(半年前?)读过的几篇文章.[1]Learning to optimize: Training deep neural networks for ...

  4. cnn风格迁移_愚蠢的CNN,换个马甲就认不出猫!但,这病能治 | ICLR Oral

    鱼羊 栗子 发自 凹非寺  量子位 报道 | 公众号 QbitAI "穿件马甲就不认识我了?" 如果把大象的纹理披在猫身上,CNN识别出的就是大象 (详见下文) . 图宾根大学的博 ...

  5. cnn风格迁移_简述风格迁移Neural-Style细节

    什么是风格迁移? 风格迁移是使用某些手段(合法的), 把图像从原风格转换到另外一个风格, 同时保证图像内容没有变化, 举个栗子, 下面的这类图片应该是很多人见过了 可以看到在把画风变成梵高的星夜后, ...

  6. 【人工智能】python图像风格迁移,来欣赏梵高风格的石原里美吧!

    图像的风格迁移,心心念念好久了啊! 简单几个步骤,就可以转换图片风格啦. 1. 在github下载模型,模型后缀名是 t7,新建 model 文件夹用来存放模型 图像风格迁移模型链接 2. 新建 fe ...

  7. python风格变换图片_【人工智能】python图片风格迁移,来欣赏梵高风格的石原里美吧!...

    图像的风格迁移,心心念念好久了啊! 简单几个步骤,就可以转换图片风格啦. 1. 在github下载模型,模型后缀名是 t7,新建 model 文件夹用来存放模型 2. 新建 fengge.py 文件, ...

  8. CNN 风格迁移模型 原理简述

    我们有了两张图片,分别是content图和style图 风格迁移本质上是找到一个新的图片,使得风格上趋近于风格图,内容上趋近于内容图 而"趋近"在深度学习中体现在loss函数中,所 ...

  9. cnn风格迁移_深度学习能否对音乐进行风格迁移?

    音色迁移.音乐流派迁移.音乐风格迁移都有做. 至少有两个可行的思路:增加condition,进行显式控制.THU九歌模型在诗歌生成中对风格进行了控制,利用infoGAN使用过的"mutual ...

最新文章

  1. Redis 笔记(16)— info 指令和命令行工具(查看内存、状态、客户端连接数、监控服务器、扫描大key、采样服务器、执行批量命令等)
  2. leetcode--最长连续递增序列--python
  3. 金星可能存在生命?科学家发现大气中有磷化氢,剧毒气体或是生物代谢产物...
  4. linux apt-get proxy
  5. JavaScript严格模式 use strict
  6. [IE技巧] 如何禁止用户关闭IE浏览器
  7. java环境变量中classpath是必须配置吗
  8. OCP笔记部分整理-学习参考
  9. centos 使用mutt发送邮件带附件
  10. 【2018.3.10】模拟赛之三-ssl2576 平台
  11. 消息中间件ActiveMQ、RabbitMQ、RocketMQ、ZeroMQ、Kafka如何选型
  12. 【渝粤教育】国家开放大学2018年秋季 0505-22T护理学基础 参考试题
  13. koa2-cookie-session
  14. jmeter+mysql+set_jmeter学习指南之操作 mysql 数据库
  15. 第 8 天 多线程与多进程
  16. matlab 矩阵jocobi迭代_计算方法实验指导书1 -
  17. python粘性拓展_Python拓展
  18. 阶段1 语言基础+高级_1-3-Java语言高级_05-异常与多线程_第3节 线程同步机制_6_解决线程安全问题_同步方法...
  19. 自写日历(周日历,农历节日节气)
  20. php 银联支付-app

热门文章

  1. 我的Android进阶之旅------解决Android Studio编译后安装apk报错:The APK file does not exist on disk...
  2. Android ActionBar完全解析,使用官方推荐的最佳导航栏(下)
  3. 三层架构—实践篇(.Net登录实例)
  4. python实现自顶向下,自底向上
  5. java实践源码--哈弗曼树
  6. golang的select
  7. char和unsigned char
  8. lodsb、stosb(和lodsw、stosw和lodsd、stosd指令)
  9. SQLite安装、编译与应用
  10. jvm四:常量的本质含义以及助记符基本认识