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, 512w, h = map(lambda x: x - x % 32, (w, h))  # resize to integer multiple of 32mask = mask.resize((w // 8, h // 8), resample = PIL.Image.NEAREST) # 64, 64mask = np.array(mask).astype(np.float32) / 255.0 # 归一化 64, 64mask = np.tile(mask, (4, 1, 1)) # 4, 64, 64mask = mask[None].transpose(0, 1, 2, 3)mask = 1 - mask  # repaint white, keep black # mask图中,mask的部分变为0mask = torch.from_numpy(mask)return mask# 预处理image
def preprocess(image):w, h = image.sizew, h = map(lambda x: x - x % 32, (w, h))  # resize to integer multiple of 32image = image.resize((w, h), resample=PIL.Image.LANCZOS)image = np.array(image).astype(np.float32) / 255.0image = image[None].transpose(0, 3, 1, 2)image = torch.from_numpy(image)return 2.0 * image - 1.0if __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# 读取输入图像和输入maskinput_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. 加载autoencodervae = 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. 加载扩散模型UNetunet = UNet2DConditionModel.from_pretrained(model_id, subfolder = "unet")# 4. 定义noise schedulernoise_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.75guidance_scale = 7.5batch_size = 1num_inference_steps = 50generator = torch.Generator(device).manual_seed(0)with torch.no_grad():# get prompt text_embeddingstext_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 embeddingsmax_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 batchtext_embeddings = torch.cat([uncond_embeddings, text_embeddings])# 设置采样步数noise_scheduler.set_timesteps(num_inference_steps, device = device)# 根据strength计算timestepsinit_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_imageinit_input = preprocess(input_image)init_latents = vae.encode(init_input.to(device, dtype=torch.float16)).latent_dist.sample(generator)init_latents = 0.18215 * init_latentsinit_latents = torch.cat([init_latents] * batch_size, dim=0)init_latents_orig = init_latents# 处理maskmask_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 stepsfor t in tqdm(timesteps):# 这里latens扩展2份,是为了同时计算unconditional predictionlatent_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 Guidancenoise_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-1latents = noise_scheduler.step(noise_pred, t, latents).prev_sample# 将unmask区域替换原始图像的nosiy latentsinit_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进行scalelatents = 1 / 0.18215 * latentsimage = vae.decode(latents).sample# 转成pillowimg = (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 StableDiffusionInpaintPipelineLegacyif __name__ == "__main__":# load inpainting pipelinemodel_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 pathpipe = StableDiffusionInpaintPipelineLegacy.from_pretrained(model_id, torch_dtype = torch.float16).to("cuda")# load input image and input maskinput_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 inferenceprompt = ["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# 转成pillowfor idx, image in enumerate(images):image.save("./outputs/output_{:d}.png".format(idx))print("All Done!")

运行结果:

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

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

相关文章

flutter 手写 TabBar

前言: 这几天在使用 flutter TabBar 的时候 我们的设计给我提了一个需求: 如下 Tabbar 第一个元素 左对齐,试了下TabBar 的配置,无法实现这个需求,他的 配置是针对所有元素的。而且 这个 TabBar 下面的 滑块在移动的时…

4.定时器

原理 时钟源:定时器是内部时钟源(晶振),计数器是外部计时长度:对应TH TL计数器初值寄存器(高八位,低八位)对应的中断触发函数 中断源中断处理函数Timer0Timer0_Routine(void) interrupt 1Timer1Timer1_Routine(void) …

爬虫学习 | 01 Web Scraper的使用

目录 背景介绍: 第一部分:Web Scraper简介 1.什么是Web Scraper: Web Scraper🛒 主要用途: 2.为什么选择Web Scraper: 第二部分:安装Web Scraper ​​​​​1.打开google浏览器&#xf…

object-C 解答算法:合并两个有序数组(leetCode-88)

合并两个有序数组(leetCode-88) 题目如下图:(也可以到leetCode上看完整题目,题号88) 首先搞懂,什么叫“非递减顺序” 非递减顺序,是指一个序列中的元素从前往后(或从左到右)保持不减少或相等。 这意味着序列中的元素可以保持相同的值,但不会…

实战:SpringBoot扩展功能ExitCodeGenerator生成的退出代码

1. 简介 ExitCodeGenerator是 Spring Boot 框架中的一个接口,它允许应用程序退出时生成自定义的退出代码。你可以根据不同的退出码,执行相应的动作,如:资源清理,日志记录等。 我们可以通过实现ExitCodeGenerator接口…

全网最适合入门的面向对象编程教程:17 类和对象的Python实现-鸭子类型与“file-like object“

全网最适合入门的面向对象编程教程:17 类和对象的 Python 实现-鸭子类型与“file-like object“ 摘要: 本文主要介绍了 Python 中创建自定义类时鸭子类型的基本定义、特点和应用场景,同时列举了**“file-like object“** 的例子对鸭子类型进…

axios以post方式提交表单形式数据

某些后端框架请求接口必须走form表单提交的那种形式&#xff0c;但前端很少有<form action"接口地址" method"post"></form>这种写法去提交表单数据&#xff0c;所以前端需要用axios模拟一个表单提交接口。 Content-Type 代表发送端&#xff0…

单链表的介绍和实现

前言 Hello,小伙伴们&#xff0c;你们的作者君又回来了&#xff0c;今天我将带领大家继续学习另一种线性表&#xff1a;单链表&#xff0c; 准备好的小伙伴三连打卡上车&#xff0c;你们的支持就是我更新的动力&#xff0c;一定不要吝啬手中的三连哟&#xff0c;万分感谢&…

ElementUI el-select 组件动态设置disabled后,高度变更的问题解决办法

问题描述 Vue2 项目在使用 el-select 组件时&#xff0c;动态将disabled变更为了 true&#xff0c;元素的高度发生了变化。 问题原因 通过浏览器开发人员工具面板&#xff0c;发现&#xff0c;组件内的 input 元素被动态设置了height的样式&#xff1a; 在项目中检查后并…

深度解析:如何优雅地删除GitHub仓库中的特定commit历史

&#x1f49d;&#x1f49d;&#x1f49d;欢迎莅临我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:「stormsha的主页」…

three.js创建基础模型

场景是一个三维空间&#xff0c;是所有物品的容器。可以将其想象成一个空房间&#xff0c;里面可以放置要呈现的物体、相机、光源等。 通过new THREE.Scene()来创建一个新的场景。 /**1. 创建场景 -- 放置物体对象的环境*/ const scene new THREE.Scene();场景只是一个三维的…

django学习入门系列之第四点《案例 后台管理样例》

文章目录 往期回顾 前期准备&#xff1a; 导航新建&#xff0c;按钮表格 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>Title</title><!-- 开发版本 --><link rel"stylesheet…

2024-07-16 Unity插件 Odin Inspector6 —— Group Attributes

文章目录 1 说明2 Group 特性2.1 BoxGroup2.2 ButtonGroup2.3 FoldoutGroup2.4 ShowIfGroup / HideIfGroup2.5 HorizontalGroup2.6 ResponsiveButtonGroup2.7 TabGroup2.8 ToggleGroup2.9 VerticalGroup 1 说明 ​ 本文介绍 Odin Inspector 插件中有关 Group 特性的使用方法。…

【解决问题】permission denied while trying to connect to the Docker daemon socket

解决方法 sudo usermod -aG docker $USER 运行上面命令&#xff0c;将当前用户添加到 docker 组&#xff0c;重启电脑。 GPT-4o (OpenAI) 看起来你在尝试通过 make build 构建项目时遇到了权限问题&#xff0c;尤其是在拉取 Docker 镜像时没有权限访问 Docker 的 Unix 套接…

如何使用 GPT?

​通过实例&#xff0c;来展示如何最好地使用 GPT。 生成文字 假设你在写一篇文章&#xff0c;需要在结尾加上这样一句&#xff1a;「California’s population is 53 times that of Alaska.」&#xff08;加州的人口是阿拉斯加州的 53 倍&#xff09;。 但现在你不知道这两个…

谷歌准备斥资 230 亿收购网络安全初创公司 Wiz

Alphabet 正在就收购 Wiz 进行深入谈判&#xff0c;这将显著增强其安全能力。这将是谷歌母公司有史以来最大规模的收购。 这是路透社根据匿名消息来源撰写的内容。目标收购金额为230亿美元&#xff0c;即211亿欧元。 Wiz 拥有实时检测和响应网络威胁的技术。通过实施人工智能…

有关电力电子技术的一些相关仿真和分析:⑥单相相控调压电路与单相斩控调压电路(MATLAB/Siumlink仿真)

针对单相相控调压电路&#xff0c;仿真研究对于给定负载&#xff0c;不同触发角作用下&#xff0c;输出电压波形和输入电流波形&#xff08;对照电网电压&#xff09;&#xff0c;研究输出电压有效值随触发角变化的规律&#xff0c;讨论并验证输入电流连续的条件。采用相同的电…

WPF实现一个带旋转动画的菜单栏

WPF实现一个带旋转动画的菜单栏 一、创建WPF项目及文件1、创建项目2、创建文件夹及文件3、添加引用 二、代码实现2.ControlAttachProperty类 一、创建WPF项目及文件 1、创建项目 打开VS2022,创建一个WPF项目&#xff0c;如下所示 2、创建文件夹及文件 创建资源文件夹&…

<Qt> 初识Qt

目录 一、项目文件解析 widget.h main.cpp widget.cpp widget.ui .pro文件 二、QT 实现Hello World程序 &#xff08;一&#xff09;按钮控件 1. 纯代码 2. 图形化 &#xff08;二&#xff09;标签控件 1. 纯代码 2. 图形化 三、内存泄漏问题 四、qdebug()的使用…

php基础: 三角形

包含&#xff1a;左三角、左上三角、右三角、右上三角、等腰三角、倒等腰三角。注意空格的数量&#xff0c;因为*号后面加了空格 /*** * 左三角形* param $n* return void*/ function triangleLeft($n){echo <pre>;for ($i 1; $i < $n; $i) {for ($j 1; $j < $i…