AIGC笔记--基于Stable Diffusion实现图片的inpainting

1--完整代码

SD_Inpainting

2--简单代码

import PIL
import torch
import numpy as np
from PIL import Image
from tqdm import tqdm
import torchvision
from diffusers import AutoencoderKL, UNet2DConditionModel, DDIMScheduler
from transformers import CLIPTextModel, CLIPTokenizer

# 预处理mask
def preprocess_mask(mask):
    mask = mask.convert("L") # 转换为灰度图: L = R * 299/1000 + G * 587/1000+ B * 114/1000。
    w, h = mask.size # 512, 512
    w, h = map(lambda x: x - x % 32, (w, h))  # resize to integer multiple of 32
    mask = mask.resize((w // 8, h // 8), resample = PIL.Image.NEAREST) # 64, 64
    mask = np.array(mask).astype(np.float32) / 255.0 # 归一化 64, 64
    mask = np.tile(mask, (4, 1, 1)) # 4, 64, 64
    mask = mask[None].transpose(0, 1, 2, 3)
    mask = 1 - mask  # repaint white, keep black # mask图中,mask的部分变为0
    mask = torch.from_numpy(mask)
    return mask

# 预处理image
def preprocess(image):
    w, h = image.size
    w, h = map(lambda x: x - x % 32, (w, h))  # resize to integer multiple of 32
    image = image.resize((w, h), resample=PIL.Image.LANCZOS)
    image = np.array(image).astype(np.float32) / 255.0
    image = image[None].transpose(0, 3, 1, 2)
    image = torch.from_numpy(image)
    return 2.0 * image - 1.0

if __name__ == "__main__":
    model_id = "runwayml/stable-diffusion-v1-5" # online download
    # model_id = "/mnt/dolphinfs/hdd_pool/docker/user/hadoop-waimai-aigc/liujinfu/All_test/test0714/huggingface.co/runwayml/stable-diffusion-v1-5" # local path

    # 读取输入图像和输入mask
    input_image = Image.open("./images/overture-creations-5sI6fQgYIuo.png").resize((512, 512))
    input_mask = Image.open("./images/overture-creations-5sI6fQgYIuo_mask.png").resize((512, 512))

    # 1. 加载autoencoder
    vae = AutoencoderKL.from_pretrained(model_id, subfolder = "vae")

    # 2. 加载tokenizer和text encoder 
    tokenizer = CLIPTokenizer.from_pretrained(model_id, subfolder = "tokenizer")
    text_encoder = CLIPTextModel.from_pretrained(model_id, subfolder = "text_encoder")

    # 3. 加载扩散模型UNet
    unet = UNet2DConditionModel.from_pretrained(model_id, subfolder = "unet")

    # 4. 定义noise scheduler
    noise_scheduler = DDIMScheduler(
        num_train_timesteps = 1000,
        beta_start = 0.00085,
        beta_end = 0.012,
        beta_schedule = "scaled_linear",
        clip_sample = False, # don't clip sample, the x0 in stable diffusion not in range [-1, 1]
        set_alpha_to_one = False,
    )

    # 将模型复制到GPU上
    device = "cuda"
    vae.to(device, dtype = torch.float16)
    text_encoder.to(device, dtype = torch.float16)
    unet = unet.to(device, dtype = torch.float16)

    # 设置prompt和超参数
    prompt = "a mecha robot sitting on a bench"
    negative_prompt = ""
    strength = 0.75
    guidance_scale = 7.5
    batch_size = 1
    num_inference_steps = 50
    generator = torch.Generator(device).manual_seed(0)

    with torch.no_grad():
        # get prompt text_embeddings
        text_input = tokenizer(prompt, padding = "max_length", 
            max_length = tokenizer.model_max_length, 
            truncation = True, 
            return_tensors = "pt")
        text_embeddings = text_encoder(text_input.input_ids.to(device))[0]

        # get unconditional text embeddings
        max_length = text_input.input_ids.shape[-1]
        uncond_input = tokenizer(
            [negative_prompt] * batch_size, padding = "max_length", max_length = max_length, return_tensors = "pt"
        )
        uncond_embeddings = text_encoder(uncond_input.input_ids.to(device))[0]
        # concat batch
        text_embeddings = torch.cat([uncond_embeddings, text_embeddings])

        # 设置采样步数
        noise_scheduler.set_timesteps(num_inference_steps, device = device)

        # 根据strength计算timesteps
        init_timestep = min(int(num_inference_steps * strength), num_inference_steps)
        t_start = max(num_inference_steps - init_timestep, 0)
        timesteps = noise_scheduler.timesteps[t_start:]

        # 预处理init_image
        init_input = preprocess(input_image)
        init_latents = vae.encode(init_input.to(device, dtype=torch.float16)).latent_dist.sample(generator)
        init_latents = 0.18215 * init_latents
        init_latents = torch.cat([init_latents] * batch_size, dim=0)
        init_latents_orig = init_latents

        # 处理mask
        mask_image = preprocess_mask(input_mask)
        mask_image = mask_image.to(device=device, dtype=init_latents.dtype)
        mask = torch.cat([mask_image] * batch_size)
        
        # 给init_latents加噪音
        noise = torch.randn(init_latents.shape, generator = generator, device = device, dtype = init_latents.dtype)
        init_latents = noise_scheduler.add_noise(init_latents, noise, timesteps[:1])
        latents = init_latents # 作为初始latents

        # Do denoise steps
        for t in tqdm(timesteps):
            # 这里latens扩展2份,是为了同时计算unconditional prediction
            latent_model_input = torch.cat([latents] * 2)
            latent_model_input = noise_scheduler.scale_model_input(latent_model_input, t) # for DDIM, do nothing

            # 预测噪音
            noise_pred = unet(latent_model_input, t, encoder_hidden_states=text_embeddings).sample

            # Classifier Free Guidance
            noise_pred_uncond, noise_pred_text = noise_pred.chunk(2)
            noise_pred = noise_pred_uncond + guidance_scale * (noise_pred_text - noise_pred_uncond)

            # x_t -> x_t-1
            latents = noise_scheduler.step(noise_pred, t, latents).prev_sample
            
            # 将unmask区域替换原始图像的nosiy latents
            init_latents_proper = noise_scheduler.add_noise(init_latents_orig, noise, torch.tensor([t]))
            # mask的部分数值为0
            # 因此init_latents_proper * mask为保留原始latents(不mask)
            # 而latents * (1 - mask)为用生成的latents替换mask的部分
            latents = (init_latents_proper * mask) + (latents * (1 - mask)) 

        # 注意要对latents进行scale
        latents = 1 / 0.18215 * latents
        image = vae.decode(latents).sample
        
        # 转成pillow
        img = (image / 2 + 0.5).clamp(0, 1).detach().cpu()
        img = torchvision.transforms.ToPILImage()(img.squeeze())
        img.save("./outputs/output.png")
        print("All Done!")

运行结果:

3--基于Diffuser进行调用

import torch
import torchvision
from PIL import Image
from diffusers import StableDiffusionInpaintPipelineLegacy

if __name__ == "__main__":
    # load inpainting pipeline
    model_id = "runwayml/stable-diffusion-v1-5"
    # model_id = "/mnt/dolphinfs/hdd_pool/docker/user/hadoop-waimai-aigc/liujinfu/All_test/test0714/huggingface.co/runwayml/stable-diffusion-v1-5" # local path
    pipe = StableDiffusionInpaintPipelineLegacy.from_pretrained(model_id, torch_dtype = torch.float16).to("cuda")

    # load input image and input mask
    input_image = Image.open("./images/overture-creations-5sI6fQgYIuo.png").resize((512, 512))
    input_mask = Image.open("./images/overture-creations-5sI6fQgYIuo_mask.png").resize((512, 512))

    # run inference
    prompt = ["a mecha robot sitting on a bench", "a cat sitting on a bench"]
    generator = torch.Generator("cuda").manual_seed(0)
    with torch.autocast("cuda"):
        images = pipe(
            prompt = prompt,
            image = input_image,
            mask_image = input_mask,
            num_inference_steps = 50,
            strength = 0.75,
            guidance_scale = 7.5,
            num_images_per_prompt = 1,
            generator = generator
        ).images

    # 转成pillow
    for idx, image in enumerate(images):
        image.save("./outputs/output_{:d}.png".format(idx))
    print("All Done!")

运行结果:

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

源码安装zabbix5.0.36完整版

源码安装zabbix5.0.36完整版 环境:CentOS Linux release 7.9,cpu:16,mem:32G软件包如下: zabbix-5.0.36.tar.gz mysql-8.0.28-linux-glibc2.17-x86_64-minimal.tar.xz nginx-1.6.2.tar.gz 1. 配置前准备 systemctl stop firewa…

K8s集群初始化遇到的问题

kubectl describe pod coredns-545d6fc579-s9g5s -n kube-system 找到原因1:CoreDNS Pod 处于 Pending 状态的原因是集群中的节点都带有 node.kubernetes.io/not-ready 污点 journalctl -u kubelet -f 14:57:59.178592 3553 remote_image.go:114] "PullIma…

集群节点状态异常的解决方式

文章目录 集群节点状态异常的解决方式问题概述解决方式1.关闭所有服务2.对所有集群删除Hadoop相关文件2.1 删除Hadoop系统运行时创建的临时数据和文件2.2 删除Hadoop的数据文件 3.重新对Hadoop节点进行初始化和启用4.重启服务,检查节点状态 集群节点状态异常的解决方…

Parallels Desktop 19 for Mac(PD19虚拟机)详细图文安装教程分享

Parallels Desktop 19是一款功能丰富、性能强大且易于使用的虚拟机软件,它可以让您在Mac上同时运行多个操作系统,为您提供更大的灵活性和兼容性。 Parallels Desktop 19 for Mac(PD19虚拟机)下载安装包 Parallels Desktop 19 for Mac(PD19虚拟机)详细图…

护眼台灯的功能作用有哪些?深挖台灯护眼是真的吗

随着现代生活方式的改变,孩子们面临着越来越多的视力挑战。在近视学生中,近10%为高度近视,且占比随年级升高而增长。幼儿园6岁儿童中有1.5%为高度近视,而高中阶段则达到了17.6%。为了守护孩子们的视力健康,在科技飞速发…

查看apk版本号

获取未安装的apk版本号 1. 使用aapt命令 使用cmd cd到aapt工具的位置。位于‌Android SDK的build-tools目录下。 使用aapt命令,指向apk所在绝对路径 aapt dump badging your_apk_file.apk (win7按住shift键,右键apk文件选择“复制为路径”…

自学鸿蒙HarmonyOS的ArkTS语言<十>@BuilderParam装饰器

作用:当子组件多处使用时,给某处的子组件添加特定功能 一、初始化 1、只能被Builder装饰的方法初始化 2、使用所属自定义组件的builder方法初始化 3、使用父组件的builder方法初始化 - 把父组件的builder传过去,参数名和子组件的builderPar…

Android NDK开发之震动服务客户端编写程序(C++)

一、背景 最近有个小伙伴问我可不可以写一个可执行程序(C/C) 来实现Android设备的震动的功能。 作为一个多年的Android开发者,我觉得这是可以实现的。 但是由于过去我一直做App开发,也就把这个实现过程想简单了。 经过了几天的折腾,终于算是…

【python学习】numpy第三方库的定义、功能、使用场景和使用以及遇到的一些问题

引言 python学习学习到第三方库知识,首先学习的就是机器学习以及对应的numpy第三方库 文章目录 引言一、numpy第三方库的定义二、numpy第三方库的功能2.1数组操作2.2 线性代数计算2.3 随机数生成2.4 文件读写 三、numpy第三方库的使用场景3.1需要进行数值计算3.2 需…

【连续四届EI检索|稳定ACM出版、EI检索|线上线下结合】2024年第五届医学人工智能国际学术会议(ISAIMS 2024,8月13-17)

第五届医学人工智能国际学术会议(ISAIMS2024)将于2024年8月13-17日于荷兰阿姆斯特丹自由大学召开,国内分会场将于2024年10月25-27日于中国武汉召开。 会议自2020年至今已经成功举办四届,吸引了来自海内外相关领域学者600余名。本届…

C# Opencv实现本地以图搜图

地址:冯腾飞/本地以图搜图

【找不到视图问题解决】@RestController 与 @Controller注解的使用区别

一、问题描述 苍穹外卖在菜品分页查询功能实现的过程中,出现了找不到视图的情况 2024-07-12 21:54:20.860 ERROR 22488 --- [nio-8080-exec-4] o.a.c.c.C.[.[.[/].[dispatcherServlet] : Servlet.service() for servlet [dispatcherServlet] in context with p…

OpenSceneGraph学习笔记

目录 引言第一章:OSG概述一、前言(1)为什么要学习OSG?(2)OSG的组成(3)OSG的智能指针(4)OSG的安装编译 二、第一个OSG程序(1)Hello OSG程序&#…

移动UI:具备什么特征,可以被认定为科技风格。

移动UI设计在科技风格上通常具备以下特征: 1. 清晰简洁的排版: 科技风格的移动UI通常采用清晰简洁的排版,注重信息的层次感和结构化,以便用户能够快速、直观地获取所需信息。 2. 几何形状和线条: 科技风格的移动UI常…

Vscode ssh远程连接Linux服务器登录时密码password无法输入

问题 最近在用Vscode远程连接Linux服务器时,在终端提示输入密码password的时候用键盘输入没有反应。 以为是键盘坏了,然后尝试复制粘贴没有用。 后来找到了原因以及解决方法,感谢原帖作者(原贴链接粘在下面) 原因 …

2024.7.16日 最新版 docker cuda container tookit下载!

nvidia官方指导 https://docs.nvidia.com/datacenter/cloud-native/container-toolkit/latest/install-guide.html 其实就是这几个命令,但是有墙: curl -fsSL https://nvidia.github.io/libnvidia-container/gpgkey | sudo gpg --dearmor -o /usr/shar…

知识图谱研究综述笔记

推荐导读:知识图谱Knowledge Graph Embeddings 论文标题:A Survey on Knowledge Graphs:Representation, Acquisition and Applications发表期刊:IEEE TRANSACTIONS ON NEURAL NETWORKS AND LEARNING SYSTEMS, 2021本文作者:Shaoxiong Ji, Shirui Pan, M…

[A-04] ARMv8/ARMv9-Cache的相关策略

ver0.3 前言 前面我们已经通过三篇文章反反复复的讲Cache的概念、结构、架构,相信大家对Cache已经大概有了初步的了解。这里简单归纳一下: (1) Cache从硬件视角看,是连接PE-Core和主存的一种存储介质,存储的数据是主存中数据的副本&#xf…

精选电脑视频录制软件,这3款让录制更高效!

随着信息技术的飞速发展,电脑视频录制软件在日常生活和工作中的应用越来越广泛。无论是教学演示、游戏录制、网络会议,还是个人创作,视频录制都扮演着不可或缺的角色。本文将详细介绍3款电脑视频录制软件,旨在帮助用户选择最适合自…

AI写作辅助工具,如何避免学术不端?

正如常言道,水边行走难免沾湿——虽然这个比喻并不完全适用——AI创作依赖于现有数据,其生成内容多基于已有素材。目前AI的智能尚未达到人类思维的复杂性,创作过程仍显机械。因此,AI撰写的文章常带有可辨识的特征。 在学术界&…