计算机视觉的应用6-利用VGG模型做毕加索风格图像迁移

news2025/1/15 20:39:45

大家好,我是微学AI,今天给大家介绍一下计算机视觉的应用5-利用VGG模型做毕加索风格图像迁移,本文将利用VGG模型实现毕加索风格图像迁移的方法。首先,我们将简要说明图像风格迁移的原理,然后使用PyTorch框架,分步骤地实现毕加索风格图像迁移的算法。最后,我们将展示实验结果,验证算法的有效性。

目录

一、引言

二、图像风格迁移原理

2.1. VGG网络
2.2. 内容损失
2.3. 风格损失
2.4. 总损失

三、算法实现

四、总结

一、引言

图像风格迁移是一种将一幅图像的艺术风格应用到另一幅图像的技术,可以生成具有不同艺术风格的图像。其中,基于CNN的风格迁移技术是一种比较常用的方法。这种方法的基本思想是,通过将一个与风格相关的损失函数加入到卷积神经网络中,来学习如何将输入图像的内容信息和风格信息进行分离,并将两者重新合成生成一幅新的图像。

毕加索风格迁移算法的实现过程可以分为以下几个步骤:

1.使用卷积神经网络VGG预处理输入图像和毕加索的艺术风格图像。这一步的目的是提取输入图像和艺术风格图像的特征,作为之后迁移的基础。

2.定义两个损失函数:内容损失和风格损失。内容损失用于保留输入图像的内容信息,而风格损失用于捕捉毕加索画风中的纹理、色彩和细节信息。

3.将两个损失函数加权相加得到总损失函数,并通过随机梯度下降等优化算法来最小化总损失函数,以达到将毕加索的艺术风格应用到输入图像上的目的。

4.对于新的输入图像,使用已经训练好的模型来进行风格迁移。

注意:毕加索风格迁移算法中的损失函数需要使用预训练好的VGG网络等。此外,在实现算法时,一些超参数的选择也会对成果产生影响,如内容和风格损失的权重、学习率、训练迭代次数等。因此,在实现算法时需要进行一定的调参操作,以获得较好的迁移效果。

 图像风格转化:

二、图像风格迁移原理

2.1. VGG网络

我们使用预训练的VGG-19网络作为特征提取器,它可以捕捉图像的内容和风格特征。VGG-19网络的结构比较简单,其名称是由其层数和单元数组合而成的,共有19层(同时包含了卷积层,池化层和全连接层),其中13个是卷积层,5个是池化层,1个是全局平均池化层,最后接上全连接层作为分类器。

 2.2. 内容损失

内容损失衡量输出图像与内容图像在某个层的特征表示之间的差异。我们通常使用较高层的特征表示,以保留图像的整体内容。

L_{content}(\vec{p}, \vec{x}, l) = \frac{1}{2} \sum_{i, j} (F_{ij}^l(\vec{p}) - F_{ij}^l(\vec{x}))^2,

其中\vec{p}是内容图像,\vec{x}是输出图像,F_{ij}^l(\cdot)是给定图像在层l的特征表示。

2.3. 风格损失

风格损失衡量输出图像与风格图像在各层的特征表示之间的差异。我们通常使用Gram矩阵来衡量风格特征。

L_{style}(\vec{a}, \vec{x}, l) = \frac{1}{4N_l^2M_l^2} \sum_{i, j}(G_{ij}^l(\vec{a}) - G_{ij}^l(\vec{x}))^2

其中\vec{a}是风格图像,G_{ij}^l(\cdot)是给定图像在层l的Gram矩阵,N_lM_l分别是层l的通道数和特征图的大小。

2.4. 总损失

我们的目标是最小化内容损失和风格损失的加权和。

L(\vec{p}, \vec{a}, \vec{x}) = \alpha L_{content}(\vec{p}, \vec{x}) + \beta L_{style}(\vec{a}, \vec{x}),

其中\alpha\beta是内容损失和风格损失的权重。

三、算法实现

import torch
import torchvision.transforms as transforms
from PIL import Image

def load_image(image_path, max_size=None, shape=None):
    image = Image.open(image_path)
    if max_size:
        scale = max_size / max(image.size)
        size = tuple([int(dim * scale) for dim in image.size])
        image = image.resize(size, Image.ANTIALIAS)

    if shape:
        image = image.resize(shape, Image.LANCZOS)

    transform = transforms.Compose([
        transforms.ToTensor()
    ])

    image = transform(image)[:3, :, :].unsqueeze(0)
    return image

def deprocess(tensor):
    transform = transforms.Compose([
        transforms.Normalize((-0.485 / 0.229, -0.456 / 0.224, -0.406 / 0.225),
                             (1 / 0.229, 1 / 0.224, 1 / 0.225)),
        transforms.ToPILImage()
    ])
    if tensor.dim() == 4:
        # If we have a batch of images
        output = []
        for image in tensor:
            image = image.clone().detach().cpu()
            image = image.squeeze(0)
            image = transform(image)
            output.append(image)
        return output[0]
    elif tensor.dim() == 3:
        # If we have a single image
        tensor = tensor.clone().detach().cpu()
        tensor = tensor.squeeze(0)
        tensor = transform(tensor)
        return tensor
    else:
        raise ValueError("Expected input tensor to be 3D or 4D")
    return transform(tensor)

import torch.nn as nn
import torchvision.models as models

class StyleTransferModel(nn.Module):
    def __init__(self, content_layers, style_layers):
        super(StyleTransferModel, self).__init__()
        self.vgg = models.vgg19(pretrained=True).features
        self.content_layers = content_layers
        self.style_layers = style_layers

    def forward(self, x):
        content_features = []
        style_features = []
        #print(list(self.vgg.named_children()))
        for name, layer in self.vgg.named_children():
            x = layer(x)
            if name in self.content_layers:
                content_features.append(x)
            if name in self.style_layers:
                style_features.append(x)

        return content_features, style_features

def gram_matrix(tensor):
    _, c, h, w = tensor.size()
    tensor = tensor.view(c, h * w)
    gram = torch.mm(tensor, tensor.t())
    return gram

import torch.optim as optim

def style_transfer(content_image_path, style_image_path, output_image_path, max_size=400, content_weight=1, style_weight=1e6, iterations=600):
    content_image = load_image(content_image_path, max_size=max_size)
    style_image = load_image(style_image_path, shape=content_image.shape[-2:])
    output_image = content_image.clone().requires_grad_(True)

    model = StyleTransferModel(content_layers=['10'], style_layers=['0','2','5','7','12'])
    #model.to(device)

    content_features = model(content_image)[0]
    style_features = model(style_image)[1]
    style_grams = [gram_matrix(feature) for feature in style_features]

    optimizer = optim.Adam([output_image], lr=0.01)
    for i in range(iterations):
        output_features = model(output_image)
        content_output_features = output_features[0]
        style_output_features = output_features[1]

        content_loss = 0.0
        style_loss = 0.0

        for target_feature, output_feature in zip(content_features, content_output_features):
            content_loss += torch.mean((output_feature - target_feature) ** 2)

        for target_gram, output_feature in zip(style_grams, style_output_features):
            output_gram = gram_matrix(output_feature)
            style_loss += torch.mean((output_gram - target_gram) ** 2) / (output_gram.numel() ** 2)

        total_loss = content_weight * content_loss + style_weight * style_loss

        optimizer.zero_grad()
        total_loss.backward(retain_graph=True)
        optimizer.step()

        if (i + 1) % 5 == 0:
            print(f"Iteration {i + 1}/{iterations}: Loss = {total_loss.item()}")

    output_image = deprocess(output_image)
    print(output_image)
    output_image.save(output_image_path)

content_image_path = "123.png"
style_image_path = "style.png"
output_image_path = "out.png"

style_transfer(content_image_path, style_image_path, output_image_path)

我们只要输入要迁移的图片123.png,图片的风格style.png,就可以生成图片了

4. 总结

本文详细介绍了基于CNN网络的毕加索风格图像迁移的原理和实现方法,使用PyTorch框架实现了一个简单有效的算法。实验结果表明,该方法可以成功地将毕加索风格应用到任意图像上,生成高质量的艺术作品。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/557670.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

chatgpt赋能Python-python_fig

Python中的fig:简介和应用 什么是fig? fig是Python中一个高效且易用的图形库,它支持大量的图像绘制功能,包括2D图形绘制、曲线和图像处理,以及3D图形和动画绘制等应用。fig可以在多个平台上运行,包括Wind…

客户体验|审美体验与体验管理

Guofu 第 93⭐️ 篇原创文章分享 (点击👆🏻上方卡片关注我,加⭐️星标⭐️~) 🚏 写在前面 伽达默尔说:“如果某个东西被经历过,而且它的经历存在还获得一种使自身继续存在意义的特征…

chatgpt赋能Python-python_har

Python HAR:一种高效的网络监测工具 Python HAR(HTTP Archive)是一个用于监测网络资源的强大工具,它能够记录网络请求、响应和资源加载的细节信息,并以可视化和格式化的方式呈现出来。Python HAR的应用范围广泛&#…

单模光纤二维模场分布的MATLAB仿真

在上一篇文章中,我们介绍了单模光纤的一维模场分布,能看出沿着径向的光场分布情况,并分析能量的分布 这一篇中,我们绘制光纤横截面上的二维光场分布:代码如下: clear close all V 2.4000; U 1.6453; W …

C4D R26 渲染学习笔记(1):C4D版本选择和基础知识(更新中)

C4D版本知识 C4D通过R来进行版本区分,现在2023年5月22日最新版的是R26。说一下特殊版本。 C4D版本介绍特点R19OC快乐版3.07最高版本,OC是C4D最具性价比的渲染器,OC学习成本低,渲染速度快,但是注意OC 3.07只支持10系N…

如何提取微信公众号的链接?非常简单!

今天在公众号里面想要复制公众号链接,用于小程序里面引导用户关注,因为小程序里面的关注公众号只能是扫码小程序才能使用,想起以前使用的原始链接跳转方法,就想试一试,结果公众号后台居然没有链接可以复制了&#xff0…

代码随想录算法训练营day49 | 121. 买卖股票的最佳时机,122.买卖股票的最佳时机II

代码随想录算法训练营day49 | 121. 买卖股票的最佳时机,122.买卖股票的最佳时机II 121. 买卖股票的最佳时机解法一:动态规划解法二:贪心算法 122.买卖股票的最佳时机II解法一:动态规划解法二:贪心算法 121. 买卖股票的…

数据要素流通使用的安全风险分析及应对策略

数据要素流通使用的安全风险分析及应对策略 刘业政1,2, 宗兰芳1, 金斗1,袁昆1,2 1 合肥工业大学管理学院,安徽 合肥 230009 2 大数据流通与交易技术国家工程实验室,上海 201203 摘要:系统地分析了数据要素流通使用过程中存在的安全…

直播预告 | 医疗人工智能入行经验分享

(本文阅读时间:2 分钟) 或许大家从不同程度上听说或使用过智能导诊机器人、语音电子病历或是智能问诊?这些高端大气又便利的产物都是人工智能在医疗健康领域的重要应用场景产品及服务。 “AI医疗”是人工智能技术赋能医疗健康产业…

综述 | 基于 Transformer 网络的多模态学习

关注公众号,发现CV技术之美 Transformer 网络结构作为一种性能卓越的神经网络学习器,已经在各类机器学习问题中取得了巨大的成功。伴随着近年来多模态应用和多模态大数据的蓬勃发展,基于Transformer 网络的多模态学习已经成为了人工智能领域的…

chatgpt赋能Python-python_for_loop

Python For Loop: 了解循环结构控制的重要性 在Python编程中,循环结构控制是必备技能之一。它允许程序员重复执行指定的代码块,而不需要手动多次输入。Python提供了几种类型的循环结构,其中for循环是最常用的之一。我们将在本文中讨论for循环…

( 回溯算法) 332. 重新安排行程 ——【Leetcode每日一题】

❓332. 重新安排行程 难度:困难 给你一份航线列表 tickets ,其中 tickets[i] [fromi, toi] 表示飞机出发和降落的机场地点。请你对该行程进行重新规划排序。 所有这些机票都属于一个从 JFK(肯尼迪国际机场)出发的先生&#xf…

【泛微ecology_oracle】如何把查询到的单列人力资源id合并成多人力资源格式

如何把查询到的单列人力资源id合并成多人力资源格式 在泛微ecology中,单列人力资源id合并成多人力资源的使用场景在泛微ecology中,在数据库里人员姓名存储形式那如何实现人力资源字段合并多人力资源字段呢? 在泛微ecology中,单列人…

Node.js博客项目开发思路笔记

博客项目介绍 1. 目标 开发一个博客系统,具备博客基本功能只开发 server 端,不关心前端 2. 需求 首页、作者页、博客详情页登陆页管理中心、新建页、编辑页 3. 技术方案 数据如何存储 博客 idtitlecontentcreatetimeauthor1标题 1内容 11111112z…

Vue购物车实例练习

功能介绍 金额 单价 * 数量金额会自动根据数量的变化进行变化,我们可以点击按钮增加或减少商品的数量。合计金额:只有在序号列号勾选上才会被计入总金额中,金额总数会根据用户的操作自动更新数据。删除:如图我们勾选了第2个商品&…

【开源项目】Easy-Trans数据翻译服务的快速入门及原理解析

项目介绍 easy-trans是一款用于做数据翻译的代码辅助插件&#xff0c;利用mybatis plus/jpa/beetsql 等ORM框架的能力自动查表&#xff0c;让开发者可以快速的把id/字典码 翻译为前端需要展示的数据。 快速入门 maven依赖 <properties> <fhs.release.version>2.…

痞子衡嵌入式:MCUBootUtility v5.0发布,初步支持i.MXRT1180

--   痞子衡维护的NXP-MCUBootUtility工具距离上一个大版本(v4.0.0)发布过去4个多月了&#xff0c;期间痞子衡也做过两个小版本更新&#xff0c;但不足以单独介绍。这一次痞子衡为大家带来了全新大版本v5.0.0&#xff0c;这次更新主要是想和大家特别聊聊恩智浦新一代 i.MXRT …

一个传统剧团的自救

今天我和大家分享一个 最近我在网上看到的案例。 是这样说的 在岭南地区 有一个较为偏远的地方 当地有一个传统的戏团 他们依托当地传统习俗 把戏曲一代一代流传下来 但是到了现在。 戏团面临传承中断 戏团解散的困境。 当地文化宣传员小林 知道这个情况后。 立马展开调查 并且…

Linux——gcc/g++编译器

gcc是用来编译C语言代码的编译器&#xff0c;而g是用来编译C代码的编译器的。 而gcc和g都是软件&#xff0c;需要使用yum进行下载 注&#xff1a;需要使用root权限才能下载 在C语言编译的过程中&#xff0c;会有四个过程: 1预处理&#xff0c;2编译&#xff0c;3汇编&#xf…

CB06551 PRD-B040SSIB-63

​ CB06551 PRD-B040SSIB-63 步进电机驱动器有什么参数   步进电机驱动器基本参数如下&#xff1a; a、供电电源&#xff0c;可据所驱动步进电机的电源规格进行选择。交流电源供电的&#xff0c;如AC80V&#xff0c;可用220V市电经降压变压器&#xff0c;提供给驱动器。选用变…