polish autodetection

This commit is contained in:
Alex Bezdieniezhnykh
2024-11-02 20:59:51 +02:00
parent 418a2116b7
commit addf7ccc11
6 changed files with 90 additions and 27 deletions
+10 -11
View File
@@ -3,27 +3,26 @@
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:extensions="clr-namespace:Azaion.Annotator.Extensions"
mc:Ignorable="d"
WindowStyle="SingleBorderWindow"
ResizeMode="NoResize"
Title="AutodetectDialog"
Height="250" Width="420"
Title="Розпізнавання"
Height="247" Width="400"
Background="LightGray">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="40"></RowDefinition>
<RowDefinition Height="*"></RowDefinition>
<RowDefinition Height="70"></RowDefinition>
</Grid.RowDefinitions>
<TextBlock Grid.Row="0"
FontSize="18" TextAlignment="Center" Padding="0 10 0 0">Йде розпізнавання...</TextBlock>
<ScrollViewer Grid.Row="1">
<TextBlock
Name="TextBlockLog"
Padding="10 10 5 5"/>
<ScrollViewer Grid.Row="0"
extensions:ScrollViewerExtensions.AlwaysScrollToEnd="True">
<TextBlock
Name="TextBlockLog"
Padding="10 10 5 5"/>
</ScrollViewer>
<Button Grid.Row="2"
Width="50" Height="50" ToolTip="Видалити всі аннотації. Клавіша: [X]"
<Button Grid.Row="1"
Width="50" Height="50" ToolTip="Зупинити розпізнавання. [Esc]"
Background="LightGray" BorderBrush="LightGray"
Click="ButtonBase_OnClick">
<Path Stretch="Fill" Fill="Gray" Data="M12,2 C17.5228,2 22,6.47715 22,12 C22,17.5228 17.5228,22 12,22 C6.47715,22 2,17.5228 2,12 C2,6.47715 6.47715,2 12,2 Z
+7 -4
View File
@@ -1,4 +1,5 @@
using System.Windows;
using System.Windows.Input;
namespace Azaion.Annotator;
@@ -7,13 +8,15 @@ public partial class AutodetectDialog : Window
public AutodetectDialog()
{
InitializeComponent();
KeyUp += (sender, args) =>
{
if (args.Key == Key.Escape)
Close();
};
}
public void Log(string message) =>
TextBlockLog.Text = TextBlockLog.Text + Environment.NewLine + message;
private void ButtonBase_OnClick(object sender, RoutedEventArgs e)
{
Close();
}
private void ButtonBase_OnClick(object sender, RoutedEventArgs e) => Close();
}
@@ -26,6 +26,7 @@ public class AnnotationControl : Border
set
{
_grid.Background = value.ColorBrush;
_probabilityLabel.Background = value.ColorBrush;
_classNameLabel.Text = value.Name;
_annotationClass = value;
}
@@ -59,10 +60,12 @@ public class AnnotationControl : Border
};
_probabilityLabel = new Label
{
Content = probability?.ToString("F1") ?? string.Empty,
Content = probability.HasValue ? $"{probability.Value:F0}%" : string.Empty,
HorizontalAlignment = HorizontalAlignment.Right,
VerticalAlignment = VerticalAlignment.Top,
Margin = new Thickness(0, -15, 0, 0),
Margin = new Thickness(0, -32, 0, 0),
FontSize = 16,
Visibility = Visibility.Visible
};
_selectionFrame = new Rectangle
{
@@ -81,6 +84,7 @@ public class AnnotationControl : Border
{
_selectionFrame,
_classNameLabel,
_probabilityLabel,
AddRect("rLT", HorizontalAlignment.Left, VerticalAlignment.Top, Cursors.SizeNWSE),
AddRect("rCT", HorizontalAlignment.Center, VerticalAlignment.Top, Cursors.SizeNS),
AddRect("rRT", HorizontalAlignment.Right, VerticalAlignment.Top, Cursors.SizeNESW),
@@ -0,0 +1,54 @@
using System.Windows;
using System.Windows.Controls;
namespace Azaion.Annotator.Extensions;
public class ScrollViewerExtensions
{
public static readonly DependencyProperty AlwaysScrollToEndProperty =
DependencyProperty.RegisterAttached("AlwaysScrollToEnd", typeof(bool), typeof(ScrollViewerExtensions), new PropertyMetadata(false, AlwaysScrollToEndChanged));
private static bool _autoScroll;
private static void AlwaysScrollToEndChanged(object sender, DependencyPropertyChangedEventArgs e)
{
if (sender is not ScrollViewer scroll)
throw new InvalidOperationException("The attached AlwaysScrollToEnd property can only be applied to ScrollViewer instances.");
var alwaysScrollToEnd = e.NewValue != null && (bool)e.NewValue;
if (alwaysScrollToEnd)
{
scroll.ScrollToEnd();
scroll.ScrollChanged += ScrollChanged;
}
else
scroll.ScrollChanged -= ScrollChanged;
}
public static bool GetAlwaysScrollToEnd(ScrollViewer scroll)
{
if (scroll == null)
throw new ArgumentNullException("scroll");
return (bool)scroll.GetValue(AlwaysScrollToEndProperty);
}
public static void SetAlwaysScrollToEnd(ScrollViewer scroll, bool alwaysScrollToEnd)
{
if (scroll == null)
throw new ArgumentNullException("scroll");
scroll.SetValue(AlwaysScrollToEndProperty, alwaysScrollToEnd);
}
private static void ScrollChanged(object sender, ScrollChangedEventArgs e)
{
var scroll = sender as ScrollViewer;
if (scroll == null)
throw new InvalidOperationException("The attached AlwaysScrollToEnd property can only be applied to ScrollViewer instances.");
if (e.ExtentHeightChange == 0)
_autoScroll = scroll.VerticalOffset == scroll.ScrollableHeight;
if (_autoScroll && e.ExtentHeightChange != 0)
scroll.ScrollToVerticalOffset(scroll.ExtentHeight);
}
}
@@ -47,11 +47,6 @@ public class VLCFrameExtractor(LibVLC libVLC)
_width = videoTrack.Data.Video.Width;
_height = videoTrack.Data.Video.Height;
//rescaling to DEFAULT_WIDTH
//TODO: probably rescaling is not necessary, should be checked
//_width = DEFAULT_WIDTH;
//_height = (uint)(DEFAULT_WIDTH * _height / (double)_width);
_pitch = Align32(_width * RGBA_BYTES);
_lines = Align32(_height);
_mediaPlayer.SetRate(PLAYBACK_RATE);
@@ -81,7 +76,6 @@ public class VLCFrameExtractor(LibVLC libVLC)
yield return (frameInfo.Time, ms);
Console.WriteLine($"Queue size: {FramesQueue.Count}");
frameInfo.Bitmap?.Dispose();
}
else
+13 -4
View File
@@ -489,9 +489,10 @@ public partial class MainWindow
return;
_mediator.Publish(new PlaybackControlEvent(PlaybackControlEnum.Play));
_mediaPlayer.SetPause(true);
var mediaInfo = (MediaFileInfo)LvFiles.SelectedItem;
_formState.CurrentMedia = mediaInfo;
_mediaPlayer.Stop();
var path = mediaInfo.Path;
var manualCancellationSource = new CancellationTokenSource();
@@ -505,20 +506,28 @@ public partial class MainWindow
_autoDetectDialog.Closing += (_, _) =>
{
manualCancellationSource.Cancel();
_mediaPlayer.Stop();
_mediaPlayer.SeekTo(TimeSpan.Zero);
Editor.RemoveAllAnns();
};
_autoDetectDialog.Top = Height - _autoDetectDialog.Height - 80;
_autoDetectDialog.Left = 5;
_ = Task.Run(async () =>
{
using var detector = new YOLODetector(_config);
Dispatcher.Invoke(() => _autoDetectDialog.Log("Ініціалізація AI..."));
var prevSeekTime = 0.0;
await foreach (var timeframe in _vlcFrameExtractor.ExtractFrames(path, token))
{
try
{
var detections = _aiDetector.Detect(timeframe.Stream);
if (timeframe.Time.TotalSeconds > prevSeekTime + 1)
{
Dispatcher.Invoke(() => SeekTo(timeframe.Time));
prevSeekTime = timeframe.Time.TotalSeconds;
}
if (!IsValidDetection(timeframe.Time, detections))
continue;
@@ -533,9 +542,8 @@ public partial class MainWindow
}
_autoDetectDialog.Close();
}, token);
_autoDetectDialog.ShowDialog();
Dispatcher.Invoke(() => Editor.Background = new SolidColorBrush(Color.FromArgb(1, 0, 0, 0)));
}
@@ -613,6 +621,7 @@ public partial class MainWindow
$"xy=({det.Label.CenterX:F2},{det.Label.CenterY:F2}), " +
$"size=({det.Label.Width:F2}, {det.Label.Height:F2}), " +
$"prob: {det.Probability:F1}%"));
Dispatcher.Invoke(() => _autoDetectDialog.Log(log));
var thumbnailDto = await _galleryManager.CreateThumbnail(imgPath, token);