mirror of
https://github.com/azaion/annotations.git
synced 2026-04-22 22:26:31 +00:00
make right annotation list more vivid
fix creation new anns bug
This commit is contained in:
@@ -4,12 +4,15 @@ using Azaion.Annotator.Extensions;
|
|||||||
|
|
||||||
namespace Azaion.Annotator.DTO;
|
namespace Azaion.Annotator.DTO;
|
||||||
|
|
||||||
public class AnnotationClass(int id, string name = "")
|
public class AnnotationClass
|
||||||
{
|
{
|
||||||
public int Id { get; set; } = id;
|
public int Id { get; set; }
|
||||||
|
|
||||||
public string Name { get; set; } = name;
|
public string Name { get; set; }
|
||||||
public Color Color { get; set; } = id.ToColor();
|
public string ShortName { get; set; }
|
||||||
|
|
||||||
|
[JsonIgnore]
|
||||||
|
public Color Color => Id.ToColor();
|
||||||
|
|
||||||
[JsonIgnore]
|
[JsonIgnore]
|
||||||
public int ClassNumber => Id + 1;
|
public int ClassNumber => Id + 1;
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
using System.Windows.Media;
|
using System.Windows.Media;
|
||||||
|
using Azaion.Annotator.Extensions;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
|
|
||||||
namespace Azaion.Annotator.DTO;
|
namespace Azaion.Annotator.DTO;
|
||||||
@@ -23,38 +24,44 @@ public class AnnotationResult
|
|||||||
//For XAML Form
|
//For XAML Form
|
||||||
public string TimeStr => $"{Time:h\\:mm\\:ss}";
|
public string TimeStr => $"{Time:h\\:mm\\:ss}";
|
||||||
|
|
||||||
|
private List<int>? _detectionClasses = null!;
|
||||||
|
|
||||||
|
//For Form
|
||||||
[JsonIgnore]
|
[JsonIgnore]
|
||||||
//For XAML Form
|
|
||||||
public string ClassName
|
public string ClassName
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
if (Detections.Count == 0)
|
if (Detections.Count == 0)
|
||||||
return "";
|
return "";
|
||||||
|
_detectionClasses ??= Detections.Select(x => x.ClassNumber).Distinct().ToList();
|
||||||
|
|
||||||
var groups = Detections.Select(x => x.ClassNumber).GroupBy(x => x).ToList();
|
return _detectionClasses.Count > 1
|
||||||
return groups.Count > 1
|
? string.Join(", ", _detectionClasses.Select(x => _config.AnnotationClassesDict[x].ShortName))
|
||||||
? string.Join(",", groups.Select(x => x.Key + 1))
|
: _config.AnnotationClassesDict[_detectionClasses.FirstOrDefault()].Name;
|
||||||
: _config.AnnotationClassesDict[groups.FirstOrDefault().Key].Name;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
[JsonIgnore]
|
[JsonIgnore]
|
||||||
//For XAML Form
|
public Color ClassColor1 => GetAnnotationClass(0);
|
||||||
public Color ClassColor
|
[JsonIgnore]
|
||||||
|
public Color ClassColor2 => GetAnnotationClass(1);
|
||||||
|
[JsonIgnore]
|
||||||
|
public Color ClassColor3 => GetAnnotationClass(2);
|
||||||
|
[JsonIgnore]
|
||||||
|
public Color ClassColor4 => GetAnnotationClass(3);
|
||||||
|
|
||||||
|
private Color GetAnnotationClass(int colorNumber)
|
||||||
{
|
{
|
||||||
get
|
|
||||||
{
|
|
||||||
var defaultColor = (Color)ColorConverter.ConvertFromString("#404040");
|
|
||||||
if (Detections.Count == 0)
|
if (Detections.Count == 0)
|
||||||
return defaultColor;
|
return (-1).ToColor();
|
||||||
|
|
||||||
var groups = Detections.Select(x => x.ClassNumber).GroupBy(x => x).ToList();
|
_detectionClasses ??= Detections.Select(x => x.ClassNumber).Distinct().ToList();
|
||||||
|
|
||||||
return groups.Count > 1
|
return colorNumber >= _detectionClasses.Count
|
||||||
? defaultColor
|
? _config.AnnotationClassesDict[_detectionClasses.LastOrDefault()].Color
|
||||||
: _config.AnnotationClassesDict[groups.FirstOrDefault().Key].Color;
|
: _config.AnnotationClassesDict[_detectionClasses[colorNumber]].Color;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -22,6 +22,8 @@ public class Config
|
|||||||
public List<AnnotationClass> AnnotationClasses { get; set; } = [];
|
public List<AnnotationClass> AnnotationClasses { get; set; } = [];
|
||||||
|
|
||||||
private Dictionary<int, AnnotationClass>? _annotationClassesDict;
|
private Dictionary<int, AnnotationClass>? _annotationClassesDict;
|
||||||
|
|
||||||
|
[JsonIgnore]
|
||||||
public Dictionary<int, AnnotationClass> AnnotationClassesDict => _annotationClassesDict ??= AnnotationClasses.ToDictionary(x => x.Id);
|
public Dictionary<int, AnnotationClass> AnnotationClassesDict => _annotationClassesDict ??= AnnotationClasses.ToDictionary(x => x.Id);
|
||||||
|
|
||||||
public WindowConfig MainWindowConfig { get; set; } = null!;
|
public WindowConfig MainWindowConfig { get; set; } = null!;
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ public class FormState
|
|||||||
public Size CurrentVideoSize { get; set; }
|
public Size CurrentVideoSize { get; set; }
|
||||||
public TimeSpan CurrentVideoLength { get; set; }
|
public TimeSpan CurrentVideoLength { get; set; }
|
||||||
|
|
||||||
public bool BackgroundShown { get; set; }
|
public TimeSpan? BackgroundTime { get; set; }
|
||||||
public int CurrentVolume { get; set; } = 100;
|
public int CurrentVolume { get; set; } = 100;
|
||||||
public ObservableCollection<AnnotationResult> AnnotationResults { get; set; } = [];
|
public ObservableCollection<AnnotationResult> AnnotationResults { get; set; } = [];
|
||||||
public WindowsEnum ActiveWindow { get; set; }
|
public WindowsEnum ActiveWindow { get; set; }
|
||||||
|
|||||||
@@ -47,7 +47,7 @@ public partial class DatasetExplorer
|
|||||||
Loaded += async (_, _) =>
|
Loaded += async (_, _) =>
|
||||||
{
|
{
|
||||||
AllAnnotationClasses = new ObservableCollection<AnnotationClass>(
|
AllAnnotationClasses = new ObservableCollection<AnnotationClass>(
|
||||||
new List<AnnotationClass> { new(-1, "All") }
|
new List<AnnotationClass> { new() {Id = -1, Name = "All", ShortName = "All"}}
|
||||||
.Concat(_config.AnnotationClasses));
|
.Concat(_config.AnnotationClasses));
|
||||||
LvClasses.ItemsSource = AllAnnotationClasses;
|
LvClasses.ItemsSource = AllAnnotationClasses;
|
||||||
|
|
||||||
|
|||||||
@@ -260,7 +260,12 @@
|
|||||||
<Style TargetType="DataGridCell">
|
<Style TargetType="DataGridCell">
|
||||||
<Setter Property="Background">
|
<Setter Property="Background">
|
||||||
<Setter.Value>
|
<Setter.Value>
|
||||||
<SolidColorBrush Color="{Binding Path=ClassColor}"></SolidColorBrush>
|
<LinearGradientBrush StartPoint="0 0 " EndPoint="1 0">
|
||||||
|
<GradientStop Offset="0.3" Color="{Binding Path=ClassColor1}" />
|
||||||
|
<GradientStop Offset="0.5" Color="{Binding Path=ClassColor2}" />
|
||||||
|
<GradientStop Offset="0.8" Color="{Binding Path=ClassColor3}" />
|
||||||
|
<GradientStop Offset="0.99" Color="{Binding Path=ClassColor3}" />
|
||||||
|
</LinearGradientBrush>
|
||||||
</Setter.Value>
|
</Setter.Value>
|
||||||
</Setter>
|
</Setter>
|
||||||
</Style>
|
</Style>
|
||||||
|
|||||||
@@ -123,7 +123,7 @@ public partial class MainWindow
|
|||||||
|
|
||||||
ReloadFiles();
|
ReloadFiles();
|
||||||
if (_config.AnnotationClasses.Count == 0)
|
if (_config.AnnotationClasses.Count == 0)
|
||||||
_config.AnnotationClasses.Add(new AnnotationClass(0));
|
_config.AnnotationClasses.Add(new AnnotationClass{Id = 0});
|
||||||
|
|
||||||
AnnotationClasses = new ObservableCollection<AnnotationClass>(_config.AnnotationClasses);
|
AnnotationClasses = new ObservableCollection<AnnotationClass>(_config.AnnotationClasses);
|
||||||
LvClasses.ItemsSource = AnnotationClasses;
|
LvClasses.ItemsSource = AnnotationClasses;
|
||||||
@@ -299,7 +299,7 @@ public partial class MainWindow
|
|||||||
if (File.Exists(imgPath))
|
if (File.Exists(imgPath))
|
||||||
{
|
{
|
||||||
Editor.Background = new ImageBrush { ImageSource = await imgPath.OpenImage() };
|
Editor.Background = new ImageBrush { ImageSource = await imgPath.OpenImage() };
|
||||||
_formState.BackgroundShown = true;
|
_formState.BackgroundTime = time;
|
||||||
videoSize = Editor.RenderSize;
|
videoSize = Editor.RenderSize;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -150,10 +150,10 @@ public class MainWindowEventHandler :
|
|||||||
_mediaPlayer.Pause();
|
_mediaPlayer.Pause();
|
||||||
if (!_mediaPlayer.IsPlaying)
|
if (!_mediaPlayer.IsPlaying)
|
||||||
_mainWindow.BlinkHelp(HelpTexts.HelpTextsDict[HelpTextEnum.AnnotationHelp]);
|
_mainWindow.BlinkHelp(HelpTexts.HelpTextsDict[HelpTextEnum.AnnotationHelp]);
|
||||||
if (_formState.BackgroundShown)
|
if (_formState.BackgroundTime.HasValue)
|
||||||
{
|
{
|
||||||
_mainWindow.Editor.Background = new SolidColorBrush(Color.FromArgb(1, 0, 0, 0));
|
_mainWindow.Editor.Background = new SolidColorBrush(Color.FromArgb(1, 0, 0, 0));
|
||||||
_formState.BackgroundShown = false;
|
_formState.BackgroundTime = null;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case PlaybackControlEnum.Stop:
|
case PlaybackControlEnum.Stop:
|
||||||
@@ -248,11 +248,11 @@ public class MainWindowEventHandler :
|
|||||||
if (_formState.CurrentMedia == null)
|
if (_formState.CurrentMedia == null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
var time = TimeSpan.FromMilliseconds(_mediaPlayer.Time);
|
var time = _formState.BackgroundTime ?? TimeSpan.FromMilliseconds(_mediaPlayer.Time);
|
||||||
var fName = _formState.GetTimeName(time);
|
var fName = _formState.GetTimeName(time);
|
||||||
|
|
||||||
var currentAnns = _mainWindow.Editor.CurrentAnns
|
var currentAnns = _mainWindow.Editor.CurrentAnns
|
||||||
.Select(x => new YoloLabel(x.Info, _mainWindow.Editor.RenderSize, _formState.BackgroundShown ? _mainWindow.Editor.RenderSize : _formState.CurrentVideoSize))
|
.Select(x => new YoloLabel(x.Info, _mainWindow.Editor.RenderSize, _formState.BackgroundTime.HasValue ? _mainWindow.Editor.RenderSize : _formState.CurrentVideoSize))
|
||||||
.ToList();
|
.ToList();
|
||||||
|
|
||||||
await YoloLabel.WriteToFile(currentAnns, Path.Combine(_config.LabelsDirectory, $"{fName}.txt"));
|
await YoloLabel.WriteToFile(currentAnns, Path.Combine(_config.LabelsDirectory, $"{fName}.txt"));
|
||||||
@@ -267,12 +267,13 @@ public class MainWindowEventHandler :
|
|||||||
_mainWindow.Editor.RemoveAllAnns();
|
_mainWindow.Editor.RemoveAllAnns();
|
||||||
if (isVideo)
|
if (isVideo)
|
||||||
{
|
{
|
||||||
if (_formState.BackgroundShown)
|
if (_formState.BackgroundTime.HasValue)
|
||||||
{
|
{
|
||||||
//no need to save image, it's already there, just remove background
|
//no need to save image, it's already there, just remove background
|
||||||
_mainWindow.Editor.Background = new SolidColorBrush(Color.FromArgb(1, 0, 0, 0));
|
_mainWindow.Editor.Background = new SolidColorBrush(Color.FromArgb(1, 0, 0, 0));
|
||||||
_formState.BackgroundShown = false;
|
_formState.BackgroundTime = null;
|
||||||
|
|
||||||
|
//next item
|
||||||
var annGrid = _mainWindow.DgAnnotations;
|
var annGrid = _mainWindow.DgAnnotations;
|
||||||
annGrid.SelectedIndex = Math.Min(annGrid.Items.Count, annGridSelectedIndex + 1);
|
annGrid.SelectedIndex = Math.Min(annGrid.Items.Count, annGridSelectedIndex + 1);
|
||||||
_mainWindow.OpenAnnotationResult((AnnotationResult)annGrid.SelectedItem);
|
_mainWindow.OpenAnnotationResult((AnnotationResult)annGrid.SelectedItem);
|
||||||
|
|||||||
@@ -6,16 +6,17 @@
|
|||||||
"ResultsDirectory": "E:\\results",
|
"ResultsDirectory": "E:\\results",
|
||||||
"UnknownImages": "E:\\unknown",
|
"UnknownImages": "E:\\unknown",
|
||||||
"AnnotationClasses": [
|
"AnnotationClasses": [
|
||||||
{ "Id": 0, "Name": "Броньована техніка", "Color": "#40FF0000" },
|
{ "Id": 0, "Name": "Броньована техніка", "ShortName": "Бронь" },
|
||||||
{ "Id": 1, "Name": "Вантажівка", "Color": "#4000FF00" },
|
{ "Id": 1, "Name": "Вантажівка", "ShortName": "Вантаж" },
|
||||||
{ "Id": 2, "Name": "Машина легкова", "Color": "#400000FF" },
|
{ "Id": 2, "Name": "Машина легкова", "ShortName": "Машина" },
|
||||||
{ "Id": 3, "Name": "Артилерія", "Color": "#40FFFF00" },
|
{ "Id": 3, "Name": "Артилерія", "ShortName": "Арта" },
|
||||||
{ "Id": 4, "Name": "Тінь від техніки", "Color": "#40FF00FF" },
|
{ "Id": 4, "Name": "Тінь від техніки", "ShortName": "Тінь" },
|
||||||
{ "Id": 5, "Name": "Окопи", "Color": "#4000FFFF" },
|
{ "Id": 5, "Name": "Окопи", "ShortName": "Окопи" },
|
||||||
{ "Id": 6, "Name": "Військовий", "Color": "#40000000" },
|
{ "Id": 6, "Name": "Військовий", "ShortName": "Військов" },
|
||||||
{ "Id": 7, "Name": "Накати", "Color": "#40800000" },
|
{ "Id": 7, "Name": "Накати", "ShortName": "Накати" },
|
||||||
{ "Id": 8, "Name": "Танк з захистом", "Color": "#40008000" },
|
{ "Id": 8, "Name": "Танк з захистом", "ShortName": "Танк захист" },
|
||||||
{ "Id": 9, "Name": "Дим", "Color": "#40000080" }
|
{ "Id": 9, "Name": "Дим", "ShortName": "Дим" },
|
||||||
|
{ "Id": 10, "Name": "Літак", "ShortName": "Літак" }
|
||||||
],
|
],
|
||||||
"MainWindowConfig": {
|
"MainWindowConfig": {
|
||||||
"WindowSize": "1920,1080",
|
"WindowSize": "1920,1080",
|
||||||
|
|||||||
Reference in New Issue
Block a user