diff --git a/Azaion.Annotator/Annotator.xaml b/Azaion.Annotator/Annotator.xaml
index 24161c8..471b81d 100644
--- a/Azaion.Annotator/Annotator.xaml
+++ b/Azaion.Annotator/Annotator.xaml
@@ -176,11 +176,11 @@
-
-
+
_logger;
private readonly VLCFrameExtractor _vlcFrameExtractor;
private readonly IAIDetector _aiDetector;
+ private readonly AnnotationService _annotationService;
private readonly CancellationTokenSource _cancellationTokenSource = new();
- private ObservableCollection AnnotationClasses { get; set; } = new();
+ private ObservableCollection AnnotationClasses { get; set; } = new();
private bool _suspendLayout;
private readonly TimeSpan _thresholdBefore = TimeSpan.FromMilliseconds(100);
@@ -52,7 +53,7 @@ public partial class Annotator
private ObservableCollection AllMediaFiles { get; set; } = new();
private ObservableCollection FilteredMediaFiles { get; set; } = new();
- public IntervalTree> Annotations { get; set; } = new();
+ public IntervalTree> Detections { get; set; } = new();
private AutodetectDialog _autoDetectDialog = new() { Topmost = true };
public Annotator(
@@ -64,7 +65,8 @@ public partial class Annotator
HelpWindow helpWindow,
ILogger logger,
VLCFrameExtractor vlcFrameExtractor,
- IAIDetector aiDetector)
+ IAIDetector aiDetector,
+ AnnotationService annotationService)
{
InitializeComponent();
_appConfig = appConfig.Value;
@@ -77,6 +79,7 @@ public partial class Annotator
_logger = logger;
_vlcFrameExtractor = vlcFrameExtractor;
_aiDetector = aiDetector;
+ _annotationService = annotationService;
Loaded += OnLoaded;
Closed += OnFormClosed;
@@ -98,7 +101,7 @@ public partial class Annotator
ReloadFiles();
- AnnotationClasses = new ObservableCollection(_appConfig.AnnotationConfig.AnnotationClasses);
+ AnnotationClasses = new ObservableCollection(_appConfig.AnnotationConfig.AnnotationClasses);
LvClasses.ItemsSource = AnnotationClasses;
LvClasses.SelectedIndex = 0;
@@ -152,7 +155,7 @@ public partial class Annotator
LvClasses.SelectionChanged += (_, _) =>
{
- var selectedClass = (AnnotationClass)LvClasses.SelectedItem;
+ var selectedClass = (DetectionClass)LvClasses.SelectedItem;
Editor.CurrentAnnClass = selectedClass;
_mediator.Publish(new AnnClassSelectedEvent(selectedClass));
};
@@ -188,7 +191,7 @@ public partial class Annotator
OpenAnnotationResult((AnnotationResult)DgAnnotations.SelectedItem);
break;
case Key.Delete:
- var result = MessageBox.Show(Application.Current.MainWindow, "Чи дійсно видалити аннотації?","Підтвердження видалення", MessageBoxButton.OKCancel, MessageBoxImage.Question);
+ var result = MessageBox.Show("Чи дійсно видалити аннотації?","Підтвердження видалення", MessageBoxButton.OKCancel, MessageBoxImage.Question);
if (result != MessageBoxResult.OK)
return;
@@ -202,7 +205,7 @@ public partial class Annotator
File.Delete(Path.Combine(_appConfig.DirectoriesConfig.LabelsDirectory, $"{imgName}.txt"));
File.Delete(thumbnailPath);
_formState.AnnotationResults.Remove(annotationResult);
- Annotations.Remove(Annotations.Query(annotationResult.Time));
+ Detections.Remove(Detections.Query(annotationResult.Time));
}
break;
}
@@ -251,7 +254,7 @@ public partial class Annotator
Editor.ClearExpiredAnnotations(time);
});
- var annotations = Annotations.Query(time).SelectMany(x => x).Select(x => new Detection(x));
+ var annotations = Detections.Query(time).SelectMany(x => x).Select(x => new Detection(_formState.GetTimeName(time), x));
AddAnnotationsToCanvas(time, annotations);
}
@@ -285,7 +288,7 @@ public partial class Annotator
private async Task ReloadAnnotations(CancellationToken ct = default)
{
_formState.AnnotationResults.Clear();
- Annotations.Clear();
+ Detections.Clear();
Editor.RemoveAllAnns();
var labelDir = new DirectoryInfo(_appConfig.DirectoriesConfig.LabelsDirectory);
@@ -294,22 +297,21 @@ public partial class Annotator
var labelFiles = labelDir.GetFiles($"{_formState.VideoName}_??????.txt");
foreach (var file in labelFiles)
- {
- var name = Path.GetFileNameWithoutExtension(file.Name);
- var time = Constants.GetTime(name);
- await AddAnnotations(time, await YoloLabel.ReadFromFile(file.FullName, ct), ct);
- }
+ await AddAnnotations(Path.GetFileNameWithoutExtension(file.Name), await YoloLabel.ReadFromFile(file.FullName, ct), ct);
}
- public async Task AddAnnotations(TimeSpan? time, List annotations, CancellationToken ct = default)
- => await AddAnnotations(time, annotations.Select(x => new Detection(x)).ToList(), ct);
+ //Load from yolo label file
+ public async Task AddAnnotations(string name, List annotations, CancellationToken ct = default)
+ => await AddAnnotations(name, annotations.Select(x => new Detection(name, x)).ToList(), ct);
- public async Task AddAnnotations(TimeSpan? time, List detections, CancellationToken ct = default)
+ //Add manually
+ public async Task AddAnnotations(string name, List detections, CancellationToken ct = default)
{
+ var time = Constants.GetTime(name);
var timeValue = time ?? TimeSpan.FromMinutes(0);
- var previousAnnotations = Annotations.Query(timeValue);
- Annotations.Remove(previousAnnotations);
- Annotations.Add(timeValue.Subtract(_thresholdBefore), timeValue.Add(_thresholdAfter), detections.Cast().ToList());
+ var previousAnnotations = Detections.Query(timeValue);
+ Detections.Remove(previousAnnotations);
+ Detections.Add(timeValue.Subtract(_thresholdBefore), timeValue.Add(_thresholdAfter), detections);
var existingResult = _formState.AnnotationResults.FirstOrDefault(x => x.Time == time);
if (existingResult != null)
@@ -345,15 +347,15 @@ public partial class Annotator
return (-1).ToColor();
return colorNumber >= detectionClasses.Count
- ? _appConfig.AnnotationConfig.AnnotationClassesDict[detectionClasses.LastOrDefault()].Color
- : _appConfig.AnnotationConfig.AnnotationClassesDict[detectionClasses[colorNumber]].Color;
+ ? _appConfig.AnnotationConfig.DetectionClassesDict[detectionClasses.LastOrDefault()].Color
+ : _appConfig.AnnotationConfig.DetectionClassesDict[detectionClasses[colorNumber]].Color;
}
var detectionClasses = detections.Select(x => x.ClassNumber).Distinct().ToList();
annotationResult.ClassName = detectionClasses.Count > 1
- ? string.Join(", ", detectionClasses.Select(x => _appConfig.AnnotationConfig.AnnotationClassesDict[x].ShortName))
- : _appConfig.AnnotationConfig.AnnotationClassesDict[detectionClasses.FirstOrDefault()].Name;
+ ? string.Join(", ", detectionClasses.Select(x => _appConfig.AnnotationConfig.DetectionClassesDict[x].ShortName))
+ : _appConfig.AnnotationConfig.DetectionClassesDict[detectionClasses.FirstOrDefault()].Name;
annotationResult.ClassColor0 = GetAnnotationClass(detectionClasses, 0);
annotationResult.ClassColor1 = GetAnnotationClass(detectionClasses, 1);
@@ -442,8 +444,8 @@ public partial class Annotator
// private void AddClassBtnClick(object sender, RoutedEventArgs e)
// {
// LvClasses.IsReadOnly = false;
- // AnnotationClasses.Add(new AnnotationClass(AnnotationClasses.Count));
- // LvClasses.SelectedIndex = AnnotationClasses.Count - 1;
+ // DetectionClasses.Add(new DetectionClass(DetectionClasses.Count));
+ // LvClasses.SelectedIndex = DetectionClasses.Count - 1;
// }
private async void OpenFolderItemClick(object sender, RoutedEventArgs e) => await OpenFolder();
private async void OpenFolderButtonClick(object sender, RoutedEventArgs e) => await OpenFolder();
@@ -578,9 +580,10 @@ public partial class Annotator
{
try
{
+ var fName = Path.GetFileNameWithoutExtension(mediaInfo.Path);
var stream = new FileStream(mediaInfo.Path, FileMode.Open);
- var detections = await _aiDetector.Detect(stream, token);
- await ProcessDetection((TimeSpan.FromMilliseconds(0), stream), detections, token);
+ var detections = await _aiDetector.Detect(fName, stream, token);
+ await ProcessDetection((TimeSpan.FromMilliseconds(0), stream), Path.GetExtension(mediaInfo.Path), detections, token);
if (detections.Count != 0)
mediaInfo.HasAnnotations = true;
}
@@ -599,7 +602,8 @@ public partial class Annotator
Console.WriteLine($"Detect time: {timeframe.Time}");
try
{
- var detections = await _aiDetector.Detect(timeframe.Stream, token);
+ var fName = _formState.GetTimeName(timeframe.Time);
+ var detections = await _aiDetector.Detect(fName, timeframe.Stream, token);
var isValid = IsValidDetection(timeframe.Time, detections);
if (timeframe.Time.TotalSeconds > prevSeekTime + 1)
@@ -628,7 +632,7 @@ public partial class Annotator
continue;
mediaInfo.HasAnnotations = true;
- await ProcessDetection(timeframe, detections, token);
+ await ProcessDetection(timeframe, "jpg", detections, token);
}
catch (Exception ex)
{
@@ -685,7 +689,7 @@ public partial class Annotator
return false;
}
- private async Task ProcessDetection((TimeSpan Time, Stream Stream) timeframe, List detections, CancellationToken token = default)
+ private async Task ProcessDetection((TimeSpan Time, Stream Stream) timeframe, string imageExtension, List detections, CancellationToken token = default)
{
_previousDetection = (timeframe.Time, detections);
await Dispatcher.Invoke(async () =>
@@ -695,22 +699,24 @@ public partial class Annotator
var time = timeframe.Time;
var fName = _formState.GetTimeName(timeframe.Time);
- var imgPath = Path.Combine(_appConfig.DirectoriesConfig.ImagesDirectory, $"{fName}.jpg");
+ var imgPath = Path.Combine(_appConfig.DirectoriesConfig.ImagesDirectory, $"{fName}.{imageExtension}");
Editor.Background = new ImageBrush { ImageSource = await imgPath.OpenImage() };
Editor.RemoveAllAnns();
AddAnnotationsToCanvas(time, detections, true);
- await AddAnnotations(timeframe.Time, detections, token);
+ await AddAnnotations(fName, detections, token);
+ await _annotationService.SaveAnnotation(fName, imageExtension, detections, SourceEnum.AI, timeframe.Stream, token);
+
var log = string.Join(Environment.NewLine, detections.Select(det =>
- $"{_appConfig.AnnotationConfig.AnnotationClassesDict[det.ClassNumber].Name}: " +
+ $"{_appConfig.AnnotationConfig.DetectionClassesDict[det.ClassNumber].Name}: " +
$"xy=({det.CenterX:F2},{det.CenterY:F2}), " +
$"size=({det.Width:F2}, {det.Height:F2}), " +
$"prob: {det.Probability:F1}%"));
Dispatcher.Invoke(() => _autoDetectDialog.Log(log));
- await _mediator.Publish(new ImageCreatedEvent(imgPath), token);
+
}
catch (Exception e)
{
diff --git a/Azaion.Annotator/AnnotatorEventHandler.cs b/Azaion.Annotator/AnnotatorEventHandler.cs
index f68ab58..f366394 100644
--- a/Azaion.Annotator/AnnotatorEventHandler.cs
+++ b/Azaion.Annotator/AnnotatorEventHandler.cs
@@ -21,7 +21,6 @@ public class AnnotatorEventHandler(
Annotator mainWindow,
FormState formState,
AnnotationService annotationService,
- IMediator mediator,
ILogger logger,
IOptions dirConfig)
:
@@ -48,15 +47,15 @@ public class AnnotatorEventHandler(
public async Task Handle(AnnClassSelectedEvent notification, CancellationToken cancellationToken)
{
- SelectClass(notification.AnnotationClass);
+ SelectClass(notification.DetectionClass);
await Task.CompletedTask;
}
- private void SelectClass(AnnotationClass annClass)
+ private void SelectClass(DetectionClass annClass)
{
mainWindow.Editor.CurrentAnnClass = annClass;
- foreach (var ann in mainWindow.Editor.CurrentAnns.Where(x => x.IsSelected))
- ann.AnnotationClass = annClass;
+ foreach (var ann in mainWindow.Editor.CurrentDetections.Where(x => x.IsSelected))
+ ann.DetectionClass = annClass;
mainWindow.LvClasses.SelectedIndex = annClass.Id;
}
@@ -73,7 +72,7 @@ public class AnnotatorEventHandler(
if ((int)key >= (int)Key.NumPad1 && (int)key <= (int)Key.NumPad9)
keyNumber = key - Key.NumPad1;
if (keyNumber.HasValue)
- SelectClass((AnnotationClass)mainWindow.LvClasses.Items[keyNumber.Value]!);
+ SelectClass((DetectionClass)mainWindow.LvClasses.Items[keyNumber.Value]!);
if (_keysControlEnumDict.TryGetValue(key, out var value))
await ControlPlayback(value, cancellationToken);
@@ -144,7 +143,7 @@ public class AnnotatorEventHandler(
mainWindow.SeekTo(mediaPlayer.Time + step);
break;
case PlaybackControlEnum.SaveAnnotations:
- await SaveAnnotations();
+ await SaveAnnotations(cancellationToken);
break;
case PlaybackControlEnum.RemoveSelectedAnns:
@@ -229,18 +228,19 @@ public class AnnotatorEventHandler(
var time = formState.BackgroundTime ?? TimeSpan.FromMilliseconds(mediaPlayer.Time);
var fName = formState.GetTimeName(time);
- var currentAnns = mainWindow.Editor.CurrentAnns
- .Select(x => new YoloLabel(x.Info, mainWindow.Editor.RenderSize, formState.BackgroundTime.HasValue ? mainWindow.Editor.RenderSize : formState.CurrentVideoSize))
+ var currentDetections = mainWindow.Editor.CurrentDetections
+ .Select(x => new Detection(fName, x.GetLabel(mainWindow.Editor.RenderSize, formState.BackgroundTime.HasValue ? mainWindow.Editor.RenderSize : formState.CurrentVideoSize)))
.ToList();
- await mainWindow.AddAnnotations(time, currentAnns, cancellationToken);
+ await mainWindow.AddAnnotations(fName, currentDetections, cancellationToken);
- formState.CurrentMedia.HasAnnotations = mainWindow.Annotations.Count != 0;
+ formState.CurrentMedia.HasAnnotations = mainWindow.Detections.Count != 0;
mainWindow.LvFiles.Items.Refresh();
mainWindow.Editor.RemoveAllAnns();
var isVideo = formState.CurrentMedia.MediaType == MediaTypes.Video;
- var imgPath = Path.Combine(dirConfig.Value.ImagesDirectory, $"{fName}{(isVideo ? ".jpg" : Path.GetExtension(formState.CurrentMedia.Path))}");
+ var imageExtension = isVideo ? ".jpg" : Path.GetExtension(formState.CurrentMedia.Path);
+ var imgPath = Path.Combine(dirConfig.Value.ImagesDirectory, $"{fName}{imageExtension}");
if (isVideo)
{
@@ -267,8 +267,6 @@ public class AnnotatorEventHandler(
File.Copy(formState.CurrentMedia.Path, imgPath, overwrite: true);
NextMedia();
}
- await annotationService.SaveAnnotation(fName, currentAnns, SourceEnum.Manual, token: cancellationToken);
-
- await mediator.Publish(new ImageCreatedEvent(imgPath), cancellationToken);
+ await annotationService.SaveAnnotation(fName, imageExtension, currentDetections, SourceEnum.Manual, token: cancellationToken);
}
}
diff --git a/Azaion.Annotator/DTO/AnnClassSelectedEvent.cs b/Azaion.Annotator/DTO/AnnClassSelectedEvent.cs
index 2e0079b..5417378 100644
--- a/Azaion.Annotator/DTO/AnnClassSelectedEvent.cs
+++ b/Azaion.Annotator/DTO/AnnClassSelectedEvent.cs
@@ -3,7 +3,7 @@ using MediatR;
namespace Azaion.Annotator.DTO;
-public class AnnClassSelectedEvent(AnnotationClass annotationClass) : INotification
+public class AnnClassSelectedEvent(DetectionClass detectionClass) : INotification
{
- public AnnotationClass AnnotationClass { get; } = annotationClass;
+ public DetectionClass DetectionClass { get; } = detectionClass;
}
\ No newline at end of file
diff --git a/Azaion.Annotator/YOLODetector.cs b/Azaion.Annotator/YOLODetector.cs
index fafe424..883cf6c 100644
--- a/Azaion.Annotator/YOLODetector.cs
+++ b/Azaion.Annotator/YOLODetector.cs
@@ -15,7 +15,7 @@ namespace Azaion.Annotator;
public interface IAIDetector
{
- Task> Detect(Stream imageStream, CancellationToken cancellationToken = default);
+ Task> Detect(string fName, Stream imageStream, CancellationToken cancellationToken = default);
}
public class YOLODetector(IOptions recognitionConfig, IResourceLoader resourceLoader) : IAIDetector, IDisposable
@@ -25,7 +25,7 @@ public class YOLODetector(IOptions recognitionConfig, IReso
private const string YOLO_MODEL = "azaion.onnx";
- public async Task> Detect(Stream imageStream, CancellationToken cancellationToken)
+ public async Task> Detect(string fName, Stream imageStream, CancellationToken cancellationToken)
{
if (_predictor == null)
{
@@ -42,7 +42,7 @@ public class YOLODetector(IOptions recognitionConfig, IReso
var detections = result.Select(d =>
{
var label = new YoloLabel(new CanvasLabel(d.Name.Id, d.Bounds.X, d.Bounds.Y, d.Bounds.Width, d.Bounds.Height), imageSize, imageSize);
- return new Detection(label, (double?)d.Confidence * 100);
+ return new Detection(fName, label, (double?)d.Confidence * 100);
}).ToList();
return FilterOverlapping(detections);
diff --git a/Azaion.Common/Constants.cs b/Azaion.Common/Constants.cs
index 6f42d35..b8a2572 100644
--- a/Azaion.Common/Constants.cs
+++ b/Azaion.Common/Constants.cs
@@ -19,7 +19,7 @@ public class Constants
#region AnnotatorConfig
- public static readonly List DefaultAnnotationClasses =
+ public static readonly List DefaultAnnotationClasses =
[
new() { Id = 0, Name = "Броньована техніка", ShortName = "Бронь" },
new() { Id = 1, Name = "Вантажівка", ShortName = "Вантаж" },
@@ -62,7 +62,6 @@ public class Constants
public const int DEFAULT_THUMBNAIL_BORDER = 10;
public const string THUMBNAIL_PREFIX = "_thumb";
- public const string THUMBNAILS_CACHE_FILE = "thumbnails.cache";
#endregion
@@ -92,6 +91,14 @@ public class Constants
public const string ANNOTATION_PRODUCER = "AnnotationsProducer";
public const string ANNOTATION_CONFIRM_PRODUCER = "AnnotationsConfirmProducer";
+ #endregion
+
+ #region Database
+
+ public const string ANNOTATIONS_TABLENAME = "annotations";
+ public const string ANNOTATIONS_QUEUE_TABLENAME = "annotations_queue";
+ public const string ADMIN_EMAIL = "admin@azaion.com";
+ public const string DETECTIONS_TABLENAME = "detections";
#endregion
diff --git a/Azaion.Common/Controls/CanvasEditor.cs b/Azaion.Common/Controls/CanvasEditor.cs
index 1ef090f..d2d4430 100644
--- a/Azaion.Common/Controls/CanvasEditor.cs
+++ b/Azaion.Common/Controls/CanvasEditor.cs
@@ -24,7 +24,7 @@ public class CanvasEditor : Canvas
private readonly TextBlock _classNameHint;
private Rectangle _curRec = new();
- private AnnotationControl _curAnn = null!;
+ private DetectionControl _curAnn = null!;
private const int MIN_SIZE = 20;
private readonly TimeSpan _viewThreshold = TimeSpan.FromMilliseconds(400);
@@ -44,8 +44,8 @@ public class CanvasEditor : Canvas
set => SetValue(GetTimeFuncProp, value);
}
- private AnnotationClass _currentAnnClass = null!;
- public AnnotationClass CurrentAnnClass
+ private DetectionClass _currentAnnClass = null!;
+ public DetectionClass CurrentAnnClass
{
get => _currentAnnClass;
set
@@ -62,7 +62,7 @@ public class CanvasEditor : Canvas
}
}
- public readonly List CurrentAnns = new();
+ public readonly List CurrentDetections = new();
public CanvasEditor()
{
@@ -173,7 +173,7 @@ public class CanvasEditor : Canvas
SelectionState = SelectionState.AnnResizing;
_lastPos = e.GetPosition(this);
_curRec = (Rectangle)sender;
- _curAnn = (AnnotationControl)((Grid)_curRec.Parent).Parent;
+ _curAnn = (DetectionControl)((Grid)_curRec.Parent).Parent;
e.Handled = true;
}
@@ -233,7 +233,7 @@ public class CanvasEditor : Canvas
private void AnnotationPositionStart(object sender, MouseEventArgs e)
{
_lastPos = e.GetPosition(this);
- _curAnn = (AnnotationControl)sender;
+ _curAnn = (DetectionControl)sender;
if (!Keyboard.IsKeyDown(Key.LeftCtrl) && !Keyboard.IsKeyDown(Key.RightCtrl))
ClearSelections();
@@ -310,9 +310,9 @@ public class CanvasEditor : Canvas
});
}
- public AnnotationControl CreateAnnotation(AnnotationClass annClass, TimeSpan? time, CanvasLabel canvasLabel)
+ public DetectionControl CreateAnnotation(DetectionClass annClass, TimeSpan? time, CanvasLabel canvasLabel)
{
- var annotationControl = new AnnotationControl(annClass, time, AnnotationResizeStart, canvasLabel.Probability)
+ var annotationControl = new DetectionControl(annClass, time, AnnotationResizeStart, canvasLabel.Probability)
{
Width = canvasLabel.Width,
Height = canvasLabel.Height
@@ -321,40 +321,40 @@ public class CanvasEditor : Canvas
SetLeft(annotationControl, canvasLabel.X );
SetTop(annotationControl, canvasLabel.Y);
Children.Add(annotationControl);
- CurrentAnns.Add(annotationControl);
+ CurrentDetections.Add(annotationControl);
_newAnnotationRect.Fill = new SolidColorBrush(annClass.Color);
return annotationControl;
}
#endregion
- private void RemoveAnnotations(IEnumerable listToRemove)
+ private void RemoveAnnotations(IEnumerable listToRemove)
{
foreach (var ann in listToRemove)
{
Children.Remove(ann);
- CurrentAnns.Remove(ann);
+ CurrentDetections.Remove(ann);
}
}
public void RemoveAllAnns()
{
- foreach (var ann in CurrentAnns)
+ foreach (var ann in CurrentDetections)
Children.Remove(ann);
- CurrentAnns.Clear();
+ CurrentDetections.Clear();
}
- public void RemoveSelectedAnns() => RemoveAnnotations(CurrentAnns.Where(x => x.IsSelected).ToList());
+ public void RemoveSelectedAnns() => RemoveAnnotations(CurrentDetections.Where(x => x.IsSelected).ToList());
private void ClearSelections()
{
- foreach (var ann in CurrentAnns)
+ foreach (var ann in CurrentDetections)
ann.IsSelected = false;
}
public void ClearExpiredAnnotations(TimeSpan time)
{
- var expiredAnns = CurrentAnns.Where(x =>
+ var expiredAnns = CurrentDetections.Where(x =>
x.Time.HasValue &&
Math.Abs((time - x.Time.Value).TotalMilliseconds) > _viewThreshold.TotalMilliseconds)
.ToList();
diff --git a/Azaion.Common/Controls/AnnotationClasses.xaml b/Azaion.Common/Controls/DetectionClasses.xaml
similarity index 96%
rename from Azaion.Common/Controls/AnnotationClasses.xaml
rename to Azaion.Common/Controls/DetectionClasses.xaml
index 7ffb7d8..c823502 100644
--- a/Azaion.Common/Controls/AnnotationClasses.xaml
+++ b/Azaion.Common/Controls/DetectionClasses.xaml
@@ -1,4 +1,4 @@
- _resizeStart;
private const double RESIZE_RECT_SIZE = 9;
@@ -18,16 +18,16 @@ public class AnnotationControl : Border
private readonly Label _probabilityLabel;
public TimeSpan? Time { get; set; }
- private AnnotationClass _annotationClass = null!;
- public AnnotationClass AnnotationClass
+ private DetectionClass _detectionClass = null!;
+ public DetectionClass DetectionClass
{
- get => _annotationClass;
+ get => _detectionClass;
set
{
_grid.Background = value.ColorBrush;
_probabilityLabel.Background = value.ColorBrush;
_classNameLabel.Text = value.Name;
- _annotationClass = value;
+ _detectionClass = value;
}
}
@@ -44,13 +44,13 @@ public class AnnotationControl : Border
}
}
- public AnnotationControl(AnnotationClass annotationClass, TimeSpan? time, Action