DragGAN编辑自定义图像

2023-12-05 13:40

本文主要是介绍DragGAN编辑自定义图像,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

 上一篇图文我们简要的看了DragGAN的官方源码,效果还可以,但是只能编辑StyleGAN生成的图片,没办编辑自定义的图片,当然如果需要编辑自己的图片,就需要将图片投影(或反转)到styleGAN预训练生成器的领域中。

01

什么是图像反转(inversion)

    反转是指将一个图像映射到生成模型的潜空间中,然后通过调整潜空间向量来修改图像的外观。反转过程旨在通过反向计算生成模型中的潜空间向量,将现实图像转换为生成模型可识别和编辑的形式。在图像编辑的上下文中,反转常用于在潜空间中进行编辑操作,然后将编辑后的潜空间向量转换为修改后的图像。通过这种方式,可以实现对图像的各种编辑操作,例如改变姿势、修改外貌特征或添加不同的风格。通过反转和编辑潜空间,可以实现对图像的高级编辑,同时保持图像的真实性和准确性。

    最近,出现了一系列利用预训练的StyleGAN的生成能力的高级面部编辑技术。为了成功地编辑一张图片,首先必须将该图片投影(或反转)到预训练生成器的领域中。然而,事实证明,StyleGAN的潜空间引入了一种固有的失真和可编辑性之间的权衡,也就是在保持原始外观和真实改变一些属性之间的权衡。从实际角度来看,这意味着对于位于生成器领域之外的面部,应用保持身份特征的面部潜空间编辑仍然具有挑战性。

02


PTI

   为了解决这个问题,有人提出了关键调整用于基于潜空间编辑真实图像的方法(Pivotal Tuning for Latent-based Editing of Real Images)。它是一种技术,通过微调生成模型的潜空间,使得可以对真实图像进行编辑。在这种方法中,首先需要将真实图像进行反转,将其映射到生成模型的潜空间。然后,通过调整潜空间向量,可以对图像进行各种编辑操作,例如改变外貌特征、调整姿势或添加不同的风格。关键调整的目标是在编辑图像时保持其身份特征的准确性和一致性。通过这种方式,可以在真实图像上应用基于潜空间的语义编辑技术,实现高级的图像修改。

    PTI原始论文,2106.05744.pdf (arxiv.org),研究目标,对于真实图片的高清编辑,论点:对于一个编辑任务,对于真实图片的映射到隐层空间后已经out of domain,导致生成的图片会有伪影,因提出了训练生成器,扩大生成器的输入domain,使得编辑后的采样点也在生成器的输入域范围内。所以,本文在训练的时候是pivotal tuning,轻微调整生成器,使得那些从真实图片映射至隐空间可能out of domain的点也能生成和输入一样的图像。这样既能保持编辑能力又能保持重构能力。

23428b2a08df8fb71a2dddb18cb7b03c.png

训练分两大步,首先是GANinversion,将真实图片映射到wp,然后以这个wp点去训练生成器来产生希望的图片,由于wp与真实图片的位置足够近,使得只需增强一些外形参数而不影响其他StyleGAN结构即可完成重构。(intuition的感觉就是先通过原始的GANinversion生成一张相似的脸,再通过finetun把这个相似的脸训练成和真实图片一样的脸)

03


PTI代码训练

    在论文中作者给出了代码仓库的地址:danielroich/PTI: Official Implementation for "Pivotal Tuning for Latent-based editing of Real Images" (ACM TOG 2022) https://arxiv.org/abs/2106.05744 (github.com)

        首先我们将代码clone下来,然后anaconda配置好环境,如果各位已经根据我上一篇图文跑通了GragGAN,用这个环境即可,实际上都是styleGAN的开发环境。如果各位在配置环境的时候出现了如下错误

839b420be06edbdf85f19a417b1613d1.png

大概率是cudatoolkit的版本不对,本人之前的版本是11.4,一直没跑通,后来换了很多版本,发现只有11.1可以用,那么pytorch的版本只能配合cu111的。

        然后我们需要配置好config文件下的paths_config各个路径,包括原始图片的路径,已经对齐图片的路径。

 接下来需要进行如下操作:

1、将需要编辑的图片放到配置的文件夹内,运行utils下的align_data.py,将图片处理成需要的格式和大小,处理后的图片会生成到你配置的路径下。

2、运行scripts下的run_pti.py,这个过程会生成对应的权重文件到scripts下的checkpoints文件夹下以及embedding权重文件到embeddings文件夹下。

3、原则上来说到这一步PTI的基本操作就已经完成了,但是要用到GragGAN里面,还需要将pt文件转换成pkl,所以还需要下面这个小脚本来进行转换。
import os
from configs import paths_config
import pickle
import torchclass pt2pkl:def __init__(self,modelpath):self.modelpath = modelpathself.model_id = []self.image_name = []file_list = os.listdir(self.modelpath)for file in file_list:name, ext = os.path.splitext(file)if ext == '.pt':self.model_id.append(name.split('_')[1])self.image_name.append(name.split('_')[2])def load_generators(self, model_id, image_name):with open(paths_config.stylegan2_ada_ffhq, 'rb') as f:old_G = pickle.load(f)['G_ema'].cuda()with open(f'{paths_config.checkpoints_dir}/model_{model_id}_{image_name}.pt', 'rb') as f_new:new_G = torch.load(f_new).cuda()return old_G, new_Gdef export_updated_pickle(self,new_G,model_id,image_name):print("Exporting large updated pickle based off new generator and ffhq.pkl")with open(paths_config.stylegan2_ada_ffhq, 'rb') as f:d = pickle.load(f)old_G = d['G_ema'].cuda() ## tensorold_D = d['D'].eval().requires_grad_(False).cpu()tmp = {}tmp['G_ema'] = old_G.eval().requires_grad_(False).cpu()# copy.deepcopy(new_G).eval().requires_grad_(False).cpu()tmp['G'] = new_G.eval().requires_grad_(False).cpu() # copy.deepcopy(new_G).eval().requires_grad_(False).cpu()tmp['D'] = old_Dtmp['training_set_kwargs'] = Nonetmp['augment_pipe'] = Nonewith open(f'{paths_config.checkpoints_dir}/model_{model_id}_{image_name}.pkl', 'wb') as f:pickle.dump(tmp, f)def pt2pkl_impl(self):for i in range(len(self.image_name)):use_multi_id_training = Falsegenerator_type = paths_config.multi_id_model_type if use_multi_id_training else self.image_name[i]old_G, new_G = self.load_generators(self.model_id[i], generator_type)self.export_updated_pickle(new_G, self.model_id[i],self.image_name[i])if __name__ == '__main__':modelpath = './checkpoints'file_list = os.listdir(modelpath)for file in file_list:name, ext = os.path.splitext(file)print(name,ext)pt2pkl_demo = pt2pkl(modelpath=modelpath)pt2pkl_demo.pt2pkl_impl()

checkpoints文件会转换成pkl格式。

04


GragGAN编辑自定义图片

    我们将第三步的生成的checkpoint文件和对应的embeddings文件复制到DragGAN工程中scripts/checkpoints文件夹下。

    然后需要对visualizer_drag_gradio.py文件进行如下修改:

    init_pkl = 'stylegan2_model_WRAFMRCPCXUC_AB'修改为你生成的pkl模型名字,注意一定要在名字前加上stylegan2,不然会无法识别 

     然后修改init_image

w_pivot = torch.load('0.pt',map_location=torch.device('cpu'))state['renderer'].init_network(state['generator_params'],  # resvalid_checkpoints_dict[state['pretrained_weight']],  # pklstate['params']['seed'],  # w0_seed,# None,  # w_loadw_pivot, # w_loadstate['params']['latent_space'] == 'w+',  # w_plus'const',state['params']['trunc_psi'],  # trunc_psi,state['params']['trunc_cutoff'],  # trunc_cutoff,None,  # input_transformstate['params']['lr']  # lr,)

接着就是见证奇迹的时刻python visualizer_drag_gradio.py

ac9ad54946605163b473d21e09574153.png

然后我们我们试试编辑他的头发

619b0decd550f5428e79d8b1b75e3645.png

哈哈,一键摆脱脱发困扰。

再试试另外的图像

d3bc3d5fdd0e14dc0f06f5710a5c19ba.png

这次让小薇给咱笑一个

43fb490e686301702f4e07e6281f8cd4.png

效果还是相当不错的。

    到这里基本实现了自定义图像的输入到styleGAN,但是这种方式实在是显得太笨拙了,每一张图像都需要反转一次,费时费力,每一张图像都需要两个不小的模型来支撑,实在是不具备量产的基础。当然硬件富裕的大佬除外。

想尝试的小伙伴点个关注,可以自行尝试下。

这篇关于DragGAN编辑自定义图像的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/457794

相关文章

springboot自定义注解RateLimiter限流注解技术文档详解

《springboot自定义注解RateLimiter限流注解技术文档详解》文章介绍了限流技术的概念、作用及实现方式,通过SpringAOP拦截方法、缓存存储计数器,结合注解、枚举、异常类等核心组件,... 目录什么是限流系统架构核心组件详解1. 限流注解 (@RateLimiter)2. 限流类型枚举 (

SpringBoot 异常处理/自定义格式校验的问题实例详解

《SpringBoot异常处理/自定义格式校验的问题实例详解》文章探讨SpringBoot中自定义注解校验问题,区分参数级与类级约束触发的异常类型,建议通过@RestControllerAdvice... 目录1. 问题简要描述2. 异常触发1) 参数级别约束2) 类级别约束3. 异常处理1) 字段级别约束

基于Python开发一个图像水印批量添加工具

《基于Python开发一个图像水印批量添加工具》在当今数字化内容爆炸式增长的时代,图像版权保护已成为创作者和企业的核心需求,本方案将详细介绍一个基于PythonPIL库的工业级图像水印解决方案,有需要... 目录一、系统架构设计1.1 整体处理流程1.2 类结构设计(扩展版本)二、核心算法深入解析2.1 自

SpringBoot+EasyExcel实现自定义复杂样式导入导出

《SpringBoot+EasyExcel实现自定义复杂样式导入导出》这篇文章主要为大家详细介绍了SpringBoot如何结果EasyExcel实现自定义复杂样式导入导出功能,文中的示例代码讲解详细,... 目录安装处理自定义导出复杂场景1、列不固定,动态列2、动态下拉3、自定义锁定行/列,添加密码4、合并

Java实现自定义table宽高的示例代码

《Java实现自定义table宽高的示例代码》在桌面应用、管理系统乃至报表工具中,表格(JTable)作为最常用的数据展示组件,不仅承载对数据的增删改查,还需要配合布局与视觉需求,而JavaSwing... 目录一、项目背景详细介绍二、项目需求详细介绍三、相关技术详细介绍四、实现思路详细介绍五、完整实现代码

一文详解Java Stream的sorted自定义排序

《一文详解JavaStream的sorted自定义排序》Javastream中的sorted方法是用于对流中的元素进行排序的方法,它可以接受一个comparator参数,用于指定排序规则,sorte... 目录一、sorted 操作的基础原理二、自定义排序的实现方式1. Comparator 接口的 Lam

如何自定义一个log适配器starter

《如何自定义一个log适配器starter》:本文主要介绍如何自定义一个log适配器starter的问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录需求Starter 项目目录结构pom.XML 配置LogInitializer实现MDCInterceptor

Python中OpenCV与Matplotlib的图像操作入门指南

《Python中OpenCV与Matplotlib的图像操作入门指南》:本文主要介绍Python中OpenCV与Matplotlib的图像操作指南,本文通过实例代码给大家介绍的非常详细,对大家的学... 目录一、环境准备二、图像的基本操作1. 图像读取、显示与保存 使用OpenCV操作2. 像素级操作3.

C/C++的OpenCV 进行图像梯度提取的几种实现

《C/C++的OpenCV进行图像梯度提取的几种实现》本文主要介绍了C/C++的OpenCV进行图像梯度提取的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的... 目录预www.chinasem.cn备知识1. 图像加载与预处理2. Sobel 算子计算 X 和 Y

c/c++的opencv图像金字塔缩放实现

《c/c++的opencv图像金字塔缩放实现》本文主要介绍了c/c++的opencv图像金字塔缩放实现,通过对原始图像进行连续的下采样或上采样操作,生成一系列不同分辨率的图像,具有一定的参考价值,感兴... 目录图像金字塔简介图像下采样 (cv::pyrDown)图像上采样 (cv::pyrUp)C++ O