add generating result image to Results directory

This commit is contained in:
Alex Bezdieniezhnykh
2025-04-03 11:06:00 +03:00
parent 83ae6a0ae9
commit c9800107a6
15 changed files with 86 additions and 61 deletions
-3
View File
@@ -331,14 +331,11 @@ public partial class Annotator
{
try
{
_logger.LogInformation($"remove annotation {existingResult.TimeStr} {existingResult.ClassName}!");
_formState.AnnotationResults.Remove(existingResult);
_logger.LogInformation($"removed {existingResult.TimeStr} {existingResult.ClassName} sucessfully!");
}
catch (Exception e)
{
_logger.LogError(e, e.Message);
//Console.WriteLine(e);
throw;
}
+1
View File
@@ -63,6 +63,7 @@ public class Constants
public const int DEFAULT_THUMBNAIL_BORDER = 10;
public const string THUMBNAIL_PREFIX = "_thumb";
public const string RESULT_PREFIX = "_result";
#endregion
+1 -1
View File
@@ -121,7 +121,7 @@ public class DetectionControl : Border
var rect = new Rectangle() // small rectangles at the corners and sides
{
ClipToBounds = false,
Margin = new Thickness(-RESIZE_RECT_SIZE),
Margin = new Thickness(-RESIZE_RECT_SIZE * 0.7),
HorizontalAlignment = ha,
VerticalAlignment = va,
Width = RESIZE_RECT_SIZE,
+1
View File
@@ -58,6 +58,7 @@ public class ConfigUpdater : IConfigUpdater
{
LeftPanelWidth = Constants.DEFAULT_LEFT_PANEL_WIDTH,
RightPanelWidth = Constants.DEFAULT_RIGHT_PANEL_WIDTH,
GenerateAnnotatedImage = false
},
DirectoriesConfig = new DirectoriesConfig
+1
View File
@@ -4,4 +4,5 @@ public class UIConfig
{
public double LeftPanelWidth { get; set; }
public double RightPanelWidth { get; set; }
public bool GenerateAnnotatedImage { get; set; }
}
@@ -30,6 +30,7 @@ public class AnnotationService : INotificationHandler<AnnotationsDeletedEvent>
private readonly IAuthProvider _authProvider;
private readonly QueueConfig _queueConfig;
private Consumer _consumer = null!;
private readonly UIConfig _uiConfig;
private static readonly Guid SaveTaskId = Guid.NewGuid();
public AnnotationService(
@@ -37,6 +38,7 @@ public class AnnotationService : INotificationHandler<AnnotationsDeletedEvent>
IDbFactory dbFactory,
FailsafeAnnotationsProducer producer,
IOptions<QueueConfig> queueConfig,
IOptions<UIConfig> uiConfig,
IGalleryService galleryService,
IMediator mediator,
IHardwareService hardwareService,
@@ -49,6 +51,7 @@ public class AnnotationService : INotificationHandler<AnnotationsDeletedEvent>
_hardwareService = hardwareService;
_authProvider = authProvider;
_queueConfig = queueConfig.Value;
_uiConfig = uiConfig.Value;
Task.Run(async () => await Init()).Wait();
}
@@ -184,7 +187,12 @@ public class AnnotationService : INotificationHandler<AnnotationsDeletedEvent>
}
await YoloLabel.WriteToFile(detections, annotation.LabelPath, token);
if (generateThumbnail)
{
await _galleryService.CreateThumbnail(annotation, token);
if (_uiConfig.GenerateAnnotatedImage)
await _galleryService.CreateAnnotatedImage(annotation, token);
}
if (!fromQueue) //Send to queue only if we're not getting from queue already
await _producer.SendToInnerQueue(annotation, token);
+19
View File
@@ -265,6 +265,24 @@ public class GalleryService(
logger.LogError(e, e.Message);
}
}
public async Task CreateAnnotatedImage(Annotation annotation, CancellationToken token)
{
var originalImage = Image.FromStream(new MemoryStream(await File.ReadAllBytesAsync(annotation.ImagePath, token)));
using var g = Graphics.FromImage(originalImage);
foreach (var detection in annotation.Detections)
{
var detClass = _annotationConfig.DetectionClassesDict[detection.ClassNumber];
var color = detClass.Color;
var brush = new SolidBrush(Color.FromArgb(color.A, color.R, color.G, color.B));
var det = new CanvasLabel(detection, new Size(originalImage.Width, originalImage.Height));
g.DrawRectangle(new Pen(brush, width: 3), (float)det.X, (float)det.Y, (float)det.Width, (float)det.Height);
var label = detection.Confidence >= 0.995 ? detClass.UIName : $"{detClass.UIName}: {detection.Confidence * 100:F0}%";
g.DrawString(label, new Font(FontFamily.GenericSerif, 14), brush, new PointF((float)(det.X + det.Width / 2.0), (float)det.Y));
}
originalImage.Save(Path.Combine(_dirConfig.ResultsDirectory, $"{annotation.Name}{Constants.RESULT_PREFIX}.jpg"), ImageFormat.Jpeg);
}
}
public interface IGalleryService
@@ -275,4 +293,5 @@ public interface IGalleryService
Task RefreshThumbnails();
Task ClearThumbnails(CancellationToken cancellationToken = default);
Task CreateAnnotatedImage(Annotation annotation, CancellationToken token);
}
-2
View File
@@ -4,8 +4,6 @@ from PyInstaller.utils.hooks import collect_all
datas = []
binaries = []
hiddenimports = ['constants', 'annotation', 'credentials', 'file_data', 'user', 'security', 'secure_model', 'api_client', 'hardware_service', 'remote_command', 'ai_config', 'inference_engine', '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')
datas += tmp_ret[0]; binaries += tmp_ret[1]; hiddenimports += tmp_ret[2]
tmp_ret = collect_all('requests')
+4 -4
View File
@@ -32,8 +32,8 @@
<ItemGroup>
<ProjectReference Include="..\Azaion.Common\Azaion.Common.csproj" />
<ProjectReference Include="..\Azaion.Annotator\Azaion.Annotator.csproj" />
<ProjectReference Include="..\Azaion.Dataset\Azaion.Dataset.csproj" />
<ProjectReference Include="..\dummy\Azaion.Annotator\Azaion.Annotator.csproj" />
<ProjectReference Include="..\dummy\Azaion.Dataset\Azaion.Dataset.csproj" />
</ItemGroup>
<ItemGroup>
@@ -61,8 +61,8 @@
<Target Name="PostBuild" AfterTargets="Build">
<MakeDir Directories="$(TargetDir)dummy" />
<Copy SourceFiles="$(TargetDir)Azaion.Annotator.dll" DestinationFolder="$(TargetDir)dummy" />
<Copy SourceFiles="$(TargetDir)Azaion.Dataset.dll" DestinationFolder="$(TargetDir)dummy" />
<Move SourceFiles="$(TargetDir)Azaion.Annotator.dll" DestinationFolder="$(TargetDir)dummy" />
<Move SourceFiles="$(TargetDir)Azaion.Dataset.dll" DestinationFolder="$(TargetDir)dummy" />
<Exec Command="upload.cmd $(ConfigurationName) stage" />
</Target>
+2 -2
View File
@@ -74,7 +74,7 @@
BorderBrush="DimGray"
BorderThickness="0,0,0,1"
HorizontalAlignment="Left"
Text="admin@azaion.com"
Text=""
/>
<TextBlock Text="Пароль"
Grid.Row="2"
@@ -89,7 +89,7 @@
Width="300"
BorderThickness="0,0,0,1"
HorizontalAlignment="Left"
Password="Az@1on1000Odm$n"/>
Password=""/>
</Grid>
<Button x:Name="LoginBtn"
Content="Вхід"
+2 -1
View File
@@ -22,6 +22,7 @@
},
"UIConfig": {
"LeftPanelWidth": 220.0,
"RightPanelWidth": 230.0
"RightPanelWidth": 230.0,
"GenerateAnnotatedImage": true
}
}
+28
View File
@@ -0,0 +1,28 @@
setlocal enabledelayedexpansion
set API_URL=https://api.azaion.com
set SOURCE_FILE=%1
set DESTINATION=%2
set "SOURCE_FILE=%SOURCE_FILE:\=/%"
set EMAIL=uploader@azaion.com
set PASSWORD=Az@1on_10Upl0@der
for /f "tokens=*" %%i in ('curl -s -X POST -H "Content-Type: application/json" ^
-d "{\"email\":\"%EMAIL%\",\"password\":\"%PASSWORD%\"}" %API_URL%/login') do set RESPONSE=%%i
for /f "tokens=2 delims=:" %%a in ('echo %RESPONSE% ^| findstr /i "token"') do (
set "TOKEN=%%a"
set "TOKEN=!TOKEN:~1,-1!"
set "TOKEN=!TOKEN:~0,-2!"
)
set UPLOAD_URL=%API_URL%/resources/%DESTINATION%
echo Uploading %SOURCE_FILE% to %UPLOAD_URL%...
curl --location %UPLOAD_URL% ^
-H "Authorization: Bearer %TOKEN%" ^
-H "Content-Type: multipart/form-data" ^
--form "data=@%SOURCE_FILE%"
echo Upload complete!
+3 -38
View File
@@ -1,45 +1,10 @@
setlocal enabledelayedexpansion
set CONFIG=%1
@echo off
set API_URL=https://api.azaion.com
set CONFIG=%1
set RESOURCES_FOLDER=%2
set EMAIL=uploader@azaion.com
set PASSWORD=Az@1on_10Upl0@der
echo %cd%
set FILE1_TO_UPLOAD=%cd%\..\Azaion.Annotator\bin\%CONFIG%\net8.0-windows\Azaion.Annotator.dll
set "FILE1_TO_UPLOAD=%FILE1_TO_UPLOAD:\=/%"
call upload-file %FILE1_TO_UPLOAD% %RESOURCES_FOLDER%
set FILE2_TO_UPLOAD=%cd%\..\Azaion.Dataset\bin\%CONFIG%\net8.0-windows\Azaion.Dataset.dll
set "FILE2_TO_UPLOAD=%FILE2_TO_UPLOAD:\=/%"
echo Logging in and retrieving token...
for /f "tokens=*" %%i in ('curl -s -X POST -H "Content-Type: application/json" ^
-d "{\"email\":\"%EMAIL%\",\"password\":\"%PASSWORD%\"}" %API_URL%/login') do set RESPONSE=%%i
for /f "tokens=2 delims=:" %%a in ('echo %RESPONSE% ^| findstr /i "token"') do (
set "TOKEN=%%a"
set "TOKEN=!TOKEN:~1,-1!"
set "TOKEN=!TOKEN:~0,-2!"
)
:: Step 2: Upload the DLL file
set UPLOAD_URL=%API_URL%/resources/%RESOURCES_FOLDER%
echo Uploading file %FILE1_TO_UPLOAD% to %UPLOAD_URL%...
curl --location %UPLOAD_URL% ^
-H "Authorization: Bearer %TOKEN%" ^
-H "Content-Type: multipart/form-data" ^
--form "data=@%FILE1_TO_UPLOAD%"
echo Uploading file %FILE2_TO_UPLOAD% to %UPLOAD_URL%...
curl --location %UPLOAD_URL% ^
-H "Authorization: Bearer %TOKEN%" ^
-H "Content-Type: multipart/form-data" ^
--form "data=@%FILE2_TO_UPLOAD%"
echo Done!
call upload-file %FILE2_TO_UPLOAD% %RESOURCES_FOLDER%
+2 -2
View File
@@ -1,12 +1,12 @@
[Setup]
AppId={{CCFEC8E2-0FCC-4B03-8EEA-00AF20D265E5}}
AppName=Azaion Suite
AppVersion=1.3.2
AppVersion=1.4.2
AppPublisher=Azaion Ukraine
DefaultDirName={localappdata}\Azaion\Azaion Suite
DefaultGroupName=Azaion Suite
OutputDir=..\
OutputBaseFilename=AzaionSuiteInstaller
OutputBaseFilename=AzaionSuite1.4.2
SetupIconFile=..\dist\logo.ico
UninstallDisplayName=Azaion Suite
UninstallDisplayIcon={app}\Azaion.Suite.exe
+13 -7
View File
@@ -5,9 +5,11 @@ echo Build .net app
dotnet build -c Release
cd Azaion.Suite
call upload.cmd Release
call upload Release
echo %cd%
call upload-file %cd%\config.secured.json
call upload-file %cd%\config.system.json
echo Publish .net app
dotnet publish -r win-x64 -p:SatelliteResourceLanguages="en" -p:DebugSymbols=false -p:ForPublish=true --self-contained true
cd ..
rmdir dist /s /q
@@ -21,6 +23,8 @@ move dist\Azaion.Dataset.dll dist\dummy\
echo Build Cython app
cd Azaion.Inference
rmdir dist /s /q
.\venv\Scripts\pyinstaller --name=azaion-inference ^
--collect-all jwt ^
--collect-all requests ^
@@ -48,7 +52,13 @@ cd Azaion.Inference
--hidden-import inference ^
--hidden-import remote_command_handler ^
start.py
move dist\start.exe ..\dist\azaion-inference.exe
xcopy /E dist\azaion-inference ..\dist\
copy venv\Lib\site-packages\tensorrt_libs\nvinfer_10.dll ..\dist
copy venv\Lib\site-packages\tensorrt_libs\nvinfer_plugin_10.dll ..\dist
copy venv\Lib\site-packages\tensorrt_libs\nvonnxparser_10.dll ..\dist
copy config.production.yaml ..\dist\config.yaml
cd..
@@ -70,9 +80,5 @@ copy %cudnn-folder%\* dist\*
del dist\cudnn_adv64_9.dll
echo building installer...
iscc build\installer.iss
cd build\
echo uploading installer...
call cdn_manager.exe upload suite AzaionSuiteInstaller.exe ..\AzaionSuiteInstaller.exe