stable diffusionを使って画像生成する簡単なc#プログラム③(img2img+Embedding+Upscale)
前回の続きです。画像生成は初心者なので、かなり適当にやってます。何やらいろんなオプションがあるのがわかってきました。Exsampleでは見えないオプションの指定とかやってみたいと思います。
Embedding
手の指が変になるのを直してくれるようですね。効果がいまいち体感できませんでしたが、お守りとして記述しています。
今回使用させていただいたもの⇒negative_hand-neg
Upscale
自分の環境でもCUDAで処理させることができるのは768X768か512X1024の解像度が限界ですね。CPUで1024X2048をやってみましたが30分ぐらいかかるのでしんどいです。
そのような場合、Upscalerというものを使うそうです。解像度を上げつつ画像を鮮明にしてくれます。
今回使用させていただいたもの⇒RealESRGAN_x4plus
試しましたが何もしない方がキレイなので今は外しています。参考のコードにはUpscale処理をつけていますので嫌な時はコメントで止めて下の行のコメントを外してください。
では実際のコードです。Nugetは同じものですね。
概要
モデルの読込み時に、Embeddingパラメータ、Upscale Class+パラメータを追加しています。
モデルは、kisaragiMix_v22を使用。
FileNameで指定された元画像をimg2imgで処理してFileName_1.png、FileName_2.png、FileName_3.png・・・と作成します。
Seed値を乱数で指定して少しの変化を持たせています。ただしStrengthの値が小さいと影響も小さくなります。
using HPPH;
using HPPH.System.Drawing;
using StableDiffusion.NET;
namespace StableDiffusion.Test
{
public class Program
{
static void Main(string[] args)
{
Task task = MainAsync();
task.Wait();
}
private static string ModelPath = Environment.GetEnvironmentVariable("LLMPATH", System.EnvironmentVariableTarget.User) + @"jiaowobaba02\stable-diffusion-v2-1-GGUF\kisaragiMix_v22.safetensors";
private static string VaePath = Environment.GetEnvironmentVariable("LLMPATH", System.EnvironmentVariableTarget.User) + @"jiaowobaba02\stable-diffusion-v2-1-GGUF\vae-ft-mse-840000-ema-pruned.safetensors";
private static string UpscalePath = Environment.GetEnvironmentVariable("LLMPATH", System.EnvironmentVariableTarget.User) + @"jiaowobaba02\stable-diffusion-v2-1-GGUF\RealESRGAN_x4plus.pth";
private static string EmbedPath = Environment.GetEnvironmentVariable("LLMPATH", System.EnvironmentVariableTarget.User) + @"jiaowobaba02\stable-diffusion-v2-1-GGUF\negative_hand-neg.pt";
public static async Task MainAsync()
{
string Filename = "pc01-0600.png";
int intWidth = 0;
int intHeight = 0;
IImage<ColorRGB> objImage;
IImage<ColorRGB> objUpscale;
IImage<ColorRGB> Image2ImageSource;
//Load Model
StableDiffusionModel sdModel = await Task.Run(() => new StableDiffusionModel(ModelPath, new ModelParameter { VaePath = VaePath, Schedule = Schedule.Karras , EmbeddingsDirectory = EmbedPath}, new UpscalerModelParameter {ESRGANPath = UpscalePath }));
//StableDiffusionModel sdModel = await Task.Run(() => new StableDiffusionModel(ModelPath, new ModelParameter { VaePath = VaePath, Schedule = Schedule.Karras , EmbeddingsDirectory = EmbedPath}));
string strPrompt = "((best quality, masterpiece, absurbres, super-resolution)), (photorealistic,realistic:1.4), (20 years old cute actress), (beautiful fingers)";
string strAntiPrompt = "(worst quality:2) , (low quality:2) , (normal quality:2) , lowres, ugly face, unclear eyes, bad mouth, bad anatomy, extra legs, (bad fingers, bad hands, missing fingers), embedding";
string ImagePath = Environment.GetEnvironmentVariable("TESTDATA", System.EnvironmentVariableTarget.User) + Filename;
Image2ImageSource = ImageHelper.LoadImage(ImagePath).ConvertTo<ColorRGB>();
intHeight = Image2ImageSource.Height;
intWidth = Image2ImageSource.Width;
long lngSeed = -1;
string[] Fname = Filename.Split('.');
for (int i = 0; i < 5; i++)
{
//Seed Random
Random rSeed = new Random();
lngSeed = rSeed.Next(0, int.MaxValue);
objImage = await Task.Run(() => sdModel?.ImageToImage(strPrompt, Image2ImageSource, new StableDiffusionParameter
{
NegativePrompt = strAntiPrompt,
Width = intWidth,
Height = intHeight,
CfgScale = 11f,
SampleSteps = 42,
Seed = lngSeed,
SampleMethod = Sampler.DPMPP2Mv2,
Strength = 0.3f,
}));
objUpscale = await Task.Run(() => sdModel?.Upscale(objImage,2)); //Upscaleしないときはここをコメントしてね
string savePath = Environment.GetEnvironmentVariable("TESTDATA", System.EnvironmentVariableTarget.User) + $"{Fname[0]}_{i+1}.{Fname[1]}";
File.WriteAllBytes(savePath, objUpscale.ToPng());
//File.WriteAllBytes(savePath, objImage.ToPng());
}
}
}
}
Upscaleはしてませんが左がオリジナルで右がStrength0.3の画像生成を加えた画像です。
目の色は、闇落ちしているせいで変な色です^^;