rework to Azaion.Suite, show tabs with annotator and dataset explorer

This commit is contained in:
Alex Bezdieniezhnykh
2024-11-23 08:53:12 +02:00
parent 490e90f239
commit 3b40bd601e
40 changed files with 374 additions and 284 deletions
+1 -5
View File
@@ -102,9 +102,6 @@ public partial class Annotator
if (LvFiles.Items.IsEmpty)
BlinkHelp(HelpTexts.HelpTextsDict[HelpTextEnum.Initial]);
if (_appConfig.WindowConfig.ShowHelpOnStart)
_helpWindow.Show();
}
public void BlinkHelp(string helpText, int times = 2)
@@ -541,7 +538,6 @@ public partial class Annotator
_ = Task.Run(async () =>
{
using var detector = new YOLODetector(_appConfig.AIRecognitionConfig);
Dispatcher.Invoke(() => _autoDetectDialog.Log("Ініціалізація AI..."));
var prevSeekTime = 0.0;
@@ -549,7 +545,7 @@ public partial class Annotator
{
try
{
var detections = _aiDetector.Detect(timeframe.Stream);
var detections = await _aiDetector.Detect(timeframe.Stream, token);
if (timeframe.Time.TotalSeconds > prevSeekTime + 1)
{
Dispatcher.Invoke(() => SeekTo(timeframe.Time));
@@ -5,6 +5,7 @@ using System.Windows.Input;
using System.Windows.Media;
using Azaion.Annotator.DTO;
using Azaion.Common.DTO;
using Azaion.Common.DTO.Config;
using LibVLCSharp.Shared;
using MediatR;
using Microsoft.Extensions.Logging;
+3 -6
View File
@@ -10,8 +10,8 @@
<ItemGroup>
<PackageReference Include="libc.translation" Version="7.1.1" />
<PackageReference Include="LibVLCSharp" Version="3.8.2" />
<PackageReference Include="LibVLCSharp.WPF" Version="3.8.2" />
<PackageReference Include="LibVLCSharp" Version="3.9.1" />
<PackageReference Include="LibVLCSharp.WPF" Version="3.9.1" />
<PackageReference Include="MediatR" Version="12.4.1" />
<PackageReference Include="Microsoft.Extensions.Configuration" Version="8.0.0" />
<PackageReference Include="Microsoft.Extensions.DependencyInjection" Version="9.0.0" />
@@ -26,16 +26,13 @@
<PackageReference Include="Serilog.Sinks.Console" Version="6.0.0" />
<PackageReference Include="Serilog.Sinks.File" Version="6.0.0" />
<PackageReference Include="SkiaSharp" Version="2.88.9" />
<PackageReference Include="VideoLAN.LibVLC.Windows" Version="3.0.20" />
<PackageReference Include="VideoLAN.LibVLC.Windows" Version="3.0.21" />
<PackageReference Include="WindowsAPICodePack" Version="7.0.4" />
<PackageReference Include="YoloV8.Gpu" Version="5.0.4" />
</ItemGroup>
<ItemGroup>
<None Remove="logo.ico" />
<None Update="config.json">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
</ItemGroup>
<ItemGroup>
-3
View File
@@ -1,8 +1,5 @@
using System.Windows.Media;
using Azaion.Annotator.Extensions;
using Azaion.Common.DTO;
using Azaion.Common.DTO.Config;
using Azaion.Common.Extensions;
using Newtonsoft.Json;
namespace Azaion.Annotator.DTO;
+10 -4
View File
@@ -1,5 +1,6 @@
using System.Windows;
using Azaion.Common.DTO.Config;
using Microsoft.Extensions.Options;
namespace Azaion.Annotator;
@@ -7,14 +8,19 @@ public partial class HelpWindow : Window
{
private readonly WindowConfig _windowConfig;
public HelpWindow(WindowConfig windowConfig)
public HelpWindow(IOptions<WindowConfig> windowConfig)
{
_windowConfig = windowConfig;
Loaded += (_, _) => CbShowHelp.IsChecked = windowConfig.ShowHelpOnStart;
_windowConfig = windowConfig.Value;
Loaded += (_, _) => CbShowHelp.IsChecked = _windowConfig.ShowHelpOnStart;
Closing += (sender, args) =>
{
args.Cancel = true;
Visibility = Visibility.Hidden;
};
InitializeComponent();
}
private void Close(object sender, RoutedEventArgs e) => Close();
private void CbShowHelp_OnChecked(object sender, RoutedEventArgs e) => _windowConfig.ShowHelpOnStart = true;
private void CbShowHelp_OnUnchecked(object sender, RoutedEventArgs e) => _windowConfig.ShowHelpOnStart = false;
}
+20 -9
View File
@@ -2,6 +2,8 @@
using Azaion.Annotator.DTO;
using Azaion.Annotator.Extensions;
using Azaion.Common.DTO;
using Azaion.Common.DTO.Config;
using Azaion.Common.Services;
using Compunet.YoloV8;
using Microsoft.Extensions.Options;
using SixLabors.ImageSharp;
@@ -12,18 +14,27 @@ namespace Azaion.Annotator;
public interface IAIDetector
{
List<Detection> Detect(Stream stream);
Task<List<Detection>> Detect(Stream imageStream, CancellationToken cancellationToken = default);
}
public class YOLODetector(AIRecognitionConfig recognitionConfig) : IAIDetector, IDisposable
public class YOLODetector(IOptions<AIRecognitionConfig> recognitionConfig, IResourceLoader resourceLoader) : IAIDetector, IDisposable
{
private readonly YoloPredictor _predictor = new(recognitionConfig.AIModelPath);
private readonly AIRecognitionConfig _recognitionConfig = recognitionConfig.Value;
private YoloPredictor? _predictor;
private const string YOLO_MODEL = "azaion.onnx";
public List<Detection> Detect(Stream stream)
public async Task<List<Detection>> Detect(Stream imageStream, CancellationToken cancellationToken)
{
stream.Seek(0, SeekOrigin.Begin);
var image = Image.Load<Rgb24>(stream);
var result = _predictor.Detect(image);
if (_predictor == null)
{
await using var stream = await resourceLoader.Load(YOLO_MODEL, cancellationToken);
_predictor = new YoloPredictor(stream.ToArray());
}
imageStream.Seek(0, SeekOrigin.Begin);
var image = Image.Load<Rgb24>(imageStream);
var result = await _predictor.DetectAsync(image);
var imageSize = new System.Windows.Size(image.Width, image.Height);
@@ -38,7 +49,7 @@ public class YOLODetector(AIRecognitionConfig recognitionConfig) : IAIDetector,
private List<Detection> FilterOverlapping(List<Detection> detections)
{
var k = recognitionConfig.TrackingIntersectionThreshold;
var k = _recognitionConfig.TrackingIntersectionThreshold;
var filteredDetections = new List<Detection>();
for (var i = 0; i < detections.Count; i++)
{
@@ -73,5 +84,5 @@ public class YOLODetector(AIRecognitionConfig recognitionConfig) : IAIDetector,
return filteredDetections;
}
public void Dispose() => _predictor.Dispose();
public void Dispose() => _predictor?.Dispose();
}
-47
View File
@@ -1,47 +0,0 @@
{
"VideosDirectory": "E:\\Azaion1\\Videos",
"LabelsDirectory": "E:\\labels",
"ImagesDirectory": "E:\\images",
"ThumbnailsDirectory": "E:\\thumbnails",
"ResultsDirectory": "E:\\results",
"UnknownImages": "E:\\unknown",
"AnnotationClasses": [
{ "Id": 0, "Name": "Броньована техніка", "ShortName": "Бронь" },
{ "Id": 1, "Name": "Вантажівка", "ShortName": "Вантаж" },
{ "Id": 2, "Name": "Машина легкова", "ShortName": "Машина" },
{ "Id": 3, "Name": "Артилерія", "ShortName": "Арта" },
{ "Id": 4, "Name": "Тінь від техніки", "ShortName": "Тінь" },
{ "Id": 5, "Name": "Окопи", "ShortName": "Окопи" },
{ "Id": 6, "Name": "Військовий", "ShortName": "Військов" },
{ "Id": 7, "Name": "Накати", "ShortName": "Накати" },
{ "Id": 8, "Name": "Танк з захистом", "ShortName": "Танк захист" },
{ "Id": 9, "Name": "Дим", "ShortName": "Дим" },
{ "Id": 10, "Name": "Літак", "ShortName": "Літак" }
],
"MainWindowConfig": {
"WindowSize": "1920,1080",
"WindowLocation": "50,50",
"FullScreen": true
},
"DatasetExplorerConfig": {
"WindowSize": "1920,1080",
"WindowLocation": "50,50",
"FullScreen": true
},
"ThumbnailConfig": {
"Size": "480,270",
"Border": 10
},
"LeftPanelWidth": 300,
"RightPanelWidth": 300,
"ShowHelpOnStart": false,
"VideoFormats": ["mov", "mp4"],
"ImageFormats": ["jpg", "jpeg", "png", "bmp", "gif"],
"AIRecognitionConfig": {
"AIModelPath": "azaion.onnx",
"FrameRecognitionSeconds": 2,
"TrackingDistanceConfidence": 0.15,
"TrackingProbabilityIncrease": 15,
"TrackingIntersectionThreshold": 0.8
}
}