mirror of
https://github.com/azaion/annotations.git
synced 2026-04-22 11:16:30 +00:00
added better logging to python
add day / winter / night switcher
This commit is contained in:
@@ -120,8 +120,8 @@ public partial class Annotator
|
|||||||
TbFolder.Text = _appConfig.DirectoriesConfig.VideosDirectory;
|
TbFolder.Text = _appConfig.DirectoriesConfig.VideosDirectory;
|
||||||
|
|
||||||
AnnotationClasses = new ObservableCollection<DetectionClass>(_appConfig.AnnotationConfig.AnnotationClasses);
|
AnnotationClasses = new ObservableCollection<DetectionClass>(_appConfig.AnnotationConfig.AnnotationClasses);
|
||||||
LvClasses.ItemsSource = AnnotationClasses;
|
LvClasses.DetectionDataGrid.ItemsSource = AnnotationClasses;
|
||||||
LvClasses.SelectedIndex = 0;
|
LvClasses.SelectNum(0);
|
||||||
|
|
||||||
if (LvFiles.Items.IsEmpty)
|
if (LvFiles.Items.IsEmpty)
|
||||||
BlinkHelp(HelpTexts.HelpTextsDict[HelpTextEnum.Initial]);
|
BlinkHelp(HelpTexts.HelpTextsDict[HelpTextEnum.Initial]);
|
||||||
@@ -176,9 +176,9 @@ public partial class Annotator
|
|||||||
await _mediator.Publish(new AnnotatorControlEvent(PlaybackControlEnum.Play));
|
await _mediator.Publish(new AnnotatorControlEvent(PlaybackControlEnum.Play));
|
||||||
};
|
};
|
||||||
|
|
||||||
LvClasses.SelectionChanged += (_, _) =>
|
LvClasses.DetectionClassChanged += (_, args) =>
|
||||||
{
|
{
|
||||||
var selectedClass = (DetectionClass)LvClasses.SelectedItem;
|
var selectedClass = args.DetectionClass;
|
||||||
Editor.CurrentAnnClass = selectedClass;
|
Editor.CurrentAnnClass = selectedClass;
|
||||||
_mediator.Publish(new AnnClassSelectedEvent(selectedClass));
|
_mediator.Publish(new AnnClassSelectedEvent(selectedClass));
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -53,12 +53,12 @@ public class AnnotatorEventHandler(
|
|||||||
await Task.CompletedTask;
|
await Task.CompletedTask;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void SelectClass(DetectionClass annClass)
|
private void SelectClass(DetectionClass detClass)
|
||||||
{
|
{
|
||||||
mainWindow.Editor.CurrentAnnClass = annClass;
|
mainWindow.Editor.CurrentAnnClass = detClass;
|
||||||
foreach (var ann in mainWindow.Editor.CurrentDetections.Where(x => x.IsSelected))
|
foreach (var ann in mainWindow.Editor.CurrentDetections.Where(x => x.IsSelected))
|
||||||
ann.DetectionClass = annClass;
|
ann.DetectionClass = detClass;
|
||||||
mainWindow.LvClasses.SelectedIndex = annClass.Id;
|
mainWindow.LvClasses.SelectNum(detClass.Id);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task Handle(KeyEvent keyEvent, CancellationToken cancellationToken = default)
|
public async Task Handle(KeyEvent keyEvent, CancellationToken cancellationToken = default)
|
||||||
@@ -74,7 +74,7 @@ public class AnnotatorEventHandler(
|
|||||||
if ((int)key >= (int)Key.NumPad1 && (int)key <= (int)Key.NumPad9)
|
if ((int)key >= (int)Key.NumPad1 && (int)key <= (int)Key.NumPad9)
|
||||||
keyNumber = key - Key.NumPad1;
|
keyNumber = key - Key.NumPad1;
|
||||||
if (keyNumber.HasValue)
|
if (keyNumber.HasValue)
|
||||||
SelectClass((DetectionClass)mainWindow.LvClasses.Items[keyNumber.Value]!);
|
SelectClass((DetectionClass)mainWindow.LvClasses.DetectionDataGrid.Items[keyNumber.Value]!);
|
||||||
|
|
||||||
if (_keysControlEnumDict.TryGetValue(key, out var value))
|
if (_keysControlEnumDict.TryGetValue(key, out var value))
|
||||||
await ControlPlayback(value, cancellationToken);
|
await ControlPlayback(value, cancellationToken);
|
||||||
|
|||||||
@@ -1,10 +1,44 @@
|
|||||||
<DataGrid x:Class="Azaion.Common.Controls.DetectionClasses"
|
<UserControl x:Class="Azaion.Common.Controls.DetectionClasses"
|
||||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||||
mc:Ignorable="d"
|
mc:Ignorable="d"
|
||||||
d:DesignHeight="300" d:DesignWidth="300"
|
d:DesignHeight="300" d:DesignWidth="300">
|
||||||
|
<UserControl.Resources>
|
||||||
|
<Style x:Key="ButtonRadioButtonStyle" TargetType="RadioButton">
|
||||||
|
<Setter Property="Template">
|
||||||
|
<Setter.Value>
|
||||||
|
<ControlTemplate TargetType="RadioButton">
|
||||||
|
<Border x:Name="Border" BorderBrush="{TemplateBinding BorderBrush}"
|
||||||
|
Background="{TemplateBinding Background}" BorderThickness="1"
|
||||||
|
Padding="10,5" CornerRadius="2">
|
||||||
|
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center"/>
|
||||||
|
</Border>
|
||||||
|
<ControlTemplate.Triggers>
|
||||||
|
<Trigger Property="IsChecked" Value="True">
|
||||||
|
<Setter TargetName="Border" Property="Background" Value="Gray"/>
|
||||||
|
</Trigger>
|
||||||
|
<Trigger Property="IsMouseOver" Value="True">
|
||||||
|
<Setter TargetName="Border" Property="Background" Value="DarkGray"/>
|
||||||
|
</Trigger>
|
||||||
|
</ControlTemplate.Triggers>
|
||||||
|
</ControlTemplate>
|
||||||
|
</Setter.Value>
|
||||||
|
</Setter>
|
||||||
|
<Setter Property="Background" Value="Transparent"/>
|
||||||
|
<Setter Property="BorderBrush" Value="White"/>
|
||||||
|
<Setter Property="Foreground" Value="White"/>
|
||||||
|
</Style>
|
||||||
|
</UserControl.Resources>
|
||||||
|
<Grid Background="Black">
|
||||||
|
<Grid.RowDefinitions>
|
||||||
|
<RowDefinition Height="*" />
|
||||||
|
<RowDefinition Height="Auto" />
|
||||||
|
</Grid.RowDefinitions>
|
||||||
|
<!-- Your DataGrid with detection classes -->
|
||||||
|
<DataGrid x:Name="DetectionDataGrid"
|
||||||
|
Grid.Row="0"
|
||||||
Background="Black"
|
Background="Black"
|
||||||
RowBackground="#252525"
|
RowBackground="#252525"
|
||||||
Foreground="White"
|
Foreground="White"
|
||||||
@@ -15,35 +49,58 @@
|
|||||||
CellStyle="{DynamicResource DataGridCellStyle1}"
|
CellStyle="{DynamicResource DataGridCellStyle1}"
|
||||||
IsReadOnly="True"
|
IsReadOnly="True"
|
||||||
CanUserResizeRows="False"
|
CanUserResizeRows="False"
|
||||||
CanUserResizeColumns="False">
|
CanUserResizeColumns="False"
|
||||||
|
SelectionChanged="DetectionDataGrid_SelectionChanged"
|
||||||
|
x:FieldModifier="public">
|
||||||
<DataGrid.Columns>
|
<DataGrid.Columns>
|
||||||
<DataGridTemplateColumn
|
<DataGridTemplateColumn Width="50" Header="Клавіша" CanUserSort="False">
|
||||||
Width="50"
|
|
||||||
Header="Клавіша"
|
|
||||||
CanUserSort="False">
|
|
||||||
<DataGridTemplateColumn.HeaderStyle>
|
<DataGridTemplateColumn.HeaderStyle>
|
||||||
<Style TargetType="DataGridColumnHeader">
|
<Style TargetType="DataGridColumnHeader">
|
||||||
<Setter Property="Background" Value="#252525"></Setter>
|
<Setter Property="Background" Value="#252525"/>
|
||||||
</Style>
|
</Style>
|
||||||
</DataGridTemplateColumn.HeaderStyle>
|
</DataGridTemplateColumn.HeaderStyle>
|
||||||
<DataGridTemplateColumn.CellTemplate>
|
<DataGridTemplateColumn.CellTemplate>
|
||||||
<DataTemplate>
|
<DataTemplate>
|
||||||
<Border Background="{Binding Path=ColorBrush}">
|
<Border Background="{Binding Path=ColorBrush}">
|
||||||
<TextBlock Text="{Binding Path=ClassNumber}"></TextBlock>
|
<TextBlock Text="{Binding Path=ClassNumber}"/>
|
||||||
</Border>
|
</Border>
|
||||||
</DataTemplate>
|
</DataTemplate>
|
||||||
</DataGridTemplateColumn.CellTemplate>
|
</DataGridTemplateColumn.CellTemplate>
|
||||||
</DataGridTemplateColumn>
|
</DataGridTemplateColumn>
|
||||||
<DataGridTextColumn
|
<DataGridTextColumn Width="*" Header="Назва" Binding="{Binding Path=Name}" CanUserSort="False">
|
||||||
Width="*"
|
|
||||||
Header="Назва"
|
|
||||||
Binding="{Binding Path=Name}"
|
|
||||||
CanUserSort="False">
|
|
||||||
<DataGridTextColumn.HeaderStyle>
|
<DataGridTextColumn.HeaderStyle>
|
||||||
<Style TargetType="DataGridColumnHeader">
|
<Style TargetType="DataGridColumnHeader">
|
||||||
<Setter Property="Background" Value="#252525"></Setter>
|
<Setter Property="Background" Value="#252525"/>
|
||||||
</Style>
|
</Style>
|
||||||
</DataGridTextColumn.HeaderStyle>
|
</DataGridTextColumn.HeaderStyle>
|
||||||
</DataGridTextColumn>
|
</DataGridTextColumn>
|
||||||
</DataGrid.Columns>
|
</DataGrid.Columns>
|
||||||
</DataGrid>
|
</DataGrid>
|
||||||
|
<!-- StackPanel with mode switcher RadioButtons -->
|
||||||
|
<StackPanel x:Name="ModeSwitcherPanel"
|
||||||
|
Grid.Row="1"
|
||||||
|
Orientation="Horizontal"
|
||||||
|
HorizontalAlignment="Center"
|
||||||
|
Margin="0,5,0,5">
|
||||||
|
<RadioButton x:Name="NormalModeRadioButton"
|
||||||
|
Tag="0"
|
||||||
|
Content="Звичайний"
|
||||||
|
GroupName="Mode"
|
||||||
|
Checked="ModeRadioButton_Checked"
|
||||||
|
IsChecked="True"
|
||||||
|
Style="{StaticResource ButtonRadioButtonStyle}"/>
|
||||||
|
<RadioButton x:Name="EveningModeRadioButton"
|
||||||
|
Tag="1"
|
||||||
|
Content="Зима"
|
||||||
|
GroupName="Mode"
|
||||||
|
Checked="ModeRadioButton_Checked" Margin="10,0,0,0"
|
||||||
|
Style="{StaticResource ButtonRadioButtonStyle}"/>
|
||||||
|
<RadioButton x:Name="NightModeRadioButton"
|
||||||
|
Tag="2"
|
||||||
|
Content="Ніч"
|
||||||
|
GroupName="Mode"
|
||||||
|
Checked="ModeRadioButton_Checked" Margin="10,0,0,0"
|
||||||
|
Style="{StaticResource ButtonRadioButtonStyle}"/>
|
||||||
|
</StackPanel>
|
||||||
|
</Grid>
|
||||||
|
</UserControl>
|
||||||
|
|||||||
@@ -1,9 +1,54 @@
|
|||||||
namespace Azaion.Common.Controls;
|
using System.Windows;
|
||||||
|
using System.Windows.Controls;
|
||||||
|
using Azaion.Common.DTO;
|
||||||
|
|
||||||
|
namespace Azaion.Common.Controls;
|
||||||
|
|
||||||
|
public class DetectionClassChangedEventArgs(DetectionClass? detectionClass, int classNumber) : EventArgs
|
||||||
|
{
|
||||||
|
public DetectionClass? DetectionClass { get; } = detectionClass;
|
||||||
|
public int ClassNumber { get; } = classNumber;
|
||||||
|
}
|
||||||
|
|
||||||
public partial class DetectionClasses
|
public partial class DetectionClasses
|
||||||
{
|
{
|
||||||
public DetectionClasses()
|
public event EventHandler<DetectionClassChangedEventArgs>? DetectionClassChanged;
|
||||||
|
public DetectionClasses() => InitializeComponent();
|
||||||
|
|
||||||
|
public int CurrentClassNumber { get; private set; } = 0;
|
||||||
|
public DetectionClass? CurrentDetectionClass { get; set; }
|
||||||
|
|
||||||
|
private void DetectionDataGrid_SelectionChanged(object sender, SelectionChangedEventArgs e) =>
|
||||||
|
RaiseDetectionClassChanged();
|
||||||
|
|
||||||
|
private void ModeRadioButton_Checked(object sender, RoutedEventArgs e) =>
|
||||||
|
RaiseDetectionClassChanged();
|
||||||
|
|
||||||
|
private void RaiseDetectionClassChanged()
|
||||||
{
|
{
|
||||||
InitializeComponent();
|
var detClass = (DetectionClass)DetectionDataGrid.SelectedItem;
|
||||||
|
var baseClassNumber = detClass?.Id ?? 0;
|
||||||
|
|
||||||
|
var modeAmplifier = 0;
|
||||||
|
foreach (var child in ModeSwitcherPanel.Children)
|
||||||
|
if (child is RadioButton { IsChecked: true } rb)
|
||||||
|
if (int.TryParse(rb.Tag?.ToString(), out int modeIndex))
|
||||||
|
{
|
||||||
|
if (detClass != null)
|
||||||
|
detClass.PhotoMode = (PhotoMode)modeIndex;
|
||||||
|
modeAmplifier += modeIndex * 20;
|
||||||
|
}
|
||||||
|
|
||||||
|
CurrentDetectionClass = detClass;
|
||||||
|
CurrentClassNumber = baseClassNumber + modeAmplifier;
|
||||||
|
|
||||||
|
DetectionClassChanged?.Invoke(this, new DetectionClassChangedEventArgs(detClass, CurrentClassNumber));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
public void SelectNum(int keyNumber)
|
||||||
|
{
|
||||||
|
DetectionDataGrid.SelectedIndex = keyNumber;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -11,8 +11,6 @@ public class AnnotationConfig
|
|||||||
[JsonIgnore]
|
[JsonIgnore]
|
||||||
public Dictionary<int, DetectionClass> DetectionClassesDict => _detectionClassesDict ??= AnnotationClasses.ToDictionary(x => x.Id);
|
public Dictionary<int, DetectionClass> DetectionClassesDict => _detectionClassesDict ??= AnnotationClasses.ToDictionary(x => x.Id);
|
||||||
|
|
||||||
public int? LastSelectedExplorerClass { get; set; }
|
|
||||||
|
|
||||||
public List<string> VideoFormats { get; set; } = null!;
|
public List<string> VideoFormats { get; set; } = null!;
|
||||||
public List<string> ImageFormats { get; set; } = null!;
|
public List<string> ImageFormats { get; set; } = null!;
|
||||||
|
|
||||||
|
|||||||
@@ -11,12 +11,21 @@ public class DetectionClass
|
|||||||
public string Name { get; set; } = null!;
|
public string Name { get; set; } = null!;
|
||||||
public string ShortName { get; set; } = null!;
|
public string ShortName { get; set; } = null!;
|
||||||
|
|
||||||
|
public PhotoMode PhotoMode { get; set; }
|
||||||
|
|
||||||
[JsonIgnore]
|
[JsonIgnore]
|
||||||
public Color Color => Id.ToColor();
|
public Color Color => Id.ToColor();
|
||||||
|
|
||||||
[JsonIgnore]
|
[JsonIgnore] //For UI
|
||||||
public int ClassNumber => Id + 1;
|
public int ClassNumber => Id + 1;
|
||||||
|
|
||||||
[JsonIgnore]
|
[JsonIgnore]
|
||||||
public SolidColorBrush ColorBrush => new(Color);
|
public SolidColorBrush ColorBrush => new(Color);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public enum PhotoMode
|
||||||
|
{
|
||||||
|
Regular = 0,
|
||||||
|
Winter = 20,
|
||||||
|
Night = 40
|
||||||
|
}
|
||||||
@@ -93,38 +93,20 @@ public partial class DatasetExplorer
|
|||||||
AllDetectionClasses = new ObservableCollection<DetectionClass>(
|
AllDetectionClasses = new ObservableCollection<DetectionClass>(
|
||||||
new List<DetectionClass> { new() {Id = -1, Name = "All", ShortName = "All"}}
|
new List<DetectionClass> { new() {Id = -1, Name = "All", ShortName = "All"}}
|
||||||
.Concat(_annotationConfig.AnnotationClasses));
|
.Concat(_annotationConfig.AnnotationClasses));
|
||||||
LvClasses.ItemsSource = AllDetectionClasses;
|
LvClasses.DetectionDataGrid.ItemsSource = AllDetectionClasses;
|
||||||
|
|
||||||
LvClasses.MouseUp += async (_, _) =>
|
LvClasses.DetectionClassChanged += async (_, args) =>
|
||||||
{
|
{
|
||||||
var selectedClass = (DetectionClass)LvClasses.SelectedItem;
|
ExplorerEditor.CurrentAnnClass = args.DetectionClass;
|
||||||
ExplorerEditor.CurrentAnnClass = selectedClass;
|
|
||||||
_annotationConfig.LastSelectedExplorerClass = selectedClass.Id;
|
|
||||||
|
|
||||||
if (Switcher.SelectedIndex == 0)
|
if (Switcher.SelectedIndex == 0)
|
||||||
await ReloadThumbnails();
|
await ReloadThumbnails();
|
||||||
else
|
else
|
||||||
foreach (var ann in ExplorerEditor.CurrentDetections.Where(x => x.IsSelected))
|
foreach (var ann in ExplorerEditor.CurrentDetections.Where(x => x.IsSelected))
|
||||||
ann.DetectionClass = selectedClass;
|
ann.DetectionClass = args.DetectionClass;
|
||||||
};
|
};
|
||||||
|
|
||||||
LvClasses.SelectionChanged += (_, _) =>
|
ExplorerEditor.CurrentAnnClass = (DetectionClass)LvClasses.CurrentDetectionClass;
|
||||||
{
|
|
||||||
if (Switcher.SelectedIndex != 1)
|
|
||||||
return;
|
|
||||||
|
|
||||||
var selectedClass = (DetectionClass)LvClasses.SelectedItem;
|
|
||||||
if (selectedClass == null)
|
|
||||||
return;
|
|
||||||
|
|
||||||
ExplorerEditor.CurrentAnnClass = selectedClass;
|
|
||||||
|
|
||||||
foreach (var ann in ExplorerEditor.CurrentDetections.Where(x => x.IsSelected))
|
|
||||||
ann.DetectionClass = selectedClass;
|
|
||||||
};
|
|
||||||
|
|
||||||
LvClasses.SelectedIndex = _annotationConfig.LastSelectedExplorerClass ?? 0;
|
|
||||||
ExplorerEditor.CurrentAnnClass = (DetectionClass)LvClasses.SelectedItem;
|
|
||||||
|
|
||||||
await _dbFactory.Run(async db =>
|
await _dbFactory.Run(async db =>
|
||||||
{
|
{
|
||||||
@@ -256,18 +238,18 @@ public partial class DatasetExplorer
|
|||||||
{
|
{
|
||||||
AnnotationsTab.Visibility = Visibility.Collapsed;
|
AnnotationsTab.Visibility = Visibility.Collapsed;
|
||||||
EditorTab.Visibility = Visibility.Visible;
|
EditorTab.Visibility = Visibility.Visible;
|
||||||
_tempSelectedClassIdx = LvClasses.SelectedIndex;
|
_tempSelectedClassIdx = LvClasses.CurrentClassNumber;
|
||||||
LvClasses.ItemsSource = _annotationConfig.AnnotationClasses;
|
LvClasses.DetectionDataGrid.ItemsSource = _annotationConfig.AnnotationClasses;
|
||||||
|
|
||||||
Switcher.SelectedIndex = 1;
|
Switcher.SelectedIndex = 1;
|
||||||
LvClasses.SelectedIndex = Math.Max(0, _tempSelectedClassIdx - 1);
|
LvClasses.SelectNum(Math.Max(0, _tempSelectedClassIdx - 1));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
AnnotationsTab.Visibility = Visibility.Visible;
|
AnnotationsTab.Visibility = Visibility.Visible;
|
||||||
EditorTab.Visibility = Visibility.Collapsed;
|
EditorTab.Visibility = Visibility.Collapsed;
|
||||||
LvClasses.ItemsSource = AllDetectionClasses;
|
LvClasses.DetectionDataGrid.ItemsSource = AllDetectionClasses;
|
||||||
LvClasses.SelectedIndex = _tempSelectedClassIdx;
|
LvClasses.SelectNum(_tempSelectedClassIdx);
|
||||||
Switcher.SelectedIndex = 0;
|
Switcher.SelectedIndex = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -42,7 +42,7 @@ public class DatasetExplorerEventHandler(
|
|||||||
if ((int)key >= (int)Key.NumPad1 && (int)key <= (int)Key.NumPad9) keyNumber = key - Key.NumPad1;
|
if ((int)key >= (int)Key.NumPad1 && (int)key <= (int)Key.NumPad9) keyNumber = key - Key.NumPad1;
|
||||||
|
|
||||||
if (keyNumber.HasValue)
|
if (keyNumber.HasValue)
|
||||||
datasetExplorer.LvClasses.SelectedIndex = keyNumber.Value;
|
datasetExplorer.LvClasses.SelectNum(keyNumber.Value);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (datasetExplorer.Switcher.SelectedIndex == 1 && _keysControlEnumDict.TryGetValue(key, out var value))
|
if (datasetExplorer.Switcher.SelectedIndex == 1 && _keysControlEnumDict.TryGetValue(key, out var value))
|
||||||
@@ -88,13 +88,11 @@ public class DatasetExplorerEventHandler(
|
|||||||
public async Task Handle(AnnotationCreatedEvent notification, CancellationToken cancellationToken)
|
public async Task Handle(AnnotationCreatedEvent notification, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
var annotation = notification.Annotation;
|
var annotation = notification.Annotation;
|
||||||
var selectedClass = ((DetectionClass?)datasetExplorer.LvClasses.SelectedItem)?.Id;
|
var selectedClass = datasetExplorer.LvClasses.CurrentClassNumber;
|
||||||
if (selectedClass == null)
|
|
||||||
return;
|
|
||||||
|
|
||||||
//TODO: For editing existing need to handle updates
|
//TODO: For editing existing need to handle updates
|
||||||
datasetExplorer.AddAnnotationToDict(annotation);
|
datasetExplorer.AddAnnotationToDict(annotation);
|
||||||
if (annotation.Classes.Contains(selectedClass.Value))
|
if (annotation.Classes.Contains(selectedClass))
|
||||||
{
|
{
|
||||||
var annThumb = new AnnotationThumbnail(annotation);
|
var annThumb = new AnnotationThumbnail(annotation);
|
||||||
datasetExplorer.SelectedAnnotations.Add(annThumb);
|
datasetExplorer.SelectedAnnotations.Add(annThumb);
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import json
|
import json
|
||||||
import os
|
import os
|
||||||
|
import time
|
||||||
from http import HTTPStatus
|
from http import HTTPStatus
|
||||||
from uuid import UUID
|
from uuid import UUID
|
||||||
import jwt
|
import jwt
|
||||||
@@ -97,7 +98,7 @@ cdef class ApiClient:
|
|||||||
|
|
||||||
stream = BytesIO(response.raw.read())
|
stream = BytesIO(response.raw.read())
|
||||||
data = Security.decrypt_to(stream, key)
|
data = Security.decrypt_to(stream, key)
|
||||||
print(f'loaded file: {filename}, {len(data)} bytes')
|
constants.log(<str>f'Downloaded file: {filename}, {len(data)} bytes')
|
||||||
return data
|
return data
|
||||||
|
|
||||||
cdef load_ai_model(self):
|
cdef load_ai_model(self):
|
||||||
|
|||||||
@@ -10,3 +10,6 @@ cdef str AI_MODEL_FILE # AI Model file
|
|||||||
|
|
||||||
cdef bytes DONE_SIGNAL
|
cdef bytes DONE_SIGNAL
|
||||||
cdef int MODEL_BATCH_SIZE
|
cdef int MODEL_BATCH_SIZE
|
||||||
|
|
||||||
|
|
||||||
|
cdef log(str log_message, bytes client_id=*)
|
||||||
@@ -1,3 +1,5 @@
|
|||||||
|
import time
|
||||||
|
|
||||||
cdef str CONFIG_FILE = "config.yaml" # Port for the zmq
|
cdef str CONFIG_FILE = "config.yaml" # Port for the zmq
|
||||||
|
|
||||||
cdef int QUEUE_MAXSIZE = 1000 # Maximum size of the command queue
|
cdef int QUEUE_MAXSIZE = 1000 # Maximum size of the command queue
|
||||||
@@ -10,3 +12,8 @@ cdef str AI_MODEL_FILE = "azaion.onnx"
|
|||||||
|
|
||||||
cdef bytes DONE_SIGNAL = b"DONE"
|
cdef bytes DONE_SIGNAL = b"DONE"
|
||||||
cdef int MODEL_BATCH_SIZE = 4
|
cdef int MODEL_BATCH_SIZE = 4
|
||||||
|
|
||||||
|
cdef log(str log_message, bytes client_id=None):
|
||||||
|
local_time = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime())
|
||||||
|
client_str = '' if client_id is None else f' {client_id}'
|
||||||
|
print(f'[{local_time}{client_str}]: {log_message}')
|
||||||
@@ -29,7 +29,6 @@ cdef class CommandProcessor:
|
|||||||
self.inference = Inference(self.api_client, self.on_annotation)
|
self.inference = Inference(self.api_client, self.on_annotation)
|
||||||
|
|
||||||
def start(self):
|
def start(self):
|
||||||
print('Started!')
|
|
||||||
while self.running:
|
while self.running:
|
||||||
try:
|
try:
|
||||||
command = self.inference_queue.get(timeout=0.5)
|
command = self.inference_queue.get(timeout=0.5)
|
||||||
|
|||||||
@@ -13,8 +13,8 @@ cdef class RemoteCommand:
|
|||||||
40: "STOP_INFERENCE",
|
40: "STOP_INFERENCE",
|
||||||
100: "EXIT"
|
100: "EXIT"
|
||||||
}
|
}
|
||||||
data_str = f'. Data: {len(self.data)} bytes' if self.data else ''
|
data_str = f'{len(self.data)} bytes' if self.data else ''
|
||||||
return f'{command_type_names[self.command_type]}: {data_str}'
|
return f'{command_type_names[self.command_type]} ({data_str})'
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
cdef from_msgpack(bytes data):
|
cdef from_msgpack(bytes data):
|
||||||
|
|||||||
@@ -14,7 +14,8 @@ cdef class RemoteCommandHandler:
|
|||||||
self._router.setsockopt(zmq.LINGER, 0)
|
self._router.setsockopt(zmq.LINGER, 0)
|
||||||
with open(<str>constants.CONFIG_FILE, "r") as f:
|
with open(<str>constants.CONFIG_FILE, "r") as f:
|
||||||
config = yaml.safe_load(f)
|
config = yaml.safe_load(f)
|
||||||
self._router.bind(f'tcp://*:{config["zmq_port"]}')
|
port = config["zmq_port"]
|
||||||
|
self._router.bind(f'tcp://*:{port}')
|
||||||
|
|
||||||
self._dealer = self._context.socket(zmq.DEALER)
|
self._dealer = self._context.socket(zmq.DEALER)
|
||||||
self._dealer.setsockopt(zmq.LINGER, 0)
|
self._dealer.setsockopt(zmq.LINGER, 0)
|
||||||
@@ -30,6 +31,7 @@ cdef class RemoteCommandHandler:
|
|||||||
for _ in range(4): # 4 worker threads
|
for _ in range(4): # 4 worker threads
|
||||||
worker = Thread(target=self._worker_loop, daemon=True)
|
worker = Thread(target=self._worker_loop, daemon=True)
|
||||||
self._workers.append(worker)
|
self._workers.append(worker)
|
||||||
|
print(f'Listening to commands on port {port}...')
|
||||||
|
|
||||||
cdef start(self):
|
cdef start(self):
|
||||||
self._proxy_thread.start()
|
self._proxy_thread.start()
|
||||||
@@ -60,7 +62,7 @@ cdef class RemoteCommandHandler:
|
|||||||
client_id, message = worker_socket.recv_multipart()
|
client_id, message = worker_socket.recv_multipart()
|
||||||
cmd = RemoteCommand.from_msgpack(<bytes> message)
|
cmd = RemoteCommand.from_msgpack(<bytes> message)
|
||||||
cmd.client_id = client_id
|
cmd.client_id = client_id
|
||||||
print(f'Received [{cmd}] from the client {client_id}')
|
constants.log(<str>f'{cmd}', client_id)
|
||||||
self._on_command(cmd)
|
self._on_command(cmd)
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
if not self._shutdown_event.is_set():
|
if not self._shutdown_event.is_set():
|
||||||
@@ -74,7 +76,7 @@ cdef class RemoteCommandHandler:
|
|||||||
with self._context.socket(zmq.DEALER) as socket:
|
with self._context.socket(zmq.DEALER) as socket:
|
||||||
socket.connect("inproc://backend")
|
socket.connect("inproc://backend")
|
||||||
socket.send_multipart([client_id, data])
|
socket.send_multipart([client_id, data])
|
||||||
print(f'{len(data)} bytes was sent to client {client_id}')
|
constants.log(<str>f'Sent {len(data)} bytes.', client_id)
|
||||||
|
|
||||||
cdef stop(self):
|
cdef stop(self):
|
||||||
self._shutdown_event.set()
|
self._shutdown_event.set()
|
||||||
|
|||||||
Reference in New Issue
Block a user