mirror of
https://github.com/azaion/annotations.git
synced 2026-04-22 22:56:29 +00:00
add generating result image to Results directory
This commit is contained in:
@@ -331,14 +331,11 @@ public partial class Annotator
|
|||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
_logger.LogInformation($"remove annotation {existingResult.TimeStr} {existingResult.ClassName}!");
|
|
||||||
_formState.AnnotationResults.Remove(existingResult);
|
_formState.AnnotationResults.Remove(existingResult);
|
||||||
_logger.LogInformation($"removed {existingResult.TimeStr} {existingResult.ClassName} sucessfully!");
|
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
_logger.LogError(e, e.Message);
|
_logger.LogError(e, e.Message);
|
||||||
//Console.WriteLine(e);
|
|
||||||
throw;
|
throw;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -63,6 +63,7 @@ public class Constants
|
|||||||
public const int DEFAULT_THUMBNAIL_BORDER = 10;
|
public const int DEFAULT_THUMBNAIL_BORDER = 10;
|
||||||
|
|
||||||
public const string THUMBNAIL_PREFIX = "_thumb";
|
public const string THUMBNAIL_PREFIX = "_thumb";
|
||||||
|
public const string RESULT_PREFIX = "_result";
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
|
|||||||
@@ -121,7 +121,7 @@ public class DetectionControl : Border
|
|||||||
var rect = new Rectangle() // small rectangles at the corners and sides
|
var rect = new Rectangle() // small rectangles at the corners and sides
|
||||||
{
|
{
|
||||||
ClipToBounds = false,
|
ClipToBounds = false,
|
||||||
Margin = new Thickness(-RESIZE_RECT_SIZE),
|
Margin = new Thickness(-RESIZE_RECT_SIZE * 0.7),
|
||||||
HorizontalAlignment = ha,
|
HorizontalAlignment = ha,
|
||||||
VerticalAlignment = va,
|
VerticalAlignment = va,
|
||||||
Width = RESIZE_RECT_SIZE,
|
Width = RESIZE_RECT_SIZE,
|
||||||
|
|||||||
@@ -58,6 +58,7 @@ public class ConfigUpdater : IConfigUpdater
|
|||||||
{
|
{
|
||||||
LeftPanelWidth = Constants.DEFAULT_LEFT_PANEL_WIDTH,
|
LeftPanelWidth = Constants.DEFAULT_LEFT_PANEL_WIDTH,
|
||||||
RightPanelWidth = Constants.DEFAULT_RIGHT_PANEL_WIDTH,
|
RightPanelWidth = Constants.DEFAULT_RIGHT_PANEL_WIDTH,
|
||||||
|
GenerateAnnotatedImage = false
|
||||||
},
|
},
|
||||||
|
|
||||||
DirectoriesConfig = new DirectoriesConfig
|
DirectoriesConfig = new DirectoriesConfig
|
||||||
|
|||||||
@@ -4,4 +4,5 @@ public class UIConfig
|
|||||||
{
|
{
|
||||||
public double LeftPanelWidth { get; set; }
|
public double LeftPanelWidth { get; set; }
|
||||||
public double RightPanelWidth { 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 IAuthProvider _authProvider;
|
||||||
private readonly QueueConfig _queueConfig;
|
private readonly QueueConfig _queueConfig;
|
||||||
private Consumer _consumer = null!;
|
private Consumer _consumer = null!;
|
||||||
|
private readonly UIConfig _uiConfig;
|
||||||
private static readonly Guid SaveTaskId = Guid.NewGuid();
|
private static readonly Guid SaveTaskId = Guid.NewGuid();
|
||||||
|
|
||||||
public AnnotationService(
|
public AnnotationService(
|
||||||
@@ -37,6 +38,7 @@ public class AnnotationService : INotificationHandler<AnnotationsDeletedEvent>
|
|||||||
IDbFactory dbFactory,
|
IDbFactory dbFactory,
|
||||||
FailsafeAnnotationsProducer producer,
|
FailsafeAnnotationsProducer producer,
|
||||||
IOptions<QueueConfig> queueConfig,
|
IOptions<QueueConfig> queueConfig,
|
||||||
|
IOptions<UIConfig> uiConfig,
|
||||||
IGalleryService galleryService,
|
IGalleryService galleryService,
|
||||||
IMediator mediator,
|
IMediator mediator,
|
||||||
IHardwareService hardwareService,
|
IHardwareService hardwareService,
|
||||||
@@ -49,6 +51,7 @@ public class AnnotationService : INotificationHandler<AnnotationsDeletedEvent>
|
|||||||
_hardwareService = hardwareService;
|
_hardwareService = hardwareService;
|
||||||
_authProvider = authProvider;
|
_authProvider = authProvider;
|
||||||
_queueConfig = queueConfig.Value;
|
_queueConfig = queueConfig.Value;
|
||||||
|
_uiConfig = uiConfig.Value;
|
||||||
|
|
||||||
Task.Run(async () => await Init()).Wait();
|
Task.Run(async () => await Init()).Wait();
|
||||||
}
|
}
|
||||||
@@ -184,7 +187,12 @@ public class AnnotationService : INotificationHandler<AnnotationsDeletedEvent>
|
|||||||
}
|
}
|
||||||
await YoloLabel.WriteToFile(detections, annotation.LabelPath, token);
|
await YoloLabel.WriteToFile(detections, annotation.LabelPath, token);
|
||||||
if (generateThumbnail)
|
if (generateThumbnail)
|
||||||
|
{
|
||||||
await _galleryService.CreateThumbnail(annotation, token);
|
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
|
if (!fromQueue) //Send to queue only if we're not getting from queue already
|
||||||
await _producer.SendToInnerQueue(annotation, token);
|
await _producer.SendToInnerQueue(annotation, token);
|
||||||
|
|||||||
@@ -265,6 +265,24 @@ public class GalleryService(
|
|||||||
logger.LogError(e, e.Message);
|
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
|
public interface IGalleryService
|
||||||
@@ -275,4 +293,5 @@ public interface IGalleryService
|
|||||||
Task RefreshThumbnails();
|
Task RefreshThumbnails();
|
||||||
Task ClearThumbnails(CancellationToken cancellationToken = default);
|
Task ClearThumbnails(CancellationToken cancellationToken = default);
|
||||||
|
|
||||||
|
Task CreateAnnotatedImage(Annotation annotation, CancellationToken token);
|
||||||
}
|
}
|
||||||
@@ -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_engine', 'inference', 'remote_command_handler']
|
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')
|
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')
|
||||||
|
|||||||
@@ -32,8 +32,8 @@
|
|||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ProjectReference Include="..\Azaion.Common\Azaion.Common.csproj" />
|
<ProjectReference Include="..\Azaion.Common\Azaion.Common.csproj" />
|
||||||
<ProjectReference Include="..\Azaion.Annotator\Azaion.Annotator.csproj" />
|
<ProjectReference Include="..\dummy\Azaion.Annotator\Azaion.Annotator.csproj" />
|
||||||
<ProjectReference Include="..\Azaion.Dataset\Azaion.Dataset.csproj" />
|
<ProjectReference Include="..\dummy\Azaion.Dataset\Azaion.Dataset.csproj" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
@@ -61,8 +61,8 @@
|
|||||||
|
|
||||||
<Target Name="PostBuild" AfterTargets="Build">
|
<Target Name="PostBuild" AfterTargets="Build">
|
||||||
<MakeDir Directories="$(TargetDir)dummy" />
|
<MakeDir Directories="$(TargetDir)dummy" />
|
||||||
<Copy SourceFiles="$(TargetDir)Azaion.Annotator.dll" DestinationFolder="$(TargetDir)dummy" />
|
<Move SourceFiles="$(TargetDir)Azaion.Annotator.dll" DestinationFolder="$(TargetDir)dummy" />
|
||||||
<Copy SourceFiles="$(TargetDir)Azaion.Dataset.dll" DestinationFolder="$(TargetDir)dummy" />
|
<Move SourceFiles="$(TargetDir)Azaion.Dataset.dll" DestinationFolder="$(TargetDir)dummy" />
|
||||||
<Exec Command="upload.cmd $(ConfigurationName) stage" />
|
<Exec Command="upload.cmd $(ConfigurationName) stage" />
|
||||||
</Target>
|
</Target>
|
||||||
|
|
||||||
|
|||||||
@@ -74,7 +74,7 @@
|
|||||||
BorderBrush="DimGray"
|
BorderBrush="DimGray"
|
||||||
BorderThickness="0,0,0,1"
|
BorderThickness="0,0,0,1"
|
||||||
HorizontalAlignment="Left"
|
HorizontalAlignment="Left"
|
||||||
Text="admin@azaion.com"
|
Text=""
|
||||||
/>
|
/>
|
||||||
<TextBlock Text="Пароль"
|
<TextBlock Text="Пароль"
|
||||||
Grid.Row="2"
|
Grid.Row="2"
|
||||||
@@ -89,7 +89,7 @@
|
|||||||
Width="300"
|
Width="300"
|
||||||
BorderThickness="0,0,0,1"
|
BorderThickness="0,0,0,1"
|
||||||
HorizontalAlignment="Left"
|
HorizontalAlignment="Left"
|
||||||
Password="Az@1on1000Odm$n"/>
|
Password=""/>
|
||||||
</Grid>
|
</Grid>
|
||||||
<Button x:Name="LoginBtn"
|
<Button x:Name="LoginBtn"
|
||||||
Content="Вхід"
|
Content="Вхід"
|
||||||
|
|||||||
@@ -22,6 +22,7 @@
|
|||||||
},
|
},
|
||||||
"UIConfig": {
|
"UIConfig": {
|
||||||
"LeftPanelWidth": 220.0,
|
"LeftPanelWidth": 220.0,
|
||||||
"RightPanelWidth": 230.0
|
"RightPanelWidth": 230.0,
|
||||||
|
"GenerateAnnotatedImage": true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -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
@@ -1,45 +1,10 @@
|
|||||||
setlocal enabledelayedexpansion
|
|
||||||
set CONFIG=%1
|
|
||||||
@echo off
|
@echo off
|
||||||
|
|
||||||
set API_URL=https://api.azaion.com
|
set CONFIG=%1
|
||||||
set RESOURCES_FOLDER=%2
|
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=%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=%cd%\..\Azaion.Dataset\bin\%CONFIG%\net8.0-windows\Azaion.Dataset.dll
|
||||||
set "FILE2_TO_UPLOAD=%FILE2_TO_UPLOAD:\=/%"
|
call upload-file %FILE2_TO_UPLOAD% %RESOURCES_FOLDER%
|
||||||
|
|
||||||
|
|
||||||
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!
|
|
||||||
|
|||||||
+2
-2
@@ -1,12 +1,12 @@
|
|||||||
[Setup]
|
[Setup]
|
||||||
AppId={{CCFEC8E2-0FCC-4B03-8EEA-00AF20D265E5}}
|
AppId={{CCFEC8E2-0FCC-4B03-8EEA-00AF20D265E5}}
|
||||||
AppName=Azaion Suite
|
AppName=Azaion Suite
|
||||||
AppVersion=1.3.2
|
AppVersion=1.4.2
|
||||||
AppPublisher=Azaion Ukraine
|
AppPublisher=Azaion Ukraine
|
||||||
DefaultDirName={localappdata}\Azaion\Azaion Suite
|
DefaultDirName={localappdata}\Azaion\Azaion Suite
|
||||||
DefaultGroupName=Azaion Suite
|
DefaultGroupName=Azaion Suite
|
||||||
OutputDir=..\
|
OutputDir=..\
|
||||||
OutputBaseFilename=AzaionSuiteInstaller
|
OutputBaseFilename=AzaionSuite1.4.2
|
||||||
SetupIconFile=..\dist\logo.ico
|
SetupIconFile=..\dist\logo.ico
|
||||||
UninstallDisplayName=Azaion Suite
|
UninstallDisplayName=Azaion Suite
|
||||||
UninstallDisplayIcon={app}\Azaion.Suite.exe
|
UninstallDisplayIcon={app}\Azaion.Suite.exe
|
||||||
|
|||||||
+13
-7
@@ -5,9 +5,11 @@ echo Build .net app
|
|||||||
dotnet build -c Release
|
dotnet build -c Release
|
||||||
|
|
||||||
cd Azaion.Suite
|
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
|
dotnet publish -r win-x64 -p:SatelliteResourceLanguages="en" -p:DebugSymbols=false -p:ForPublish=true --self-contained true
|
||||||
cd ..
|
cd ..
|
||||||
rmdir dist /s /q
|
rmdir dist /s /q
|
||||||
@@ -21,6 +23,8 @@ move dist\Azaion.Dataset.dll dist\dummy\
|
|||||||
|
|
||||||
echo Build Cython app
|
echo Build Cython app
|
||||||
cd Azaion.Inference
|
cd Azaion.Inference
|
||||||
|
rmdir dist /s /q
|
||||||
|
|
||||||
.\venv\Scripts\pyinstaller --name=azaion-inference ^
|
.\venv\Scripts\pyinstaller --name=azaion-inference ^
|
||||||
--collect-all jwt ^
|
--collect-all jwt ^
|
||||||
--collect-all requests ^
|
--collect-all requests ^
|
||||||
@@ -48,7 +52,13 @@ cd Azaion.Inference
|
|||||||
--hidden-import inference ^
|
--hidden-import inference ^
|
||||||
--hidden-import remote_command_handler ^
|
--hidden-import remote_command_handler ^
|
||||||
start.py
|
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
|
copy config.production.yaml ..\dist\config.yaml
|
||||||
cd..
|
cd..
|
||||||
|
|
||||||
@@ -70,9 +80,5 @@ copy %cudnn-folder%\* dist\*
|
|||||||
del dist\cudnn_adv64_9.dll
|
del dist\cudnn_adv64_9.dll
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
echo building installer...
|
echo building installer...
|
||||||
iscc build\installer.iss
|
iscc build\installer.iss
|
||||||
cd build\
|
|
||||||
echo uploading installer...
|
|
||||||
call cdn_manager.exe upload suite AzaionSuiteInstaller.exe ..\AzaionSuiteInstaller.exe
|
|
||||||
Reference in New Issue
Block a user