Buckets:
| # ControlNet | |
| [ControlNet](https://huggingface.co/papers/2302.05543) は、テキストプロンプトを維持したまま、構造制御画像(エッジ、深度、ポーズなど)を用いて事前学習済み拡散モデルを制御します。ベースモデルを凍結し、デノイザーを導く残差を出力する並列ネットワークを追加することで、ファインチューニングなしにレイアウトの制御を実現します。 | |
| 必要なコントロール(canny など)に対応する ControlNet を読み込み、[from_pretrained()](/docs/diffusers/main/ja/api/pipelines/overview#diffusers.DiffusionPipeline.from_pretrained) に `controlnet=` として渡します。`controlnet_conditioning_scale` を使用して、コントロールが生成をどの程度強く誘導するかを設定します。 | |
| > [!TIP] | |
| > ControlNetは、[Flux](../api/pipelines/controlnet_flux)、[Hunyuan-DiT](../api/pipelines/controlnet_hunyuandit)、[Stable Diffusion 3](../api/pipelines/controlnet_sd3)など、多くのモデルで利用可能です。本ガイドの例では、FluxとStable Diffusion XLを使用しています。旧来のStable Diffusion系チェックポイントにおけるT2I-Adapterについては、[レガシーアダプター](./legacy_adapters#t2i-adapter)を参照してください。新しい制御可能な生成タスクには、ControlNetの使用を推奨します。 | |
| 以下のタブには、テキストから画像生成、画像から画像生成、インペインティング用のControlNetが表示されています。 | |
| [opencv-python](https://github.com/opencv/opencv-python)を使用してCannyエッジ画像を生成します。 | |
| ```py | |
| import cv2 | |
| import numpy as np | |
| from PIL import Image | |
| from diffusers.utils import load_image | |
| original_image = load_image( | |
| "https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/diffusers/non-enhanced-prompt.png" | |
| ) | |
| image = np.array(original_image) | |
| low_threshold = 100 | |
| high_threshold = 200 | |
| image = cv2.Canny(image, low_threshold, high_threshold) | |
| image = image[:, :, None] | |
| image = np.concatenate([image, image, image], axis=2) | |
| canny_image = Image.fromarray(image) | |
| ``` | |
| Canny画像をパイプラインに渡します。`controlnet_conditioning_scale` パラメータを使用して、コントロールに割り当てる重みを決定します。 | |
| ```py | |
| import torch | |
| from diffusers.utils import load_image | |
| from diffusers import FluxControlNetPipeline, FluxControlNetModel | |
| controlnet = FluxControlNetModel.from_pretrained( | |
| "InstantX/FLUX.1-dev-Controlnet-Canny", dtype=torch.bfloat16 | |
| ) | |
| pipeline = FluxControlNetPipeline.from_pretrained( | |
| "black-forest-labs/FLUX.1-dev", controlnet=controlnet, dtype=torch.bfloat16 | |
| ).to("cuda") # or "mps", "xpu", "cpu" | |
| prompt = """ | |
| A photorealistic overhead image of a cat reclining sideways in a flamingo pool floatie holding a margarita. | |
| The cat is floating leisurely in the pool and completely relaxed and happy. | |
| """ | |
| pipeline( | |
| prompt, | |
| control_image=canny_image, | |
| controlnet_conditioning_scale=0.5, | |
| num_inference_steps=50, | |
| guidance_scale=3.5, | |
| ).images[0] | |
| ``` | |
| 元の画像 | |
| canny image | |
| 生成された画像 | |
| Transformers の深度推定パイプラインを使用して深度マップを生成します。 | |
| ```py | |
| import torch | |
| import numpy as np | |
| from PIL import Image | |
| from transformers import DPTImageProcessor, DPTForDepthEstimation | |
| from diffusers import ControlNetModel, StableDiffusionXLControlNetImg2ImgPipeline, AutoencoderKL | |
| from diffusers.utils import load_image | |
| device = "cuda" # or "mps", "xpu", "cpu" | |
| depth_estimator = DPTForDepthEstimation.from_pretrained("Intel/dpt-hybrid-midas").to(device) | |
| feature_extractor = DPTImageProcessor.from_pretrained("Intel/dpt-hybrid-midas") | |
| def get_depth_map(image): | |
| image = feature_extractor(images=image, return_tensors="pt").pixel_values.to(device) | |
| with torch.no_grad(), torch.autocast(device): | |
| depth_map = depth_estimator(image).predicted_depth | |
| depth_map = torch.nn.functional.interpolate( | |
| depth_map.unsqueeze(1), | |
| size=(1024, 1024), | |
| mode="bicubic", | |
| align_corners=False, | |
| ) | |
| depth_min = torch.amin(depth_map, dim=[1, 2, 3], keepdim=True) | |
| depth_max = torch.amax(depth_map, dim=[1, 2, 3], keepdim=True) | |
| depth_map = (depth_map - depth_min) / (depth_max - depth_min) | |
| image = torch.cat([depth_map] * 3, dim=1) | |
| image = image.permute(0, 2, 3, 1).cpu().numpy()[0] | |
| image = Image.fromarray((image * 255.0).clip(0, 255).astype(np.uint8)) | |
| return image | |
| image = load_image( | |
| "https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/diffusers/non-enhanced-prompt.png" | |
| ).resize((1024, 1024)) | |
| depth_image = get_depth_map(image) | |
| ``` | |
| 深度マップをパイプラインに渡します。`controlnet_conditioning_scale` パラメータを使用して、コントロールに割り当てる重みを決定します。 | |
| ```py | |
| controlnet = ControlNetModel.from_pretrained( | |
| "diffusers/controlnet-depth-sdxl-1.0-small", | |
| dtype=torch.float16, | |
| ) | |
| vae = AutoencoderKL.from_pretrained("madebyollin/sdxl-vae-fp16-fix", dtype=torch.float16) | |
| pipeline = StableDiffusionXLControlNetImg2ImgPipeline.from_pretrained( | |
| "stabilityai/stable-diffusion-xl-base-1.0", | |
| controlnet=controlnet, | |
| vae=vae, | |
| dtype=torch.float16, | |
| ).to(device) | |
| prompt = """ | |
| A photorealistic overhead image of a cat reclining sideways in a flamingo pool floatie holding a margarita. | |
| The cat is floating leisurely in the pool and completely relaxed and happy. | |
| """ | |
| controlnet_conditioning_scale = 0.5 | |
| pipeline( | |
| prompt, | |
| image=image, | |
| control_image=depth_image, | |
| controlnet_conditioning_scale=controlnet_conditioning_scale, | |
| strength=0.99, | |
| num_inference_steps=100, | |
| ).images[0] | |
| ``` | |
| 元の画像 | |
| 深度マップ | |
| 生成された画像 | |
| 置き換えるピクセルを示すマスク画像を生成し、コントロール画像とともに`mask_image`として渡します。 | |
| ```py | |
| import cv2 | |
| import torch | |
| import numpy as np | |
| from PIL import Image | |
| from diffusers.utils import load_image | |
| from diffusers import StableDiffusionXLControlNetInpaintPipeline, ControlNetModel | |
| init_image = load_image( | |
| "https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/diffusers/non-enhanced-prompt.png" | |
| ) | |
| init_image = init_image.resize((1024, 1024)) | |
| mask_image = load_image( | |
| "https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/diffusers/cat_mask.png" | |
| ) | |
| mask_image = mask_image.resize((1024, 1024)) | |
| def make_canny_condition(image): | |
| image = np.array(image) | |
| image = cv2.Canny(image, 100, 200) | |
| image = image[:, :, None] | |
| image = np.concatenate([image, image, image], axis=2) | |
| image = Image.fromarray(image) | |
| return image | |
| control_image = make_canny_condition(init_image) | |
| ``` | |
| マスクとコントロール画像をパイプラインに渡します。コントロールにどの程度の重みを割り当てるかを決定するには、`controlnet_conditioning_scale` パラメータを使用します。 | |
| ```py | |
| controlnet = ControlNetModel.from_pretrained( | |
| "diffusers/controlnet-canny-sdxl-1.0", dtype=torch.float16 | |
| ) | |
| pipeline = StableDiffusionXLControlNetInpaintPipeline.from_pretrained( | |
| "stabilityai/stable-diffusion-xl-base-1.0", controlnet=controlnet, dtype=torch.float16 | |
| ).to("cuda") # or "mps", "xpu", "cpu" | |
| pipeline( | |
| "a cute and fluffy bunny rabbit", | |
| num_inference_steps=100, | |
| strength=0.99, | |
| controlnet_conditioning_scale=0.5, | |
| image=init_image, | |
| mask_image=mask_image, | |
| control_image=control_image, | |
| ).images[0] | |
| ``` | |
| 元の画像 | |
| マスク画像 | |
| 生成された画像 | |
| ## Multi-ControlNet | |
| `controlnet_conditioning_scale` を個別に調整し、重複する領域にはマスクを適用できる場合は適用して、複数の ControlNet(例: canny + depth)をリストとして渡すことで合成します。`canny_image` は OpenCV の Canny(テキストから画像生成の場合と同様)、`depth_image` は DPT(画像から画像生成の場合と同様)で生成します。パイプラインを呼び出す前に、すべてのコントロール画像をパイプラインのサイズにリサイズしてください。 | |
| ```py | |
| import cv2 | |
| import torch | |
| import numpy as np | |
| from PIL import Image | |
| from transformers import DPTImageProcessor, DPTForDepthEstimation | |
| from diffusers import StableDiffusionXLControlNetPipeline, ControlNetModel, AutoencoderKL | |
| from diffusers.utils import load_image | |
| original_image = load_image( | |
| "https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/diffusers/non-enhanced-prompt.png" | |
| ) | |
| image = np.array(original_image) | |
| canny_image = Image.fromarray( | |
| np.concatenate([cv2.Canny(image, 100, 200)[:, :, None]] * 3, axis=2) | |
| ) | |
| device = "cuda" # or "mps", "xpu", "cpu" | |
| depth_estimator = DPTForDepthEstimation.from_pretrained("Intel/dpt-hybrid-midas").to(device) | |
| feature_extractor = DPTImageProcessor.from_pretrained("Intel/dpt-hybrid-midas") | |
| def get_depth_map(image): | |
| image = feature_extractor(images=image, return_tensors="pt").pixel_values.to(device) | |
| with torch.no_grad(), torch.autocast(device): | |
| depth_map = depth_estimator(image).predicted_depth | |
| depth_map = torch.nn.functional.interpolate( | |
| depth_map.unsqueeze(1), | |
| size=(1024, 1024), | |
| mode="bicubic", | |
| align_corners=False, | |
| ) | |
| depth_min = torch.amin(depth_map, dim=[1, 2, 3], keepdim=True) | |
| depth_max = torch.amax(depth_map, dim=[1, 2, 3], keepdim=True) | |
| depth_map = (depth_map - depth_min) / (depth_max - depth_min) | |
| image = torch.cat([depth_map] * 3, dim=1) | |
| image = image.permute(0, 2, 3, 1).cpu().numpy()[0] | |
| image = Image.fromarray((image * 255.0).clip(0, 255).astype(np.uint8)) | |
| return image | |
| depth_image = get_depth_map(original_image.resize((1024, 1024))) | |
| controlnets = [ | |
| ControlNetModel.from_pretrained( | |
| "diffusers/controlnet-canny-sdxl-1.0", dtype=torch.float16 | |
| ), | |
| ControlNetModel.from_pretrained( | |
| "diffusers/controlnet-depth-sdxl-1.0-small", dtype=torch.float16 | |
| ), | |
| ] | |
| vae = AutoencoderKL.from_pretrained("madebyollin/sdxl-vae-fp16-fix", dtype=torch.float16) | |
| pipeline = StableDiffusionXLControlNetPipeline.from_pretrained( | |
| "stabilityai/stable-diffusion-xl-base-1.0", controlnet=controlnets, vae=vae, dtype=torch.float16 | |
| ).to(device) | |
| prompt = """ | |
| a relaxed rabbit sitting on a striped towel next to a pool with a tropical drink nearby, | |
| bright sunny day, vacation scene, 35mm photograph, film, professional, 4k, highly detailed | |
| """ | |
| negative_prompt = "lowres, bad anatomy, worst quality, low quality, deformed, ugly" | |
| images = [canny_image.resize((1024, 1024)), depth_image.resize((1024, 1024))] | |
| pipeline( | |
| prompt, | |
| negative_prompt=negative_prompt, | |
| image=images, | |
| num_inference_steps=100, | |
| controlnet_conditioning_scale=[0.5, 0.5], | |
| ).images[0] | |
| ``` | |
| canny image | |
| 深度マップ | |
| 生成された画像 | |
| ## 推測モード | |
| [Guess mode](https://github.com/lllyasviel/ControlNet/discussions/188)は、テキストプロンプトがない場合(または不要な場合)に、コントロールのみから画像を生成します。ControlNetの残差をブロックの深さに応じてスケーリングし、初期のダウンブロックでは`0.1`程度から、ミッドブロックでは`1.0`まで変化させます。これにより、初期レイヤーが過度に制約をかけるのを防ぎつつ、深いブロックが構造を保持できるようにします。 | |
| ```py | |
| import torch | |
| from diffusers.utils import load_image | |
| from diffusers import StableDiffusionXLControlNetPipeline, ControlNetModel | |
| controlnet = ControlNetModel.from_pretrained( | |
| "diffusers/controlnet-canny-sdxl-1.0", dtype=torch.float16 | |
| ) | |
| pipeline = StableDiffusionXLControlNetPipeline.from_pretrained( | |
| "stabilityai/stable-diffusion-xl-base-1.0", | |
| controlnet=controlnet, | |
| dtype=torch.float16 | |
| ).to("cuda") # or "mps", "xpu", "cpu" | |
| canny_image = load_image("https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/diffusers/canny-cat.png") | |
| pipeline( | |
| "", | |
| image=canny_image, | |
| guess_mode=True | |
| ).images[0] | |
| ``` | |
| canny image | |
| 生成された画像 | |
Xet Storage Details
- Size:
- 12.5 kB
- Xet hash:
- f366745ec58c7713b00587906696f51d32f317d3351fc64b263cdc35a4e4ca64
·
Xet efficiently stores files, intelligently splitting them into unique chunks and accelerating uploads and downloads. More info.