mirror of
https://github.com/azaion/annotations.git
synced 2026-04-22 11:06:30 +00:00
add offset
fixes add visual validation border and validate functionality
This commit is contained in:
@@ -13,22 +13,37 @@
|
||||
|
||||
<Window.Resources>
|
||||
<DataTemplate x:Key="ThumbnailTemplate" DataType="{x:Type dto:AnnotationImageView}">
|
||||
<Grid>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="*"></RowDefinition>
|
||||
<RowDefinition Height="32"></RowDefinition>
|
||||
</Grid.RowDefinitions>
|
||||
<Image
|
||||
Grid.Row="0"
|
||||
Source="{Binding Thumbnail}"
|
||||
Width="480"
|
||||
Height="270"
|
||||
Margin="2" />
|
||||
<TextBlock
|
||||
Grid.Row="1"
|
||||
Foreground="LightGray"
|
||||
Text="{Binding ImageName}" />
|
||||
</Grid>
|
||||
<Border BorderBrush="IndianRed" Padding="5">
|
||||
<Border.Style>
|
||||
<Style TargetType="Border">
|
||||
<Setter Property="BorderThickness" Value="0"></Setter>
|
||||
<Style.Triggers>
|
||||
<DataTrigger Binding="{Binding IsSeed}" Value="True">
|
||||
<Setter Property="BorderThickness" Value="8"></Setter>
|
||||
</DataTrigger>
|
||||
<DataTrigger Binding="{Binding IsSeed}" Value="False">
|
||||
<Setter Property="BorderThickness" Value="0"></Setter>
|
||||
</DataTrigger>
|
||||
</Style.Triggers>
|
||||
</Style>
|
||||
</Border.Style>
|
||||
<Grid>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="*"></RowDefinition>
|
||||
<RowDefinition Height="32"></RowDefinition>
|
||||
</Grid.RowDefinitions>
|
||||
<Image
|
||||
Grid.Row="0"
|
||||
Source="{Binding Thumbnail}"
|
||||
Width="480"
|
||||
Height="270"
|
||||
Margin="2" />
|
||||
<TextBlock
|
||||
Grid.Row="1"
|
||||
Foreground="LightGray"
|
||||
Text="{Binding ImageName}" />
|
||||
</Grid>
|
||||
</Border>
|
||||
</DataTemplate>
|
||||
</Window.Resources>
|
||||
|
||||
@@ -109,20 +124,29 @@
|
||||
</ItemsPanelTemplate>
|
||||
</StatusBar.ItemsPanel>
|
||||
<StatusBarItem Grid.Column="2" Background="Black">
|
||||
<TextBlock Name="RefreshThumbCaption">База іконок:</TextBlock>
|
||||
</StatusBarItem>
|
||||
<StatusBarItem Grid.Column="3" Background="Black">
|
||||
<ProgressBar x:Name="RefreshThumbBar"
|
||||
Width="150"
|
||||
Height="15"
|
||||
HorizontalAlignment="Stretch"
|
||||
Background="#252525"
|
||||
BorderBrush="#252525"
|
||||
Foreground="LightBlue"
|
||||
Maximum="100"
|
||||
Minimum="0"
|
||||
Value="0">
|
||||
</ProgressBar>
|
||||
<Button Name="ValidateBtn"
|
||||
Padding="2"
|
||||
ToolTip="Підтвердити валідність. Клавіша: [A]"
|
||||
Background="Black" BorderBrush="Black" Cursor="Hand"
|
||||
Click="ValidateAnnotationsClick">
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<Image>
|
||||
<Image.Source>
|
||||
<DrawingImage>
|
||||
<DrawingImage.Drawing>
|
||||
<DrawingGroup ClipGeometry="M0,0 V320 H320 V0 H0 Z">
|
||||
<GeometryDrawing Brush="LightGray" Geometry="m30.71 7.29-6-6a1 1 0 0 0 -.71-.29h-2v8a2 2 0 0 1 -2 2h-8a2 2 0 0
|
||||
1 -2-2v-8h-6a3 3 0 0 0 -3 3v24a3 3 0 0 0 3 3h2v-9a3 3 0 0 1 3-3h14a3 3 0 0 1 3 3v9h2a3 3 0 0 0 3-3v-20a1 1 0 0 0 -.29-.71z" />
|
||||
<GeometryDrawing Brush="LightGray" Geometry="m12 1h8v8h-8z" />
|
||||
<GeometryDrawing Brush="LightGray" Geometry="m23 21h-14a1 1 0 0 0 -1 1v9h16v-9a1 1 0 0 0 -1-1z" />
|
||||
</DrawingGroup>
|
||||
</DrawingImage.Drawing>
|
||||
</DrawingImage>
|
||||
</Image.Source>
|
||||
</Image>
|
||||
<TextBlock Text="Підтвердити валідність" Foreground="White" Padding="8 0 0 0"></TextBlock>
|
||||
</StackPanel>
|
||||
</Button>
|
||||
</StatusBarItem>
|
||||
<Separator Grid.Column="4"/>
|
||||
<StatusBarItem Grid.Column="5" Background="Black">
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
using System.Collections.ObjectModel;
|
||||
using System.IO;
|
||||
using System.Windows;
|
||||
using System.Windows.Input;
|
||||
using System.Windows.Media;
|
||||
@@ -8,6 +7,8 @@ using Azaion.Common.Database;
|
||||
using Azaion.Common.DTO;
|
||||
using Azaion.Common.DTO.Config;
|
||||
using Azaion.Common.Services;
|
||||
using Azaion.CommonSecurity.DTO;
|
||||
using Azaion.CommonSecurity.Services;
|
||||
using LinqToDB;
|
||||
using MediatR;
|
||||
using Microsoft.Extensions.Logging;
|
||||
@@ -26,13 +27,15 @@ public partial class DatasetExplorer : INotificationHandler<AnnotationCreatedEve
|
||||
private Dictionary<int, List<Annotation>> _annotationsDict;
|
||||
|
||||
public ObservableCollection<AnnotationImageView> SelectedAnnotations { get; set; } = new();
|
||||
private ObservableCollection<DetectionClass> AllAnnotationClasses { get; set; } = new();
|
||||
public ObservableCollection<DetectionClass> AllAnnotationClasses { get; set; } = new();
|
||||
|
||||
public Dictionary<string, LabelInfo> LabelsCache { get; set; } = new();
|
||||
private Dictionary<string, LabelInfo> LabelsCache { get; set; } = new();
|
||||
|
||||
private int _tempSelectedClassIdx = 0;
|
||||
private readonly IGalleryService _galleryService;
|
||||
private readonly IDbFactory _dbFactory;
|
||||
private readonly IMediator _mediator;
|
||||
private readonly AzaionApiClient _apiClient;
|
||||
|
||||
public bool ThumbnailLoading { get; set; }
|
||||
|
||||
@@ -44,13 +47,17 @@ public partial class DatasetExplorer : INotificationHandler<AnnotationCreatedEve
|
||||
ILogger<DatasetExplorer> logger,
|
||||
IGalleryService galleryService,
|
||||
FormState formState,
|
||||
IDbFactory dbFactory)
|
||||
IDbFactory dbFactory,
|
||||
IMediator mediator,
|
||||
AzaionApiClient apiClient)
|
||||
{
|
||||
_directoriesConfig = directoriesConfig.Value;
|
||||
_annotationConfig = annotationConfig.Value;
|
||||
_logger = logger;
|
||||
_galleryService = galleryService;
|
||||
_dbFactory = dbFactory;
|
||||
_mediator = mediator;
|
||||
_apiClient = apiClient;
|
||||
|
||||
InitializeComponent();
|
||||
Loaded += OnLoaded;
|
||||
@@ -73,14 +80,11 @@ public partial class DatasetExplorer : INotificationHandler<AnnotationCreatedEve
|
||||
ThumbnailsView.SelectionChanged += (_, _) =>
|
||||
{
|
||||
StatusText.Text = $"Обрано: {ThumbnailsView.SelectedItems.Count} | {ThumbnailsView.SelectedIndex} / {SelectedAnnotations.Count}";
|
||||
ValidateBtn.Visibility = ThumbnailsView.SelectedItems.Cast<AnnotationImageView>().Any(x => x.IsSeed)
|
||||
? Visibility.Visible
|
||||
: Visibility.Hidden;
|
||||
};
|
||||
|
||||
ExplorerEditor.GetTimeFunc = () => Constants.GetTime(CurrentAnnotation!.Annotation.ImagePath);
|
||||
galleryService.ThumbnailsUpdate += thumbnailsPercentage =>
|
||||
{
|
||||
Dispatcher.Invoke(() => RefreshThumbBar.Value = thumbnailsPercentage);
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
private async void OnLoaded(object sender, RoutedEventArgs e)
|
||||
@@ -135,7 +139,6 @@ public partial class DatasetExplorer : INotificationHandler<AnnotationCreatedEve
|
||||
await ReloadThumbnails();
|
||||
await LoadClassDistribution();
|
||||
|
||||
RefreshThumbBar.Value = _galleryService.ProcessedThumbnailsPercentage;
|
||||
DataContext = this;
|
||||
}
|
||||
|
||||
@@ -285,18 +288,30 @@ public partial class DatasetExplorer : INotificationHandler<AnnotationCreatedEve
|
||||
SelectedAnnotations.Add(new AnnotationImageView(ann));
|
||||
}
|
||||
|
||||
|
||||
private void AddThumbnail(Annotation annotation)
|
||||
public async Task Handle(AnnotationCreatedEvent notification, CancellationToken cancellationToken)
|
||||
{
|
||||
var annotation = notification.Annotation;
|
||||
var selectedClass = ((DetectionClass?)LvClasses.SelectedItem)?.Id;
|
||||
if (selectedClass == null)
|
||||
return;
|
||||
|
||||
//TODO: For editing existing need to handle updates
|
||||
AddAnnotationToDict(annotation);
|
||||
if (annotation.Classes.Contains(selectedClass.Value))
|
||||
{
|
||||
SelectedAnnotations.Add(new AnnotationImageView(annotation));
|
||||
}
|
||||
}
|
||||
|
||||
public async Task Handle(AnnotationCreatedEvent notification, CancellationToken cancellationToken) =>
|
||||
AddThumbnail(notification.Annotation);
|
||||
}
|
||||
private async void ValidateAnnotationsClick(object sender, RoutedEventArgs e)
|
||||
{
|
||||
try
|
||||
{
|
||||
await _mediator.Publish(new DatasetExplorerControlEvent(PlaybackControlEnum.ValidateAnnotations));
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogError(ex, ex.Message);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,26 +1,32 @@
|
||||
using System.IO;
|
||||
using System.Windows.Input;
|
||||
using Azaion.Common.DTO;
|
||||
using Azaion.Common.DTO.Config;
|
||||
using Azaion.Common.DTO.Queue;
|
||||
using Azaion.Common.Services;
|
||||
using MediatR;
|
||||
using Microsoft.Extensions.Options;
|
||||
|
||||
namespace Azaion.Dataset;
|
||||
|
||||
public class DatasetExplorerEventHandler(
|
||||
DatasetExplorer datasetExplorer,
|
||||
AnnotationService annotationService) : INotificationHandler<KeyEvent>
|
||||
AnnotationService annotationService)
|
||||
: INotificationHandler<KeyEvent>,
|
||||
INotificationHandler<DatasetExplorerControlEvent>
|
||||
{
|
||||
private readonly Dictionary<Key, PlaybackControlEnum> _keysControlEnumDict = new()
|
||||
{
|
||||
{ Key.Enter, PlaybackControlEnum.SaveAnnotations },
|
||||
{ Key.Delete, PlaybackControlEnum.RemoveSelectedAnns },
|
||||
{ Key.X, PlaybackControlEnum.RemoveAllAnns },
|
||||
{ Key.Escape, PlaybackControlEnum.Close }
|
||||
{ Key.Escape, PlaybackControlEnum.Close },
|
||||
{ Key.A, PlaybackControlEnum.ValidateAnnotations}
|
||||
};
|
||||
|
||||
public async Task Handle(DatasetExplorerControlEvent notification, CancellationToken cancellationToken)
|
||||
{
|
||||
await HandleControl(notification.PlaybackControl, cancellationToken);
|
||||
}
|
||||
|
||||
public async Task Handle(KeyEvent keyEvent, CancellationToken cancellationToken)
|
||||
{
|
||||
if (keyEvent.WindowEnum != WindowEnum.DatasetExplorer)
|
||||
@@ -37,11 +43,11 @@ public class DatasetExplorerEventHandler(
|
||||
else
|
||||
{
|
||||
if (datasetExplorer.Switcher.SelectedIndex == 1 && _keysControlEnumDict.TryGetValue(key, out var value))
|
||||
await HandleControl(value);
|
||||
await HandleControl(value, cancellationToken);
|
||||
}
|
||||
}
|
||||
|
||||
private async Task HandleControl(PlaybackControlEnum controlEnum)
|
||||
private async Task HandleControl(PlaybackControlEnum controlEnum, CancellationToken cancellationToken = default)
|
||||
{
|
||||
switch (controlEnum)
|
||||
{
|
||||
@@ -55,7 +61,7 @@ public class DatasetExplorerEventHandler(
|
||||
var detections = datasetExplorer.ExplorerEditor.CurrentDetections
|
||||
.Select(x => new Detection(fName, x.GetLabel(datasetExplorer.ExplorerEditor.RenderSize)))
|
||||
.ToList();
|
||||
await annotationService.SaveAnnotation(fName, extension, detections, SourceEnum.Manual);
|
||||
await annotationService.SaveAnnotation(fName, extension, detections, SourceEnum.Manual, token: cancellationToken);
|
||||
datasetExplorer.SwitchTab(toEditor: false);
|
||||
break;
|
||||
case PlaybackControlEnum.RemoveSelectedAnns:
|
||||
@@ -67,6 +73,15 @@ public class DatasetExplorerEventHandler(
|
||||
case PlaybackControlEnum.Close:
|
||||
datasetExplorer.SwitchTab(toEditor: false);
|
||||
break;
|
||||
case PlaybackControlEnum.ValidateAnnotations:
|
||||
var annotations = datasetExplorer.ThumbnailsView.SelectedItems.Cast<AnnotationImageView>()
|
||||
.Select(x => x.Annotation)
|
||||
.ToList();
|
||||
foreach (var annotation in annotations)
|
||||
{
|
||||
await annotationService.ValidateAnnotation(annotation, cancellationToken);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user