Skip to content
This repository was archived by the owner on Nov 27, 2024. It is now read-only.

Commit 9205547

Browse files
committed
ControlNet, ControlNetImage UI support
1 parent e14d29f commit 9205547

File tree

9 files changed

+84
-31
lines changed

9 files changed

+84
-31
lines changed

OnnxStack.StableDiffusion/Config/PromptOptions.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@ public class PromptOptions
2020

2121
public InputImage InputImageMask { get; set; }
2222

23+
public InputImage InputContolImage { get; set; }
24+
2325
public VideoInput InputVideo { get; set; }
2426

2527
public float VideoInputFPS { get; set; }

OnnxStack.StableDiffusion/Diffusers/StableDiffusion/ControlNetDiffuser.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -193,7 +193,7 @@ protected static DenseTensor<double> CreateConditioningScaleTensor(float conditi
193193
/// <returns></returns>
194194
protected DenseTensor<float> PrepareControlImage(PromptOptions promptOptions, SchedulerOptions schedulerOptions)
195195
{
196-
return promptOptions.InputImage.ToDenseTensor(new[] { 1, 3, schedulerOptions.Height, schedulerOptions.Width }, false);
196+
return promptOptions.InputContolImage.ToDenseTensor(new[] { 1, 3, schedulerOptions.Height, schedulerOptions.Width }, false);
197197
}
198198

199199

OnnxStack.StableDiffusion/Services/ImageService.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -179,7 +179,7 @@ private async Task<InputImage> GenerateDepthImage(ControlNetModelSet controlNetM
179179
/// <returns></returns>
180180
private static InputImage PrepareInputImage(InputImage inputImage, int height, int width)
181181
{
182-
return new InputImage(inputImage.ToDenseTensor(new[] { 1, 3, height, width }, false));
182+
return inputImage;
183183
}
184184

185185

OnnxStack.UI/Models/SchedulerOptionsModel.cs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ public class SchedulerOptionsModel : INotifyPropertyChanged
3333
private int _originalInferenceSteps = 100;
3434
private SchedulerType _schedulerType;
3535
private float _conditioningScale = 0.7f;
36+
private bool _processInputImage;
3637
private bool _hasChanged;
3738

3839
/// <summary>
@@ -208,6 +209,11 @@ public float ConditioningScale
208209
set { _conditioningScale = value; NotifyPropertyChanged(); }
209210
}
210211

212+
public bool ProcessInputImage
213+
{
214+
get { return _processInputImage; }
215+
set { _processInputImage = value; NotifyPropertyChanged(); }
216+
}
211217

212218
public bool HasChanged
213219
{

OnnxStack.UI/Models/StableDiffusionModelSetViewModel.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
using OnnxStack.StableDiffusion.Config;
2+
using OnnxStack.StableDiffusion.Enums;
23
using System.ComponentModel;
34
using System.Runtime.CompilerServices;
45
using System.Text.Json.Serialization;
@@ -31,6 +32,8 @@ public bool IsLoading
3132
set { _isLoading = value; NotifyPropertyChanged(); }
3233
}
3334

35+
public bool IsControlNet => ModelSet.Diffusers.Contains(DiffuserType.ControlNet);
36+
3437
public StableDiffusionModelSet ModelSet { get; set; }
3538

3639
#region INotifyPropertyChanged

OnnxStack.UI/UserControls/SchedulerControl.xaml

Lines changed: 17 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,20 @@
3333
<ComboBox ItemsSource="{Binding SchedulerTypes}" SelectedItem="{Binding SchedulerOptions.SchedulerType}"/>
3434
</StackPanel>
3535

36-
36+
<StackPanel Margin="5,0,0,0" VerticalAlignment="Bottom" Visibility="{Binding SelectedModel.IsControlNet, Converter={StaticResource BooleanToVisibilityConverter}, FallbackValue=Collapsed}">
37+
<CheckBox IsChecked="{Binding SchedulerOptions.ProcessInputImage}" Content="Process Input Image" Margin="0,0,0,3"/>
38+
39+
<!--<StackPanel.Style>
40+
<Style TargetType="{x:Type StackPanel}">
41+
<Setter Property="IsEnabled" Value="False" />
42+
<Style.Triggers>
43+
<DataTrigger Binding="{Binding SchedulerOptions.Strength}" Value="1">
44+
<Setter Property="IsEnabled" Value="True" />
45+
</DataTrigger>
46+
</Style.Triggers>
47+
</Style>
48+
</StackPanel.Style>-->
49+
</StackPanel>
3750

3851

3952
</UniformGrid>
@@ -111,7 +124,7 @@
111124
</i:Interaction.Behaviors>
112125
</Slider>
113126
<StackPanel.Style>
114-
127+
115128
<Style TargetType="{x:Type StackPanel}">
116129
<Style.Triggers>
117130
<DataTrigger Binding="{Binding Path=DiffuserType}" Value="TextToImage">
@@ -129,7 +142,7 @@
129142
</StackPanel>
130143

131144

132-
<StackPanel Margin="0,0,5,0">
145+
<StackPanel Margin="0,0,5,0" Visibility="{Binding SelectedModel.IsControlNet, Converter={StaticResource BooleanToVisibilityConverter}}">
133146
<DockPanel>
134147
<Label>Conditioning Scale</Label>
135148
<TextBlock Text="{Binding ElementName=SliderInitialConditioningScale, Path=Value, StringFormat={}{0:F2}}" VerticalAlignment="Bottom" HorizontalAlignment="Right" FontSize="10" Margin="0,0,6,0" FontWeight="Medium" />
@@ -139,16 +152,7 @@
139152
<behaviors:SliderMouseWheelBehavior />
140153
</i:Interaction.Behaviors>
141154
</Slider>
142-
<StackPanel.Style>
143-
<Style TargetType="{x:Type StackPanel}">
144-
<Setter Property="Visibility" Value="Collapsed" />
145-
<Style.Triggers>
146-
<DataTrigger Binding="{Binding Path=DiffuserType}" Value="ControlNet">
147-
<Setter Property="Visibility" Value="Visible" />
148-
</DataTrigger>
149-
</Style.Triggers>
150-
</Style>
151-
</StackPanel.Style>
155+
152156
</StackPanel>
153157

154158
</UniformGrid>

OnnxStack.UI/Views/ControlNetView.xaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@
2626
SupportedDiffusers="{Binding SupportedDiffusers}"
2727
IsEnabled="{Binding IsGenerating, Converter={StaticResource InverseBoolConverter}}"
2828
SelectedModel="{Binding SelectedModel, Mode=TwoWay}"/>
29-
<userControls:ControlNetPickerControl
29+
<userControls:ControlNetPickerControl Visibility="{Binding SelectedModel.IsControlNet, Converter={StaticResource BooleanToVisibilityConverter}}"
3030
UISettings="{Binding UISettings}"
3131
IsEnabled="{Binding IsGenerating, Converter={StaticResource InverseBoolConverter}}"
3232
SelectedModel="{Binding SelectedControlNetModel, Mode=TwoWay}"/>

OnnxStack.UI/Views/ImageToImageView.xaml

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -20,11 +20,19 @@
2020
<Button Content="Generate" Command="{Binding GenerateCommand}" IsEnabled="{Binding SelectedModel.IsLoaded, FallbackValue=False, TargetNullValue=False}" IsDefault="True" Margin="1,0,0,0"/>
2121
</UniformGrid>
2222
<DockPanel>
23-
<userControls:ModelPickerControl DockPanel.Dock="Top"
24-
UISettings="{Binding UISettings}"
25-
SupportedDiffusers="{Binding SupportedDiffusers}"
26-
IsEnabled="{Binding IsGenerating, Converter={StaticResource InverseBoolConverter}}"
27-
SelectedModel="{Binding SelectedModel, Mode=TwoWay}"/>
23+
<StackPanel DockPanel.Dock="Top">
24+
<userControls:ModelPickerControl
25+
UISettings="{Binding UISettings}"
26+
SupportedDiffusers="{Binding SupportedDiffusers}"
27+
IsEnabled="{Binding IsGenerating, Converter={StaticResource InverseBoolConverter}}"
28+
SelectedModel="{Binding SelectedModel, Mode=TwoWay}"/>
29+
<userControls:ControlNetPickerControl
30+
UISettings="{Binding UISettings}"
31+
IsEnabled="{Binding IsGenerating, Converter={StaticResource InverseBoolConverter}}"
32+
SelectedModel="{Binding SelectedControlNetModel, Mode=TwoWay}"
33+
Visibility="{Binding SelectedModel.IsControlNet, Converter={StaticResource BooleanToVisibilityConverter}, FallbackValue=Collapsed}"/>
34+
</StackPanel>
35+
2836
<DockPanel IsEnabled="{Binding SelectedModel.IsLoaded, FallbackValue=False, TargetNullValue=False}">
2937
<userControls:SchedulerControl DockPanel.Dock="Bottom" Margin="0, 10, 0 ,0"
3038
SelectedModel="{Binding SelectedModel}"

OnnxStack.UI/Views/ImageToImageView.xaml.cs

Lines changed: 40 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ public partial class ImageToImageView : UserControl, INavigatable, INotifyProper
2626
{
2727
private readonly ILogger<ImageToImageView> _logger;
2828
private readonly IStableDiffusionService _stableDiffusionService;
29+
private readonly IImageService _imageService;
2930

3031
private bool _hasResult;
3132
private int _progressMax;
@@ -37,6 +38,7 @@ public partial class ImageToImageView : UserControl, INavigatable, INotifyProper
3738
private ImageInput _inputImage;
3839
private ImageResult _resultImage;
3940
private StableDiffusionModelSetViewModel _selectedModel;
41+
private ControlNetModelSetViewModel _selectedControlNetModel;
4042
private PromptOptionsModel _promptOptionsModel;
4143
private SchedulerOptionsModel _schedulerOptions;
4244
private CancellationTokenSource _cancelationTokenSource;
@@ -51,9 +53,10 @@ public ImageToImageView()
5153
{
5254
_logger = App.GetService<ILogger<ImageToImageView>>();
5355
_stableDiffusionService = App.GetService<IStableDiffusionService>();
56+
_imageService = App.GetService<IImageService>();
5457
}
5558

56-
SupportedDiffusers = new() { DiffuserType.ImageToImage };
59+
SupportedDiffusers = new() { DiffuserType.ImageToImage, DiffuserType.ControlNet };
5760
CancelCommand = new AsyncRelayCommand(Cancel, CanExecuteCancel);
5861
GenerateCommand = new AsyncRelayCommand(Generate, CanExecuteGenerate);
5962
ClearHistoryCommand = new AsyncRelayCommand(ClearHistory, CanExecuteClearHistory);
@@ -84,6 +87,12 @@ public StableDiffusionModelSetViewModel SelectedModel
8487
get { return _selectedModel; }
8588
set { _selectedModel = value; NotifyPropertyChanged(); }
8689
}
90+
91+
public ControlNetModelSetViewModel SelectedControlNetModel
92+
{
93+
get { return _selectedControlNetModel; }
94+
set { _selectedControlNetModel = value; NotifyPropertyChanged(); }
95+
}
8796

8897
public PromptOptionsModel PromptOptions
8998
{
@@ -195,13 +204,13 @@ private async Task Generate()
195204
IsControlsEnabled = false;
196205
ResultImage = null;
197206
_cancelationTokenSource = new CancellationTokenSource();
198-
var promptOptions = GetPromptOptions(PromptOptions, InputImage);
207+
var promptOptions = await GetPromptOptions(PromptOptions, InputImage);
199208
var schedulerOptions = SchedulerOptions.ToSchedulerOptions();
200209

201210
try
202211
{
203212
var timestamp = Stopwatch.GetTimestamp();
204-
var result = await _stableDiffusionService.GenerateAsBytesAsync(new ModelOptions(_selectedModel.ModelSet), promptOptions, schedulerOptions, ProgressCallback(), _cancelationTokenSource.Token);
213+
var result = await _stableDiffusionService.GenerateAsBytesAsync(new ModelOptions(_selectedModel.ModelSet, _selectedControlNetModel?.ModelSet), promptOptions, schedulerOptions, ProgressCallback(), _cancelationTokenSource.Token);
205214
var resultImage = await GenerateResultAsync(result, promptOptions, schedulerOptions, timestamp);
206215
if (resultImage != null)
207216
{
@@ -232,8 +241,8 @@ private async Task Generate()
232241
private bool CanExecuteGenerate()
233242
{
234243
return !IsGenerating
235-
// && !string.IsNullOrEmpty(PromptOptions.Prompt)
236-
&& HasInputResult;
244+
&& HasInputResult
245+
&& (!SelectedModel.IsControlNet || (SelectedModel.IsControlNet && SelectedControlNetModel?.IsLoaded == true));
237246
}
238247

239248

@@ -294,17 +303,38 @@ private void Reset()
294303
}
295304

296305

297-
private PromptOptions GetPromptOptions(PromptOptionsModel promptOptionsModel, ImageInput imageInput)
306+
private async Task<PromptOptions> GetPromptOptions(PromptOptionsModel promptOptionsModel, ImageInput imageInput)
298307
{
308+
if (_selectedModel.IsControlNet)
309+
{
310+
var controlNetDiffuserType = _schedulerOptions.Strength >= 1
311+
? DiffuserType.ControlNet
312+
: DiffuserType.ControlNetImage;
313+
314+
var inputImage = default(InputImage);
315+
if (controlNetDiffuserType == DiffuserType.ControlNetImage)
316+
inputImage = new InputImage(imageInput.Image.GetImageBytes());
317+
318+
var controlImage = new InputImage(imageInput.Image.GetImageBytes());
319+
if (_schedulerOptions.ProcessInputImage)
320+
controlImage = await _imageService.PrepareInputImage(_selectedControlNetModel.ModelSet, controlImage, _schedulerOptions.Height, _schedulerOptions.Width);
321+
322+
return new PromptOptions
323+
{
324+
Prompt = promptOptionsModel.Prompt,
325+
NegativePrompt = promptOptionsModel.NegativePrompt,
326+
DiffuserType = controlNetDiffuserType,
327+
InputImage = inputImage,
328+
InputContolImage = controlImage
329+
};
330+
}
331+
299332
return new PromptOptions
300333
{
301334
Prompt = promptOptionsModel.Prompt,
302335
NegativePrompt = promptOptionsModel.NegativePrompt,
303336
DiffuserType = DiffuserType.ImageToImage,
304-
InputImage = new InputImage
305-
{
306-
ImageBytes = imageInput.Image.GetImageBytes()
307-
}
337+
InputImage = new InputImage(imageInput.Image.GetImageBytes())
308338
};
309339
}
310340

0 commit comments

Comments
 (0)