fix ai detection bugs #2

This commit is contained in:
Alex Bezdieniezhnykh
2024-11-05 13:01:36 +02:00
parent d8f60d7491
commit 5d537aeef6
6 changed files with 63 additions and 42 deletions
+7 -11
View File
@@ -13,12 +13,9 @@ public class AnnotationResult
[JsonProperty(PropertyName = "t")] [JsonProperty(PropertyName = "t")]
public TimeSpan Time { get; set; } public TimeSpan Time { get; set; }
[JsonProperty(PropertyName = "p")]
public double Percentage { get; set; }
public double Lat { get; set; } public double Lat { get; set; }
public double Lon { get; set; } public double Lon { get; set; }
public List<YoloLabel> Labels { get; set; } = new(); public List<Detection> Detections { get; set; } = new();
#region For Display in the grid #region For Display in the grid
@@ -32,10 +29,10 @@ public class AnnotationResult
{ {
get get
{ {
if (Labels.Count == 0) if (Detections.Count == 0)
return ""; return "";
var groups = Labels.Select(x => x.ClassNumber).GroupBy(x => x).ToList(); var groups = Detections.Select(x => x.ClassNumber).GroupBy(x => x).ToList();
return groups.Count > 1 return groups.Count > 1
? string.Join(",", groups.Select(x => x.Key + 1)) ? string.Join(",", groups.Select(x => x.Key + 1))
: _config.AnnotationClassesDict[groups.FirstOrDefault().Key].Name; : _config.AnnotationClassesDict[groups.FirstOrDefault().Key].Name;
@@ -49,10 +46,10 @@ public class AnnotationResult
get get
{ {
var defaultColor = (Color)ColorConverter.ConvertFromString("#404040"); var defaultColor = (Color)ColorConverter.ConvertFromString("#404040");
if (Labels.Count == 0) if (Detections.Count == 0)
return defaultColor; return defaultColor;
var groups = Labels.Select(x => x.ClassNumber).GroupBy(x => x).ToList(); var groups = Detections.Select(x => x.ClassNumber).GroupBy(x => x).ToList();
return groups.Count > 1 return groups.Count > 1
? defaultColor ? defaultColor
@@ -64,12 +61,11 @@ public class AnnotationResult
#endregion #endregion
public AnnotationResult() { } public AnnotationResult() { }
public AnnotationResult(TimeSpan time, string timeName, List<YoloLabel> labels, Config config) public AnnotationResult(TimeSpan time, string timeName, List<Detection> detections, Config config)
{ {
_config = config; _config = config;
Labels = labels; Detections = detections;
Time = time; Time = time;
Image = $"{timeName}.jpg"; Image = $"{timeName}.jpg";
Percentage = 100;
} }
} }
@@ -106,7 +106,7 @@ public class VLCFrameExtractor(LibVLC libVLC)
if (_frameCounter > 20 && _frameCounter % 10 == 0) if (_frameCounter > 20 && _frameCounter % 10 == 0)
{ {
var msToAdd = (_frameCounter - _lastFrame) * (_lastFrameTimestamp.TotalMilliseconds / _lastFrame); var msToAdd = (_frameCounter - _lastFrame) * (_lastFrame == 0 ? 0 : _lastFrameTimestamp.TotalMilliseconds / _lastFrame);
var time = _lastFrameTimestamp.Add(TimeSpan.FromMilliseconds(msToAdd)); var time = _lastFrameTimestamp.Add(TimeSpan.FromMilliseconds(msToAdd));
FramesQueue.Enqueue(new FrameInfo(time, _currentBitmap)); FramesQueue.Enqueue(new FrameInfo(time, _currentBitmap));
} }
+2 -2
View File
@@ -144,8 +144,8 @@ public class GalleryManager : IGalleryManager
var size = new Size(originalImage.Width, originalImage.Height); var size = new Size(originalImage.Width, originalImage.Height);
if (!File.Exists(labelName)) if (!File.Exists(labelName))
{ {
File.Move(imgPath, Path.Combine(_config.UnknownImages, imgName)); File.Delete(imgPath);
_logger.LogInformation($"No labels found for image {imgName}! Moved image to the {_config.UnknownImages} folder."); _logger.LogInformation($"No labels found for image {imgName}! Image deleted!");
return null; return null;
} }
var labels = (await YoloLabel.ReadFromFile(labelName, cancellationToken)) var labels = (await YoloLabel.ReadFromFile(labelName, cancellationToken))
+32 -12
View File
@@ -206,18 +206,18 @@ public partial class MainWindow
DgAnnotations.MouseDoubleClick += (sender, args) => DgAnnotations.MouseDoubleClick += (sender, args) =>
{ {
var dgRow = ItemsControl.ContainerFromElement((DataGrid)sender, (args.OriginalSource as DependencyObject)!) as DataGridRow; var dgRow = ItemsControl.ContainerFromElement((DataGrid)sender, (args.OriginalSource as DependencyObject)!) as DataGridRow;
var res = (AnnotationResult)dgRow!.Item; OpenAnnotationResult((AnnotationResult)dgRow!.Item);
_mediaPlayer.SetPause(true);
Editor.RemoveAllAnns();
_mediaPlayer.Time = (long)res.Time.TotalMilliseconds;
ShowTimeAnnotations(res.Time, showImage: true);
}; };
DgAnnotations.KeyUp += (sender, args) => DgAnnotations.KeyUp += (sender, args) =>
{ {
if (args.Key != Key.Delete) switch (args.Key)
return; {
case Key.Up:
case Key.Down: //cursor is already moved by system behaviour
OpenAnnotationResult((AnnotationResult)DgAnnotations.SelectedItem);
break;
case Key.Delete:
var result = MessageBox.Show("Чи дійсно видалити аннотації?","Підтвердження видалення", MessageBoxButton.OKCancel, MessageBoxImage.Question); var result = MessageBox.Show("Чи дійсно видалити аннотації?","Підтвердження видалення", MessageBoxButton.OKCancel, MessageBoxImage.Question);
if (result != MessageBoxResult.OK) if (result != MessageBoxResult.OK)
return; return;
@@ -233,6 +233,8 @@ public partial class MainWindow
_formState.AnnotationResults.Remove(annotationResult); _formState.AnnotationResults.Remove(annotationResult);
Annotations.Remove(Annotations.Query(annotationResult.Time)); Annotations.Remove(Annotations.Query(annotationResult.Time));
} }
break;
}
}; };
Editor.FormState = _formState; Editor.FormState = _formState;
@@ -240,6 +242,21 @@ public partial class MainWindow
DgAnnotations.ItemsSource = _formState.AnnotationResults; DgAnnotations.ItemsSource = _formState.AnnotationResults;
} }
public void OpenAnnotationResult(AnnotationResult res)
{
_mediaPlayer.SetPause(true);
Editor.RemoveAllAnns();
_mediaPlayer.Time = (long)res.Time.TotalMilliseconds;
Dispatcher.Invoke(() =>
{
VideoSlider.Value = _mediaPlayer.Position * VideoSlider.Maximum;
StatusClock.Text = $"{TimeSpan.FromMilliseconds(_mediaPlayer.Time):mm\\:ss} / {_formState.CurrentVideoLength:mm\\:ss}";
Editor.ClearExpiredAnnotations(res.Time);
});
AddAnnotationsToCanvas(res.Time, res.Detections, showImage: true);
}
private async Task SaveUserSettings() private async Task SaveUserSettings()
{ {
if (_suspendLayout) if (_suspendLayout)
@@ -256,7 +273,7 @@ public partial class MainWindow
}, TimeSpan.FromSeconds(5)); }, TimeSpan.FromSeconds(5));
} }
private void ShowTimeAnnotations(TimeSpan time, bool showImage = false) private void ShowTimeAnnotations(TimeSpan time)
{ {
Dispatcher.Invoke(() => Dispatcher.Invoke(() =>
{ {
@@ -266,7 +283,7 @@ public partial class MainWindow
}); });
var annotations = Annotations.Query(time).SelectMany(x => x).Select(x => new Detection(x)); var annotations = Annotations.Query(time).SelectMany(x => x).Select(x => new Detection(x));
AddAnnotationsToCanvas(time, annotations, showImage); AddAnnotationsToCanvas(time, annotations);
} }
private void AddAnnotationsToCanvas(TimeSpan? time, IEnumerable<Detection> labels, bool showImage = false) private void AddAnnotationsToCanvas(TimeSpan? time, IEnumerable<Detection> labels, bool showImage = false)
@@ -316,11 +333,14 @@ public partial class MainWindow
} }
public async Task AddAnnotations(TimeSpan? time, List<YoloLabel> annotations, CancellationToken ct = default) public async Task AddAnnotations(TimeSpan? time, List<YoloLabel> annotations, CancellationToken ct = default)
=> await AddAnnotations(time, annotations.Select(x => new Detection(x)).ToList(), ct);
public async Task AddAnnotations(TimeSpan? time, List<Detection> annotations, CancellationToken ct = default)
{ {
var timeValue = time ?? TimeSpan.FromMinutes(0); var timeValue = time ?? TimeSpan.FromMinutes(0);
var previousAnnotations = Annotations.Query(timeValue); var previousAnnotations = Annotations.Query(timeValue);
Annotations.Remove(previousAnnotations); Annotations.Remove(previousAnnotations);
Annotations.Add(timeValue.Subtract(_thresholdBefore), timeValue.Add(_thresholdAfter), annotations); Annotations.Add(timeValue.Subtract(_thresholdBefore), timeValue.Add(_thresholdAfter), annotations.Cast<YoloLabel>().ToList());
var existingResult = _formState.AnnotationResults.FirstOrDefault(x => x.Time == time); var existingResult = _formState.AnnotationResults.FirstOrDefault(x => x.Time == time);
if (existingResult != null) if (existingResult != null)
@@ -633,7 +653,7 @@ public partial class MainWindow
Editor.Background = new ImageBrush { ImageSource = await imgPath.OpenImage() }; Editor.Background = new ImageBrush { ImageSource = await imgPath.OpenImage() };
Editor.RemoveAllAnns(); Editor.RemoveAllAnns();
AddAnnotationsToCanvas(time, detections, true); AddAnnotationsToCanvas(time, detections, true);
await AddAnnotations(timeframe.Time, detections.Cast<YoloLabel>().ToList(), token); await AddAnnotations(timeframe.Time, detections, token);
var log = string.Join(Environment.NewLine, detections.Select(det => var log = string.Join(Environment.NewLine, detections.Select(det =>
$"{_config.AnnotationClassesDict[det.ClassNumber].Name}: " + $"{_config.AnnotationClassesDict[det.ClassNumber].Name}: " +
+7 -2
View File
@@ -243,6 +243,8 @@ public class MainWindowEventHandler :
private async Task SaveAnnotations() private async Task SaveAnnotations()
{ {
var annGridSelectedIndex = _mainWindow.DgAnnotations.SelectedIndex;
if (_formState.CurrentMedia == null) if (_formState.CurrentMedia == null)
return; return;
@@ -270,15 +272,18 @@ public class MainWindowEventHandler :
//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.BackgroundShown = false;
var annGrid = _mainWindow.DgAnnotations;
annGrid.SelectedIndex = Math.Min(annGrid.Items.Count, annGridSelectedIndex + 1);
_mainWindow.OpenAnnotationResult((AnnotationResult)annGrid.SelectedItem);
} }
else else
{ {
var resultHeight = (uint)Math.Round(RESULT_WIDTH / _formState.CurrentVideoSize.Width * _formState.CurrentVideoSize.Height); var resultHeight = (uint)Math.Round(RESULT_WIDTH / _formState.CurrentVideoSize.Width * _formState.CurrentVideoSize.Height);
_mediaPlayer.TakeSnapshot(0, destinationPath, RESULT_WIDTH, resultHeight); _mediaPlayer.TakeSnapshot(0, destinationPath, RESULT_WIDTH, resultHeight);
}
_mediaPlayer.Play(); _mediaPlayer.Play();
} }
}
else else
{ {
File.Copy(_formState.CurrentMedia.Path, destinationPath, overwrite: true); File.Copy(_formState.CurrentMedia.Path, destinationPath, overwrite: true);
+1 -1
View File
@@ -3,4 +3,4 @@ Works on Windows only for now
Install: Install:
1. C# dotnet with wpf 1. C# dotnet with wpf
2. CUDNN 2. [CUDNN](https://developer.nvidia.com/cudnn)