add results pane

differentiate videos which already has annotations
This commit is contained in:
Oleksandr Bezdieniezhnykh
2024-07-20 13:50:10 +03:00
parent 288a34e992
commit 83e3532de2
11 changed files with 189 additions and 87 deletions
+63 -58
View File
@@ -1,6 +1,8 @@
using System.Collections.ObjectModel;
using System.IO;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using Azaion.Annotator.DTO;
using Azaion.Annotator.Extensions;
using LibVLCSharp.Shared;
@@ -9,6 +11,7 @@ using Microsoft.WindowsAPICodePack.Dialogs;
using Newtonsoft.Json;
using Point = System.Windows.Point;
using Size = System.Windows.Size;
using IntervalTree;
namespace Azaion.Annotator;
@@ -24,10 +27,13 @@ public partial class MainWindow
public ObservableCollection<AnnotationClass> AnnotationClasses { get; set; } = new();
private bool _suspendLayout;
public Dictionary<TimeSpan, List<YoloLabel>> Annotations { get; set; } = new();
public Dictionary<TimeSpan, List<AnnotationResult>> AnnotationResults { get; set; } = new();
private readonly TimeSpan _thresholdBefore = TimeSpan.FromMilliseconds(100);
private readonly TimeSpan _thresholdAfter = TimeSpan.FromMilliseconds(300);
public Dictionary<TimeSpan, List<YoloLabel>> AnnotationsDict { get; set; } = new();
private IntervalTree<TimeSpan, List<YoloLabel>> Annotations { get; set; } = new();
public MainWindow(LibVLC libVLC, MediaPlayer mediaPlayer,
IMediator mediator,
FormState formState,
@@ -111,20 +117,7 @@ public partial class MainWindow
_mediaPlayer.PositionChanged += (o, args) =>
{
Dispatcher.Invoke(() => VideoSlider.Value = _mediaPlayer.Position * VideoSlider.Maximum);
Dispatcher.Invoke(() => StatusClock.Text = $"{TimeSpan.FromMilliseconds(_mediaPlayer.Time):mm\\:ss} / {_formState.CurrentVideoLength:mm\\:ss}");
var time = TimeSpan.FromMilliseconds(_mediaPlayer.Time);
if (!Annotations.TryGetValue(time, out var annotations))
return;
foreach (var ann in annotations)
{
var annClass = _config.AnnotationClasses[ann.ClassNumber];
var annInfo = new CanvasLabel(ann, Editor.RenderSize, _formState.CurrentVideoSize);
Dispatcher.Invoke(() => Editor.CreateAnnotation(annClass, time, annInfo));
}
Dispatcher.Invoke(() => Editor.ClearExpiredAnnotations(time));
ShowTimeAnnotations(TimeSpan.FromMilliseconds(_mediaPlayer.Time));
};
VideoSlider.ValueChanged += (value, newValue) =>
@@ -147,59 +140,58 @@ public partial class MainWindow
Editor.FormState = _formState;
Editor.Mediator = _mediator;
}
public void LoadExistingAnnotations()
{
Annotations = LoadAnnotations();
_formState.AnnotationResults = LoadAnnotationResults();
DgAnnotations.ItemsSource = _formState.AnnotationResults;
}
private Dictionary<TimeSpan, List<YoloLabel>> LoadAnnotations()
private void ShowTimeAnnotations(TimeSpan time)
{
Dispatcher.Invoke(() => VideoSlider.Value = _mediaPlayer.Position * VideoSlider.Maximum);
Dispatcher.Invoke(() => StatusClock.Text = $"{TimeSpan.FromMilliseconds(_mediaPlayer.Time):mm\\:ss} / {_formState.CurrentVideoLength:mm\\:ss}");
Dispatcher.Invoke(() => Editor.ClearExpiredAnnotations(time));
var annotations = Annotations.Query(time).SelectMany(x => x).ToList();
foreach (var ann in annotations)
{
var annClass = _config.AnnotationClasses[ann.ClassNumber];
var annInfo = new CanvasLabel(ann, Editor.RenderSize, _formState.CurrentVideoSize);
Dispatcher.Invoke(() => Editor.CreateAnnotation(annClass, time, annInfo));
}
}
public void ReloadAnnotations()
{
_formState.AnnotationResults.Clear();
AnnotationsDict.Clear();
Annotations.Clear();
var labelDir = new DirectoryInfo(_config.LabelsDirectory);
if (!labelDir.Exists)
return new Dictionary<TimeSpan, List<YoloLabel>>();
return;
var labelFiles = labelDir.GetFiles($"{_formState.VideoName}_*");
return labelFiles.Select(x =>
foreach (var file in labelFiles)
{
var name = Path.GetFileNameWithoutExtension(x.Name);
return new
{
Name = x.FullName,
Time = _formState.GetTime(name)
};
}).ToDictionary(f => f.Time!.Value, f =>
{
var str = File.ReadAllText(f.Name);
return str.Split(Environment.NewLine).Select(YoloLabel.Parse)
.Where(x => x != null)
.ToList();
})!;
}
var name = Path.GetFileNameWithoutExtension(file.Name);
var time = _formState.GetTime(name)!.Value;
private List<AnnotationResult> LoadAnnotationResults()
{
var resultDir = new DirectoryInfo(_config!.ResultsDirectory);
if (!resultDir.Exists)
Directory.CreateDirectory(_config!.ResultsDirectory);
var resultsFile = resultDir.GetFiles($"{_formState!.CurrentFile}*").FirstOrDefault();
List<AnnotationResult> results;
if (resultsFile == null)
{
results = Annotations.Select(anns => new AnnotationResult(anns.Key, _formState.GetTimeName(anns.Key), anns.Value))
var str = File.ReadAllText(file.FullName);
var annotations = str.Split(Environment.NewLine).Select(YoloLabel.Parse)
.Where(ann => ann != null)
.ToList();
File.WriteAllText($"{_config.ResultsDirectory}/{_formState.VideoName}.json", JsonConvert.SerializeObject(results, Formatting.Indented));
AddAnnotation(time, annotations!);
}
else
results = JsonConvert.DeserializeObject<List<AnnotationResult>>(File.ReadAllText(File.ReadAllText(resultsFile.FullName)))!;
return results;
}
public async Task AddAnnotation(TimeSpan time, List<YoloLabel> annotations)
{
var fName = _formState.GetTimeName(time);
AnnotationsDict.Add(time, annotations!);
Annotations.Add(time.Subtract(_thresholdBefore), time.Add(_thresholdAfter), annotations);
_formState.AnnotationResults.Add(new AnnotationResult(time, fName, annotations, _config));
await File.WriteAllTextAsync($"{_config.ResultsDirectory}/{fName}.json", JsonConvert.SerializeObject(_formState.AnnotationResults));
}
private void ReloadFiles()
{
@@ -288,4 +280,17 @@ public partial class MainWindow
_helpWindow.Show();
_helpWindow.Activate();
}
private void DgAnnotationsRowClick(object sender, MouseButtonEventArgs e)
{
DgAnnotations.MouseDoubleClick += (sender, args) =>
{
Editor.RemoveAllAnns();
var dgRow = ItemsControl.ContainerFromElement((DataGrid)sender, (args.OriginalSource as DependencyObject)!) as DataGridRow;
var res = (AnnotationResult)dgRow!.Item;
_mediaPlayer.SetPause(true);
_mediaPlayer.Time = (long)res.Time.TotalMilliseconds;// + 250;
ShowTimeAnnotations(res.Time);
};
}
}