mirror of
https://github.com/azaion/annotations.git
synced 2026-04-22 22:06:30 +00:00
fix switcher between modes in DatasetExplorer.xaml
This commit is contained in:
@@ -49,8 +49,8 @@ public partial class Annotator
|
|||||||
public bool FollowAI = false;
|
public bool FollowAI = false;
|
||||||
public bool IsInferenceNow = false;
|
public bool IsInferenceNow = false;
|
||||||
|
|
||||||
private readonly TimeSpan _thresholdBefore = TimeSpan.FromMilliseconds(100);
|
private readonly TimeSpan _thresholdBefore = TimeSpan.FromMilliseconds(50);
|
||||||
private readonly TimeSpan _thresholdAfter = TimeSpan.FromMilliseconds(300);
|
private readonly TimeSpan _thresholdAfter = TimeSpan.FromMilliseconds(150);
|
||||||
private static readonly Guid SaveConfigTaskId = Guid.NewGuid();
|
private static readonly Guid SaveConfigTaskId = Guid.NewGuid();
|
||||||
|
|
||||||
public ObservableCollection<MediaFileInfo> AllMediaFiles { get; set; } = new();
|
public ObservableCollection<MediaFileInfo> AllMediaFiles { get; set; } = new();
|
||||||
|
|||||||
@@ -82,26 +82,102 @@
|
|||||||
Grid.Row="1"
|
Grid.Row="1"
|
||||||
Orientation="Horizontal"
|
Orientation="Horizontal"
|
||||||
HorizontalAlignment="Center"
|
HorizontalAlignment="Center"
|
||||||
Margin="0,5,0,5">
|
Margin="0,2,0,2">
|
||||||
<RadioButton x:Name="NormalModeRadioButton"
|
<RadioButton x:Name="NormalModeRadioButton"
|
||||||
Tag="0"
|
Tag="0"
|
||||||
Content="Звичайний"
|
|
||||||
GroupName="Mode"
|
GroupName="Mode"
|
||||||
Checked="ModeRadioButton_Checked"
|
Checked="ModeRadioButton_Checked"
|
||||||
IsChecked="True"
|
IsChecked="{Binding IsChecked}"
|
||||||
Style="{StaticResource ButtonRadioButtonStyle}"/>
|
Style="{StaticResource ButtonRadioButtonStyle}">
|
||||||
|
<StackPanel Orientation="Horizontal">
|
||||||
|
<Image Height="16" Width="16">
|
||||||
|
<Image.Source>
|
||||||
|
<DrawingImage>
|
||||||
|
<DrawingImage.Drawing>
|
||||||
|
<DrawingGroup ClipGeometry="M0,0 V640 H640 V0 H0 Z">
|
||||||
|
<GeometryDrawing Brush="LightGray" Geometry="m256,105.5c-83.9,0-152.2,68.3-152.2,152.2 0,83.9 68.3,152.2 152.2,152.2 83.9,0 152.2-68.3
|
||||||
|
152.2-152.2 0-84-68.3-152.2-152.2-152.2zm0,263.5c-61.4,0-111.4-50-111.4-111.4 0-61.4 50-111.4 111.4-111.4 61.4,0 111.4,50 111.4,111.4
|
||||||
|
0,61.4-50,111.4-111.4,111.4z" />
|
||||||
|
<GeometryDrawing Brush="LightGray" Geometry="m256,74.8c11.3,0 20.4-9.1 20.4-20.4v-23c0-11.3-9.1-20.4-20.4-20.4-11.3,0-20.4,9.1-20.4,20.4v23c2.84217e-14,11.3 9.1,20.4 20.4,20.4z" />
|
||||||
|
<GeometryDrawing Brush="LightGray" Geometry="m256,437.2c-11.3,0-20.4,9.1-20.4,20.4v22.9c0,11.3 9.1,20.4 20.4,20.4 11.3,0 20.4-9.1 20.4-20.4v-22.9c0-11.2-9.1-20.4-20.4-20.4z" />
|
||||||
|
<GeometryDrawing Brush="LightGray" Geometry="m480.6,235.6h-23c-11.3,0-20.4,9.1-20.4,20.4 0,11.3 9.1,20.4 20.4,20.4h23c11.3,0 20.4-9.1 20.4-20.4 0-11.3-9.1-20.4-20.4-20.4z" />
|
||||||
|
<GeometryDrawing Brush="LightGray" Geometry="m54.4,235.6h-23c-11.3,0-20.4,9.1-20.4,20.4 0,11.3 9.1,20.4 20.4,20.4h22.9c11.3,0 20.4-9.1 20.4-20.4 0.1-11.3-9.1-20.4-20.3-20.4z" />
|
||||||
|
<GeometryDrawing Brush="LightGray" Geometry="M400.4,82.8L384.1,99c-8,8-8,20.9,0,28.9s20.9,8,28.9,0l16.2-16.2c8-8,8-20.9,0-28.9S408.3,74.8,400.4,82.8z" />
|
||||||
|
<GeometryDrawing Brush="LightGray" Geometry="m99,384.1l-16.2,16.2c-8,8-8,20.9 0,28.9 8,8 20.9,8 28.9,0l16.2-16.2c8-8 8-20.9 0-28.9s-20.9-7.9-28.9,0z" />
|
||||||
|
<GeometryDrawing Brush="LightGray" Geometry="m413,384.1c-8-8-20.9-8-28.9,0-8,8-8,20.9 0,28.9l16.2,16.2c8,8 20.9,8 28.9,0 8-8 8-20.9 0-28.9l-16.2-16.2z" />
|
||||||
|
<GeometryDrawing Brush="LightGray" Geometry="m99,127.9c8,8 20.9,8 28.9,0 8-8 8-20.9 0-28.9l-16.2-16.2c-8-8-20.9-8-28.9,0-8,8-8,20.9 0,28.9l16.2,16.2z" />
|
||||||
|
</DrawingGroup>
|
||||||
|
</DrawingImage.Drawing>
|
||||||
|
</DrawingImage>
|
||||||
|
</Image.Source>
|
||||||
|
</Image>
|
||||||
|
<TextBlock Text="Норма"
|
||||||
|
Padding="7"
|
||||||
|
/>
|
||||||
|
</StackPanel>
|
||||||
|
</RadioButton>
|
||||||
<RadioButton x:Name="EveningModeRadioButton"
|
<RadioButton x:Name="EveningModeRadioButton"
|
||||||
Tag="20"
|
Tag="20"
|
||||||
Content="Зима"
|
|
||||||
GroupName="Mode"
|
GroupName="Mode"
|
||||||
Checked="ModeRadioButton_Checked" Margin="10,0,0,0"
|
Checked="ModeRadioButton_Checked" Margin="3,0,0,0"
|
||||||
Style="{StaticResource ButtonRadioButtonStyle}"/>
|
Style="{StaticResource ButtonRadioButtonStyle}">
|
||||||
|
<StackPanel Orientation="Horizontal">
|
||||||
|
<Image Height="16" Width="16">
|
||||||
|
<Image.Source>
|
||||||
|
<DrawingImage>
|
||||||
|
<DrawingImage.Drawing>
|
||||||
|
<DrawingGroup ClipGeometry="M0,0 V640 H640 V0 H0 Z">
|
||||||
|
<GeometryDrawing Brush="LightGray" Geometry="m444.8,256l50.2-50.2c8-8 8-20.9 0-28.9-8-8-20.9-8-28.9,0l-58.7,58.7h-85c-1.3-4.2-3-8.3-5-12.1l60.1-60.1h83c11.3,
|
||||||
|
0 20.4-9.1 20.4-20.4 0-11.3-9.1-20.4-20.4-20.4h-71v-71c0-11.3-9.1-20.4-20.4-20.4s-20.4,9.1-20.4,20.4v83l-60.1,60.1c-3.8-2-7.9-3.7-12.1-5v-85l58.7-58.7c8-8 8-20.9
|
||||||
|
0-28.9-8-8-20.9-8-28.9,0l-50.3,50.1-50.2-50.2c-8-8-20.9-8-28.9,0-8,8-8,20.9 0,28.9l58.7,58.7v85c-4.2,1.3-8.3,
|
||||||
|
3-12.1,5l-60.1-60.1v-83c0-11.3-9.1-20.4-20.4-20.4-11.3,0-20.4,9.1-20.4,20.4v71h-71c-11.3,0-20.4,9.1-20.4,20.4 0,11.3 9.1,20.4 20.4,
|
||||||
|
20.4h83l60.1,60.1c-2,3.8-3.7,7.9-5,12.1h-85l-58.7-58.7c-8-8-20.9-8-28.9,0-8,8-8,20.9 0,28.9l50.1,50.3-50.2,50.2c-8,8-8,20.9 0,28.9
|
||||||
|
8,8 20.9,8 28.9,0l58.7-58.7h85c1.3,4.2 3,8.3 5,12.1l-60.1,60.1h-83c-11.3,0-20.4,9.1-20.4,20.4 0,11.3 9.1,20.4 20.4,20.4h71v71c0,11.3
|
||||||
|
9.1,20.4 20.4,20.4 11.3,0 20.4-9.1 20.4-20.4v-83l60.1-60.1c3.8,2 7.9,3.7 12.1,5v85l-58.7,58.7c-8,8-8,20.9 0,28.9 8,8 20.9,8 28.9,0l50.2-50.2
|
||||||
|
50.2,50.2c8,8 20.9,8 28.9,0 8-8 8-20.9 0-28.9l-58.7-58.7v-85c4.2-1.3 8.3-3 12.1-5l60.1,60.1v83c0,11.3 9.1,20.4 20.4,20.4s20.4-9.1 20.4-20.4v-71h71c11.3,0
|
||||||
|
20.4-9.1 20.4-20.4 0-11.3-9.1-20.4-20.4-20.4h-83l-60.1-60.1c2-3.8 3.7-7.9 5-12.1h85l58.7,58.7c8,8 20.9,8 28.9,0 8-8 8-20.9
|
||||||
|
0-28.9l-50-50.2zm-217.3,0c0-15.7 12.8-28.5 28.5-28.5s28.5,12.8 28.5,28.5-12.8,28.5-28.5,28.5-28.5-12.8-28.5-28.5z" />
|
||||||
|
</DrawingGroup>
|
||||||
|
</DrawingImage.Drawing>
|
||||||
|
</DrawingImage>
|
||||||
|
</Image.Source>
|
||||||
|
</Image>
|
||||||
|
<TextBlock Text="Зима"
|
||||||
|
Padding="7"
|
||||||
|
/>
|
||||||
|
</StackPanel>
|
||||||
|
</RadioButton>
|
||||||
<RadioButton x:Name="NightModeRadioButton"
|
<RadioButton x:Name="NightModeRadioButton"
|
||||||
Tag="40"
|
Tag="40"
|
||||||
Content="Ніч"
|
|
||||||
GroupName="Mode"
|
GroupName="Mode"
|
||||||
Checked="ModeRadioButton_Checked" Margin="10,0,0,0"
|
Checked="ModeRadioButton_Checked" Margin="3,0,0,0"
|
||||||
Style="{StaticResource ButtonRadioButtonStyle}"/>
|
Style="{StaticResource ButtonRadioButtonStyle}"
|
||||||
|
>
|
||||||
|
<StackPanel Orientation="Horizontal">
|
||||||
|
<Image Height="16" Width="16">
|
||||||
|
<Image.Source>
|
||||||
|
<DrawingImage>
|
||||||
|
<DrawingImage.Drawing>
|
||||||
|
<DrawingGroup ClipGeometry="M0,0 V640 H640 V0 H0 Z">
|
||||||
|
<GeometryDrawing Brush="LightGray" Geometry="m500,113.1c-2.4-7.5-8.9-13-16.8-14.1l-55.2-7.9-24.6-48.9c-3.5-7-10.7-11.4-18.5-11.4-7.8,0-15,4.4-18.5,11.4l-24.6,
|
||||||
|
48.9-55.2,7.9c-7.8,1.1-14.3,6.6-16.8,14.1-2.4,7.5-0.3,15.8 5.4,21.3l39.7,37.9-9.4,53.4c-1.4,7.7 1.8,15.6 8.1,20.2 6.3,4.7 14.7,5.3 21.7,1.7l49.5-25.5
|
||||||
|
49.5,25.5c3,1.5 6.2,2.3 9.5,2.3 4.3,0 8.6-1.4 12.2-4 6.3-4.6 9.5-12.5 8.1-20.2l-9.4-53.4 39.7-37.9c5.9-5.5 8-13.8 5.6-21.3zm-81.6,36.9c-5,4.8-7.3,
|
||||||
|
11.7-6.1,18.5l4.1,23.3-22-11.3c-5.9-3-13-3-18.9,0l-22,11.3 4.1-23.3c1.2-6.8-1.1-13.7-6.1-18.5l-16.9-16.2 23.8-3.4c6.7-1 12.5-5.1 15.5-11.2l11-21.9
|
||||||
|
11,21.9c3,6 8.8,10.2 15.5,11.2l23.8,3.4-16.8,16.2z" />
|
||||||
|
<GeometryDrawing Brush="LightGray" Geometry="m442,361c-14.9,3.4-30.3,5.1-45.7,5.1-113.8,0-206.4-92.6-206.4-206.3 0-41.8 12.4-82 35.9-116.3
|
||||||
|
4.8-7 4.8-16.3 0-23.4-4.8-7.1-13.4-10.5-21.8-8.6-54,12.2-103,42.7-138,86-35.4,43.8-55,99.2-55,155.7 0,66.2 25.8,128.4 72.6,175.2 46.8,46.8
|
||||||
|
109.1,72.6 175.3,72.6 81.9,0 158.4-40.4 204.8-108.1 4.8-7 4.8-16.3 0-23.4-4.8-7-13.4-10.4-21.7-8.5zm-183.1,98.5c-113.8,0-206.4-92.6-206.4-206.3
|
||||||
|
0-78.2 45.3-149.1 112.8-183.8-11.2,28.6-17,59.1-17, 90.4 0,66.2 25.8,128.4 72.6,175.2 46.7,46.7 108.8,72.5 174.9,72.6-37.3,33.1-85.8,51.9-136.9,51.9z" />
|
||||||
|
</DrawingGroup>
|
||||||
|
</DrawingImage.Drawing>
|
||||||
|
</DrawingImage>
|
||||||
|
</Image.Source>
|
||||||
|
</Image>
|
||||||
|
<TextBlock Text="Ніч"
|
||||||
|
Padding="7"
|
||||||
|
/>
|
||||||
|
</StackPanel>
|
||||||
|
</RadioButton>
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
</Grid>
|
</Grid>
|
||||||
</UserControl>
|
</UserControl>
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ public class DetectionClassChangedEventArgs(DetectionClass detectionClass, int c
|
|||||||
public partial class DetectionClasses
|
public partial class DetectionClasses
|
||||||
{
|
{
|
||||||
public event EventHandler<DetectionClassChangedEventArgs>? DetectionClassChanged;
|
public event EventHandler<DetectionClassChangedEventArgs>? DetectionClassChanged;
|
||||||
|
public bool IsChecked = true;
|
||||||
|
|
||||||
public DetectionClasses()
|
public DetectionClasses()
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ public class DetectionControl : Border
|
|||||||
{
|
{
|
||||||
_grid.Background = value.ColorBrush;
|
_grid.Background = value.ColorBrush;
|
||||||
_probabilityLabel.Background = value.ColorBrush;
|
_probabilityLabel.Background = value.ColorBrush;
|
||||||
_classNameLabel.Text = value.Name;
|
_classNameLabel.Text = value.UIName;
|
||||||
_detectionClass = value;
|
_detectionClass = value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -37,7 +37,7 @@ public class DetectionClass
|
|||||||
public int ClassNumber => Id + 1;
|
public int ClassNumber => Id + 1;
|
||||||
|
|
||||||
[JsonIgnore]
|
[JsonIgnore]
|
||||||
public int YoloId => (int)PhotoMode + Id;
|
public int YoloId => Id == -1 ? Id : (int)PhotoMode + Id;
|
||||||
|
|
||||||
[JsonIgnore]
|
[JsonIgnore]
|
||||||
public SolidColorBrush ColorBrush => new(Color);
|
public SolidColorBrush ColorBrush => new(Color);
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ public class PythonResourceLoader : IResourceLoader, IAuthProvider
|
|||||||
|
|
||||||
public PythonResourceLoader(PythonConfig config)
|
public PythonResourceLoader(PythonConfig config)
|
||||||
{
|
{
|
||||||
//StartPython();
|
StartPython();
|
||||||
_dealer.Options.Identity = Encoding.UTF8.GetBytes(_clientId.ToString("N"));
|
_dealer.Options.Identity = Encoding.UTF8.GetBytes(_clientId.ToString("N"));
|
||||||
_dealer.Connect($"tcp://{config.ZeroMqHost}:{config.ZeroMqPort}");
|
_dealer.Connect($"tcp://{config.ZeroMqHost}:{config.ZeroMqPort}");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -57,7 +57,7 @@
|
|||||||
<RowDefinition Height="32"></RowDefinition>
|
<RowDefinition Height="32"></RowDefinition>
|
||||||
</Grid.RowDefinitions>
|
</Grid.RowDefinitions>
|
||||||
<Grid.ColumnDefinitions>
|
<Grid.ColumnDefinitions>
|
||||||
<ColumnDefinition Width="200" />
|
<ColumnDefinition Width="250" />
|
||||||
<ColumnDefinition Width="4"/>
|
<ColumnDefinition Width="4"/>
|
||||||
<ColumnDefinition Width="*" />
|
<ColumnDefinition Width="*" />
|
||||||
</Grid.ColumnDefinitions>
|
</Grid.ColumnDefinitions>
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ public partial class DatasetExplorer
|
|||||||
private readonly AnnotationConfig _annotationConfig;
|
private readonly AnnotationConfig _annotationConfig;
|
||||||
private readonly DirectoriesConfig _directoriesConfig;
|
private readonly DirectoriesConfig _directoriesConfig;
|
||||||
|
|
||||||
private readonly Dictionary<int, List<Annotation>> _annotationsDict;
|
private readonly Dictionary<int, Dictionary<string, Annotation>> _annotationsDict;
|
||||||
private readonly CancellationTokenSource _cts = new();
|
private readonly CancellationTokenSource _cts = new();
|
||||||
|
|
||||||
public List<DetectionClass> AllDetectionClasses { get; set; }
|
public List<DetectionClass> AllDetectionClasses { get; set; }
|
||||||
@@ -61,7 +61,7 @@ public partial class DatasetExplorer
|
|||||||
|
|
||||||
var photoModes = Enum.GetValues(typeof(PhotoMode)).Cast<PhotoMode>().ToList();
|
var photoModes = Enum.GetValues(typeof(PhotoMode)).Cast<PhotoMode>().ToList();
|
||||||
_annotationsDict = _annotationConfig.DetectionClasses.SelectMany(cls => photoModes.Select(mode => (int)mode + cls.Id))
|
_annotationsDict = _annotationConfig.DetectionClasses.SelectMany(cls => photoModes.Select(mode => (int)mode + cls.Id))
|
||||||
.ToDictionary(x => x, _ => new List<Annotation>());
|
.ToDictionary(x => x, _ => new Dictionary<string, Annotation>());
|
||||||
_annotationsDict.Add(-1, []);
|
_annotationsDict.Add(-1, []);
|
||||||
|
|
||||||
AnnotationsClasses = annotationConfig.Value.DetectionClasses;
|
AnnotationsClasses = annotationConfig.Value.DetectionClasses;
|
||||||
@@ -141,8 +141,8 @@ public partial class DatasetExplorer
|
|||||||
public void AddAnnotationToDict(Annotation annotation)
|
public void AddAnnotationToDict(Annotation annotation)
|
||||||
{
|
{
|
||||||
foreach (var c in annotation.Classes)
|
foreach (var c in annotation.Classes)
|
||||||
_annotationsDict[c].Add(annotation);
|
_annotationsDict[c][annotation.Name] = annotation;
|
||||||
_annotationsDict[-1].Add(annotation);
|
_annotationsDict[-1][annotation.Name] = annotation;
|
||||||
}
|
}
|
||||||
|
|
||||||
private async Task LoadClassDistribution()
|
private async Task LoadClassDistribution()
|
||||||
@@ -277,9 +277,11 @@ public partial class DatasetExplorer
|
|||||||
private async Task ReloadThumbnails()
|
private async Task ReloadThumbnails()
|
||||||
{
|
{
|
||||||
SelectedAnnotations.Clear();
|
SelectedAnnotations.Clear();
|
||||||
foreach (var ann in _annotationsDict[ExplorerEditor.CurrentAnnClass.Id])
|
SelectedAnnotationDict.Clear();
|
||||||
|
var annotations = _annotationsDict[ExplorerEditor.CurrentAnnClass.YoloId];
|
||||||
|
foreach (var ann in annotations.OrderByDescending(x => x.Value.CreatedDate))
|
||||||
{
|
{
|
||||||
var annThumb = new AnnotationThumbnail(ann);
|
var annThumb = new AnnotationThumbnail(ann.Value);
|
||||||
SelectedAnnotations.Add(annThumb);
|
SelectedAnnotations.Add(annThumb);
|
||||||
SelectedAnnotationDict.Add(annThumb.Annotation.Name, annThumb);
|
SelectedAnnotationDict.Add(annThumb.Annotation.Name, annThumb);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -92,12 +92,15 @@ public class DatasetExplorerEventHandler(
|
|||||||
|
|
||||||
//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))
|
if (annotation.Classes.Contains(selectedClass) || selectedClass == -1)
|
||||||
{
|
{
|
||||||
var annThumb = new AnnotationThumbnail(annotation);
|
var annThumb = new AnnotationThumbnail(annotation);
|
||||||
datasetExplorer.SelectedAnnotations.Add(annThumb);
|
if (!datasetExplorer.SelectedAnnotationDict.ContainsKey(annThumb.Annotation.Name))
|
||||||
|
{
|
||||||
|
datasetExplorer.SelectedAnnotations.Insert(0, annThumb);
|
||||||
datasetExplorer.SelectedAnnotationDict.Add(annThumb.Annotation.Name, annThumb);
|
datasetExplorer.SelectedAnnotationDict.Add(annThumb.Annotation.Name, annThumb);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
await Task.CompletedTask;
|
await Task.CompletedTask;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -119,3 +119,4 @@ cdef class ApiClient:
|
|||||||
key = Security.get_model_encryption_key()
|
key = Security.get_model_encryption_key()
|
||||||
|
|
||||||
model_bytes = Security.decrypt_to(encrypted_model_bytes, key)
|
model_bytes = Security.decrypt_to(encrypted_model_bytes, key)
|
||||||
|
return model_bytes
|
||||||
|
|||||||
@@ -18,13 +18,13 @@ cdef class Inference:
|
|||||||
|
|
||||||
cdef bint is_video(self, str filepath)
|
cdef bint is_video(self, str filepath)
|
||||||
cdef run_inference(self, RemoteCommand cmd)
|
cdef run_inference(self, RemoteCommand cmd)
|
||||||
cdef _process_video(self, RemoteCommand cmd, str video_name)
|
cdef _process_video(self, RemoteCommand cmd, AIRecognitionConfig ai_config, str video_name)
|
||||||
cdef _process_images(self, RemoteCommand cmd, list[str] image_paths)
|
cdef _process_images(self, RemoteCommand cmd, AIRecognitionConfig ai_config, list[str] image_paths)
|
||||||
cdef stop(self)
|
cdef stop(self)
|
||||||
|
|
||||||
cdef preprocess(self, frames)
|
cdef preprocess(self, frames)
|
||||||
cdef remove_overlapping_detections(self, list[Detection] detections)
|
cdef remove_overlapping_detections(self, list[Detection] detections)
|
||||||
cdef postprocess(self, output)
|
cdef postprocess(self, output, ai_config)
|
||||||
cdef split_list_extend(self, lst, chunk_size)
|
cdef split_list_extend(self, lst, chunk_size)
|
||||||
|
|
||||||
cdef bint is_valid_annotation(self, Annotation annotation)
|
cdef bint is_valid_annotation(self, Annotation annotation, AIRecognitionConfig ai_config)
|
||||||
|
|||||||
@@ -20,7 +20,6 @@ cdef class Inference:
|
|||||||
self.model_width = 0
|
self.model_width = 0
|
||||||
self.model_height = 0
|
self.model_height = 0
|
||||||
self.class_names = None
|
self.class_names = None
|
||||||
self.ai_config = AIRecognitionConfig(4, 2, 0.25, 0.15, 15, 0.8, b'', [])
|
|
||||||
|
|
||||||
def init_ai(self):
|
def init_ai(self):
|
||||||
model_bytes = self.api_client.load_ai_model()
|
model_bytes = self.api_client.load_ai_model()
|
||||||
@@ -47,7 +46,7 @@ cdef class Inference:
|
|||||||
for frame in frames]
|
for frame in frames]
|
||||||
return np.vstack(blobs)
|
return np.vstack(blobs)
|
||||||
|
|
||||||
cdef postprocess(self, output):
|
cdef postprocess(self, output, ai_config):
|
||||||
cdef list[Detection] detections = []
|
cdef list[Detection] detections = []
|
||||||
cdef int ann_index
|
cdef int ann_index
|
||||||
cdef float x1, y1, x2, y2, conf, cx, cy, w, h
|
cdef float x1, y1, x2, y2, conf, cx, cy, w, h
|
||||||
@@ -70,6 +69,7 @@ cdef class Inference:
|
|||||||
y = (y1 + y2) / 2
|
y = (y1 + y2) / 2
|
||||||
w = x2 - x1
|
w = x2 - x1
|
||||||
h = y2 - y1
|
h = y2 - y1
|
||||||
|
if conf >= ai_config.probability_threshold:
|
||||||
detections.append(Detection(x, y, w, h, class_id, conf))
|
detections.append(Detection(x, y, w, h, class_id, conf))
|
||||||
filtered_detections = self.remove_overlapping_detections(detections)
|
filtered_detections = self.remove_overlapping_detections(detections)
|
||||||
results.append(filtered_detections)
|
results.append(filtered_detections)
|
||||||
@@ -116,30 +116,32 @@ cdef class Inference:
|
|||||||
cdef run_inference(self, RemoteCommand cmd):
|
cdef run_inference(self, RemoteCommand cmd):
|
||||||
cdef list[str] videos = []
|
cdef list[str] videos = []
|
||||||
cdef list[str] images = []
|
cdef list[str] images = []
|
||||||
|
cdef AIRecognitionConfig ai_config = AIRecognitionConfig.from_msgpack(cmd.data)
|
||||||
|
if ai_config is None:
|
||||||
|
raise Exception('ai recognition config is empty')
|
||||||
|
|
||||||
self.ai_config = AIRecognitionConfig.from_msgpack(cmd.data)
|
|
||||||
self.stop_signal = False
|
self.stop_signal = False
|
||||||
if self.session is None:
|
if self.session is None:
|
||||||
self.init_ai()
|
self.init_ai()
|
||||||
|
|
||||||
for m in self.ai_config.paths:
|
print(ai_config.paths)
|
||||||
|
for m in ai_config.paths:
|
||||||
if self.is_video(m):
|
if self.is_video(m):
|
||||||
videos.append(m)
|
videos.append(m)
|
||||||
else:
|
else:
|
||||||
images.append(m)
|
images.append(m)
|
||||||
|
|
||||||
# images first, it's faster
|
# images first, it's faster
|
||||||
if len(images) > 0:
|
if len(images) > 0:
|
||||||
for chunk in self.split_list_extend(images, constants.MODEL_BATCH_SIZE):
|
for chunk in self.split_list_extend(images, constants.MODEL_BATCH_SIZE):
|
||||||
print(f'run inference on {" ".join(chunk)}...')
|
print(f'run inference on {" ".join(chunk)}...')
|
||||||
self._process_images(cmd, chunk)
|
self._process_images(cmd, ai_config, chunk)
|
||||||
if len(videos) > 0:
|
if len(videos) > 0:
|
||||||
for v in videos:
|
for v in videos:
|
||||||
print(f'run inference on {v}...')
|
print(f'run inference on {v}...')
|
||||||
self._process_video(cmd, v)
|
self._process_video(cmd, ai_config, v)
|
||||||
|
|
||||||
|
|
||||||
cdef _process_video(self, RemoteCommand cmd, str video_name):
|
cdef _process_video(self, RemoteCommand cmd, AIRecognitionConfig ai_config, str video_name):
|
||||||
cdef int frame_count = 0
|
cdef int frame_count = 0
|
||||||
cdef list batch_frames = []
|
cdef list batch_frames = []
|
||||||
cdef list[int] batch_timestamps = []
|
cdef list[int] batch_timestamps = []
|
||||||
@@ -152,30 +154,32 @@ cdef class Inference:
|
|||||||
break
|
break
|
||||||
|
|
||||||
frame_count += 1
|
frame_count += 1
|
||||||
if frame_count % self.ai_config.frame_period_recognition == 0:
|
if frame_count % ai_config.frame_period_recognition == 0:
|
||||||
batch_frames.append(frame)
|
batch_frames.append(frame)
|
||||||
batch_timestamps.append(int(v_input.get(cv2.CAP_PROP_POS_MSEC)))
|
batch_timestamps.append(int(v_input.get(cv2.CAP_PROP_POS_MSEC)))
|
||||||
|
|
||||||
if len(batch_frames) == constants.MODEL_BATCH_SIZE:
|
if len(batch_frames) == constants.MODEL_BATCH_SIZE:
|
||||||
input_blob = self.preprocess(batch_frames)
|
input_blob = self.preprocess(batch_frames)
|
||||||
outputs = self.session.run(None, {self.model_input: input_blob})
|
outputs = self.session.run(None, {self.model_input: input_blob})
|
||||||
list_detections = self.postprocess(outputs)
|
list_detections = self.postprocess(outputs, ai_config)
|
||||||
for i in range(len(list_detections)):
|
for i in range(len(list_detections)):
|
||||||
detections = list_detections[i]
|
detections = list_detections[i]
|
||||||
annotation = Annotation(video_name, batch_timestamps[i], detections)
|
annotation = Annotation(video_name, batch_timestamps[i], detections)
|
||||||
if self.is_valid_annotation(annotation):
|
if self.is_valid_annotation(annotation, ai_config):
|
||||||
_, image = cv2.imencode('.jpg', frame)
|
_, image = cv2.imencode('.jpg', batch_frames[i])
|
||||||
annotation.image = image.tobytes()
|
annotation.image = image.tobytes()
|
||||||
|
self._previous_annotation = annotation
|
||||||
|
|
||||||
print(annotation.to_str(self.class_names))
|
print(annotation.to_str(self.class_names))
|
||||||
self.on_annotation(cmd, annotation)
|
self.on_annotation(cmd, annotation)
|
||||||
self._previous_annotation = annotation
|
|
||||||
|
|
||||||
batch_frames.clear()
|
batch_frames.clear()
|
||||||
batch_timestamps.clear()
|
batch_timestamps.clear()
|
||||||
v_input.release()
|
v_input.release()
|
||||||
|
|
||||||
|
|
||||||
cdef _process_images(self, RemoteCommand cmd, list[str] image_paths):
|
cdef _process_images(self, RemoteCommand cmd, AIRecognitionConfig ai_config, list[str] image_paths):
|
||||||
cdef list frames = []
|
cdef list frames = []
|
||||||
cdef list timestamps = []
|
cdef list timestamps = []
|
||||||
self._previous_annotation = None
|
self._previous_annotation = None
|
||||||
@@ -186,7 +190,7 @@ cdef class Inference:
|
|||||||
|
|
||||||
input_blob = self.preprocess(frames)
|
input_blob = self.preprocess(frames)
|
||||||
outputs = self.session.run(None, {self.model_input: input_blob})
|
outputs = self.session.run(None, {self.model_input: input_blob})
|
||||||
list_detections = self.postprocess(outputs)
|
list_detections = self.postprocess(outputs, ai_config)
|
||||||
for i in range(len(list_detections)):
|
for i in range(len(list_detections)):
|
||||||
detections = list_detections[i]
|
detections = list_detections[i]
|
||||||
annotation = Annotation(image_paths[i], timestamps[i], detections)
|
annotation = Annotation(image_paths[i], timestamps[i], detections)
|
||||||
@@ -198,7 +202,7 @@ cdef class Inference:
|
|||||||
cdef stop(self):
|
cdef stop(self):
|
||||||
self.stop_signal = True
|
self.stop_signal = True
|
||||||
|
|
||||||
cdef bint is_valid_annotation(self, Annotation annotation):
|
cdef bint is_valid_annotation(self, Annotation annotation, AIRecognitionConfig ai_config):
|
||||||
# No detections, invalid
|
# No detections, invalid
|
||||||
if not annotation.detections:
|
if not annotation.detections:
|
||||||
return False
|
return False
|
||||||
@@ -208,7 +212,7 @@ cdef class Inference:
|
|||||||
return True
|
return True
|
||||||
|
|
||||||
# Enough time has passed since last annotation
|
# Enough time has passed since last annotation
|
||||||
if annotation.time >= self._previous_annotation.time + <long>(self.ai_config.frame_recognition_seconds * 1000):
|
if annotation.time >= self._previous_annotation.time + <long>(ai_config.frame_recognition_seconds * 1000):
|
||||||
return True
|
return True
|
||||||
|
|
||||||
# More objects detected than before
|
# More objects detected than before
|
||||||
@@ -236,11 +240,11 @@ cdef class Inference:
|
|||||||
closest_det = prev_det
|
closest_det = prev_det
|
||||||
|
|
||||||
# Check if beyond tracking distance
|
# Check if beyond tracking distance
|
||||||
if min_distance_sq > self.ai_config.tracking_distance_confidence:
|
if min_distance_sq > ai_config.tracking_distance_confidence:
|
||||||
return True
|
return True
|
||||||
|
|
||||||
# Check probability increase
|
# Check probability increase
|
||||||
if current_det.confidence >= closest_det.confidence + self.ai_config.tracking_probability_increase:
|
if current_det.confidence >= closest_det.confidence + ai_config.tracking_probability_increase:
|
||||||
return True
|
return True
|
||||||
|
|
||||||
return False
|
return False
|
||||||
|
|||||||
@@ -4,8 +4,6 @@ from PyInstaller.utils.hooks import collect_all
|
|||||||
datas = []
|
datas = []
|
||||||
binaries = []
|
binaries = []
|
||||||
hiddenimports = ['constants', 'annotation', 'credentials', 'file_data', 'user', 'security', 'secure_model', 'api_client', 'hardware_service', 'remote_command', 'ai_config', 'inference', 'remote_command_handler']
|
hiddenimports = ['constants', 'annotation', 'credentials', 'file_data', 'user', 'security', 'secure_model', 'api_client', 'hardware_service', 'remote_command', 'ai_config', 'inference', 'remote_command_handler']
|
||||||
tmp_ret = collect_all('pyyaml')
|
|
||||||
datas += tmp_ret[0]; binaries += tmp_ret[1]; hiddenimports += tmp_ret[2]
|
|
||||||
tmp_ret = collect_all('jwt')
|
tmp_ret = collect_all('jwt')
|
||||||
datas += tmp_ret[0]; binaries += tmp_ret[1]; hiddenimports += tmp_ret[2]
|
datas += tmp_ret[0]; binaries += tmp_ret[1]; hiddenimports += tmp_ret[2]
|
||||||
tmp_ret = collect_all('requests')
|
tmp_ret = collect_all('requests')
|
||||||
|
|||||||
@@ -51,8 +51,8 @@ public partial class App
|
|||||||
|
|
||||||
private readonly List<string> _encryptedResources =
|
private readonly List<string> _encryptedResources =
|
||||||
[
|
[
|
||||||
// "Azaion.Annotator",
|
"Azaion.Annotator",
|
||||||
// "Azaion.Dataset"
|
"Azaion.Dataset"
|
||||||
];
|
];
|
||||||
|
|
||||||
private static PythonConfig ReadPythonConfig()
|
private static PythonConfig ReadPythonConfig()
|
||||||
|
|||||||
+3
-2
@@ -1,5 +1,6 @@
|
|||||||
@echo off
|
@echo off
|
||||||
|
|
||||||
|
cd %~dp0..
|
||||||
echo Build .net app
|
echo Build .net app
|
||||||
dotnet build -c Release
|
dotnet build -c Release
|
||||||
|
|
||||||
@@ -46,8 +47,8 @@ move dist\start.exe ..\dist\azaion-inference.exe
|
|||||||
copy config.yaml ..\dist
|
copy config.yaml ..\dist
|
||||||
|
|
||||||
echo Download onnx model
|
echo Download onnx model
|
||||||
cd build
|
cd ..\build
|
||||||
call onnx_download.exe
|
call onnx_downloader.exe
|
||||||
move azaion.onnx.big ..\dist\
|
move azaion.onnx.big ..\dist\
|
||||||
cd ..
|
cd ..
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user