I got an email from CodeProject about their AI Explorer that can be hosted locally.
https://www.codeproject.com/Articles/5322557/CodeProject-AI-Server-AI-the-easy-way
It took about an hour to install it and not all the modules are usable and useful. Nevertheless, the modules that are useful are interesting. It comes with a well designed dashboard that lets you interact with the AI services.
Once you have installed this and installed the scene classification module you will see Scene Classification as it looks below.
These services can also be called from your code. I wanted to write a simple WPF application that could classify images as you can see above. My application won't be as pretty, but it will be mine.
Start a new C#, .Net Core Visual Studio project and call it SceneClassifier.
It will let the user select an image, and when they do it will display the image and call the SceneClassifier AI service. It will then display the scene classification and confidence.
Here's the XAML for MainWindow.xaml. There's nothing clever here. It's all in the code.
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:SceneClassifier"
mc:Ignorable="d"
DataContext="{Binding RelativeSource={RelativeSource Self}}"
SizeToContent="WidthAndHeight"
Title="Scene Classifier" Height="450" Width="800">
<Window.Resources>
<RoutedCommand x:Key="SelectCommand"/>
</Window.Resources>
<Window.CommandBindings>
<CommandBinding Command="{StaticResource SelectCommand}" Executed="Select_Executed"/>
</Window.CommandBindings>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="auto"/>
<RowDefinition Height="auto"/>
<RowDefinition Height="auto"/>
<RowDefinition Height="auto"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="100"/>
<ColumnDefinition Width="100"/>
<ColumnDefinition Width="100"/>
<ColumnDefinition Width="100"/>
</Grid.ColumnDefinitions>
<TextBlock Grid.Row="0" Grid.Column="1" Grid.ColumnSpan="3" Text="{Binding FileName}"/>
<TextBlock Grid.Row="2" Grid.Column="1" Text="{Binding Classification}"/>
<TextBlock Grid.Row="2" Grid.Column="3" Text="{Binding Confidence}"/>
<TextBlock Grid.Row="3" Grid.Column="0" Grid.ColumnSpan="4" Text="{Binding Status}"/>
</Grid>
</Window>
-------------------------------------------------------------------------------------
The code uses an HttpClient to access the REST service provided by CodeProject's AI server and deserializes the result into an object. The we pull the classification and confidence out of the object. Yes, I know the architecture sucks - this isn't a post about code purity :-)
namespace SceneClassifier;
{
public bool success { get; set; }
[ObservableObject]
{
[ObservableProperty] String _FileName = "";
HttpClient httpClient = new HttpClient();
public MainWindow()
InitializeComponent();
}
private void Select_Executed(object sender, ExecutedRoutedEventArgs e)
OpenFileDialog openFileDialog = new OpenFileDialog();
FileName = openFileDialog.FileName;
ClassifyScene(FileName);
}
}
private async void ClassifyScene(string FileName)
Byte[] imageBytes = System.IO.File.ReadAllBytes(FileName);
MultipartFormDataContent form = new MultipartFormDataContent();
HttpResponseMessage response = await httpClient.PostAsync("http://localhost:32168/v1/vision/scene", form);
cResult result = await response.Content.ReadFromJsonAsync<cResult>();
Confidence = Math.Round(result.confidence * 100).ToString() + "%";
else
{
string Error = await response.Content.ReadAsStringAsync();
}
}