mirror of
https://github.com/azaion/annotations.git
synced 2026-04-22 09:36:30 +00:00
update validation logic
This commit is contained in:
@@ -35,4 +35,6 @@ public class AnnotationThumbnail(Annotation annotation) : INotifyPropertyChanged
|
|||||||
{
|
{
|
||||||
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
|
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void UpdateUI() => OnPropertyChanged(nameof(IsSeed));
|
||||||
}
|
}
|
||||||
@@ -31,6 +31,9 @@ public class Annotation
|
|||||||
[IgnoreMember]public SourceEnum Source { get; set; }
|
[IgnoreMember]public SourceEnum Source { get; set; }
|
||||||
[IgnoreMember]public AnnotationStatus AnnotationStatus { get; set; }
|
[IgnoreMember]public AnnotationStatus AnnotationStatus { get; set; }
|
||||||
|
|
||||||
|
[IgnoreMember]public DateTime ValidateDate { get; set; }
|
||||||
|
[IgnoreMember]public string ValidateEmail { get; set; } = null!;
|
||||||
|
|
||||||
[Key("d")] public IEnumerable<Detection> Detections { get; set; } = null!;
|
[Key("d")] public IEnumerable<Detection> Detections { get; set; } = null!;
|
||||||
[Key("t")] public long Milliseconds { get; set; }
|
[Key("t")] public long Milliseconds { get; set; }
|
||||||
|
|
||||||
|
|||||||
@@ -94,7 +94,6 @@ public class AnnotationService : INotificationHandler<AnnotationsDeletedEvent>
|
|||||||
new MemoryStream(msg.Image),
|
new MemoryStream(msg.Image),
|
||||||
msg.CreatedRole,
|
msg.CreatedRole,
|
||||||
msg.CreatedEmail,
|
msg.CreatedEmail,
|
||||||
generateThumbnail: true,
|
|
||||||
fromQueue: true,
|
fromQueue: true,
|
||||||
token: cancellationToken);
|
token: cancellationToken);
|
||||||
}
|
}
|
||||||
@@ -106,17 +105,12 @@ public class AnnotationService : INotificationHandler<AnnotationsDeletedEvent>
|
|||||||
{
|
{
|
||||||
a.Time = TimeSpan.FromMilliseconds(a.Milliseconds);
|
a.Time = TimeSpan.FromMilliseconds(a.Milliseconds);
|
||||||
return await SaveAnnotationInner(DateTime.Now, a.OriginalMediaName, a.Time, a.Detections.ToList(),
|
return await SaveAnnotationInner(DateTime.Now, a.OriginalMediaName, a.Time, a.Detections.ToList(),
|
||||||
SourceEnum.AI, new MemoryStream(a.Image), _api.CurrentUser.Role, _api.CurrentUser.Email, generateThumbnail: true, token: ct);
|
SourceEnum.AI, new MemoryStream(a.Image), _api.CurrentUser.Role, _api.CurrentUser.Email, token: ct);
|
||||||
}
|
}
|
||||||
|
|
||||||
//Manual
|
//Manual
|
||||||
public async Task<Annotation> SaveAnnotation(string originalMediaName, TimeSpan time, List<Detection> detections, Stream? stream = null, CancellationToken token = default) =>
|
public async Task<Annotation> SaveAnnotation(string originalMediaName, TimeSpan time, List<Detection> detections, Stream? stream = null, CancellationToken token = default) =>
|
||||||
await SaveAnnotationInner(DateTime.UtcNow, originalMediaName, time, detections, SourceEnum.Manual, stream,
|
await SaveAnnotationInner(DateTime.UtcNow, originalMediaName, time, detections, SourceEnum.Manual, stream,
|
||||||
_api.CurrentUser.Role, _api.CurrentUser.Email, generateThumbnail: true, token: token);
|
|
||||||
|
|
||||||
//Manual Validate existing
|
|
||||||
public async Task ValidateAnnotation(Annotation annotation, CancellationToken token = default) =>
|
|
||||||
await SaveAnnotationInner(DateTime.UtcNow, annotation.OriginalMediaName, annotation.Time, annotation.Detections.ToList(), SourceEnum.Manual, null,
|
|
||||||
_api.CurrentUser.Role, _api.CurrentUser.Email, token: token);
|
_api.CurrentUser.Role, _api.CurrentUser.Email, token: token);
|
||||||
|
|
||||||
// Manual save from Validators -> Validated -> stream: azaion-annotations-confirm
|
// Manual save from Validators -> Validated -> stream: azaion-annotations-confirm
|
||||||
@@ -124,11 +118,9 @@ public class AnnotationService : INotificationHandler<AnnotationsDeletedEvent>
|
|||||||
private async Task<Annotation> SaveAnnotationInner(DateTime createdDate, string originalMediaName, TimeSpan time, List<Detection> detections, SourceEnum source, Stream? stream,
|
private async Task<Annotation> SaveAnnotationInner(DateTime createdDate, string originalMediaName, TimeSpan time, List<Detection> detections, SourceEnum source, Stream? stream,
|
||||||
RoleEnum userRole,
|
RoleEnum userRole,
|
||||||
string createdEmail,
|
string createdEmail,
|
||||||
bool generateThumbnail = false,
|
|
||||||
bool fromQueue = false,
|
bool fromQueue = false,
|
||||||
CancellationToken token = default)
|
CancellationToken token = default)
|
||||||
{
|
{
|
||||||
|
|
||||||
AnnotationStatus status;
|
AnnotationStatus status;
|
||||||
var fName = originalMediaName.ToTimeName(time);
|
var fName = originalMediaName.ToTimeName(time);
|
||||||
var annotation = await _dbFactory.Run(async db =>
|
var annotation = await _dbFactory.Run(async db =>
|
||||||
@@ -179,13 +171,10 @@ public class AnnotationService : INotificationHandler<AnnotationsDeletedEvent>
|
|||||||
img.Save(annotation.ImagePath, ImageFormat.Jpeg); //todo: check png images coming from queue
|
img.Save(annotation.ImagePath, ImageFormat.Jpeg); //todo: check png images coming from queue
|
||||||
}
|
}
|
||||||
await YoloLabel.WriteToFile(detections, annotation.LabelPath, token);
|
await YoloLabel.WriteToFile(detections, annotation.LabelPath, token);
|
||||||
if (generateThumbnail)
|
|
||||||
{
|
|
||||||
await _galleryService.CreateThumbnail(annotation, token);
|
|
||||||
if (_uiConfig.GenerateAnnotatedImage)
|
|
||||||
await _galleryService.CreateAnnotatedImage(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);
|
||||||
@@ -195,10 +184,32 @@ public class AnnotationService : INotificationHandler<AnnotationsDeletedEvent>
|
|||||||
{
|
{
|
||||||
_dbFactory.SaveToDisk();
|
_dbFactory.SaveToDisk();
|
||||||
await Task.CompletedTask;
|
await Task.CompletedTask;
|
||||||
}, SaveTaskId, TimeSpan.FromSeconds(5));
|
}, SaveTaskId, TimeSpan.FromSeconds(5), true);
|
||||||
return annotation;
|
return annotation;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public async Task ValidateAnnotations(List<Annotation> annotations, CancellationToken token = default)
|
||||||
|
{
|
||||||
|
if (!_api.CurrentUser.Role.IsValidator())
|
||||||
|
return;
|
||||||
|
|
||||||
|
var annNames = annotations.Select(x => x.Name).ToHashSet();
|
||||||
|
await _dbFactory.Run(async db =>
|
||||||
|
{
|
||||||
|
await db.Annotations
|
||||||
|
.Where(x => annNames.Contains(x.Name))
|
||||||
|
.Set(x => x.AnnotationStatus, AnnotationStatus.Validated)
|
||||||
|
.Set(x => x.ValidateDate, DateTime.UtcNow)
|
||||||
|
.Set(x => x.ValidateEmail, _api.CurrentUser.Email)
|
||||||
|
.UpdateAsync(token: token);
|
||||||
|
});
|
||||||
|
ThrottleExt.Throttle(async () =>
|
||||||
|
{
|
||||||
|
_dbFactory.SaveToDisk();
|
||||||
|
await Task.CompletedTask;
|
||||||
|
}, SaveTaskId, TimeSpan.FromSeconds(5), true);
|
||||||
|
}
|
||||||
|
|
||||||
public async Task Handle(AnnotationsDeletedEvent notification, CancellationToken cancellationToken)
|
public async Task Handle(AnnotationsDeletedEvent notification, CancellationToken cancellationToken)
|
||||||
{
|
{
|
||||||
await _dbFactory.DeleteAnnotations(notification.Annotations, cancellationToken);
|
await _dbFactory.DeleteAnnotations(notification.Annotations, cancellationToken);
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
using System.Windows;
|
using System.Windows;
|
||||||
using System.Windows.Input;
|
using System.Windows.Input;
|
||||||
using System.Windows.Threading;
|
using System.Windows.Threading;
|
||||||
|
using Azaion.Common.Database;
|
||||||
using Azaion.Common.DTO;
|
using Azaion.Common.DTO;
|
||||||
using Azaion.Common.DTO.Queue;
|
using Azaion.Common.DTO.Queue;
|
||||||
using Azaion.Common.Events;
|
using Azaion.Common.Events;
|
||||||
@@ -96,8 +97,14 @@ public class DatasetExplorerEventHandler(
|
|||||||
var annotations = datasetExplorer.ThumbnailsView.SelectedItems.Cast<AnnotationThumbnail>()
|
var annotations = datasetExplorer.ThumbnailsView.SelectedItems.Cast<AnnotationThumbnail>()
|
||||||
.Select(x => x.Annotation)
|
.Select(x => x.Annotation)
|
||||||
.ToList();
|
.ToList();
|
||||||
foreach (var annotation in annotations)
|
await annotationService.ValidateAnnotations(annotations, cancellationToken);
|
||||||
await annotationService.ValidateAnnotation(annotation, cancellationToken);
|
foreach (var ann in datasetExplorer.SelectedAnnotations.Where(x => annotations.Contains(x.Annotation)))
|
||||||
|
{
|
||||||
|
ann.Annotation.AnnotationStatus = AnnotationStatus.Validated;
|
||||||
|
if (datasetExplorer.SelectedAnnotationDict.TryGetValue(ann.Annotation.Name, out var value))
|
||||||
|
value.Annotation.AnnotationStatus = AnnotationStatus.Validated;
|
||||||
|
ann.UpdateUI();
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,6 +24,7 @@
|
|||||||
},
|
},
|
||||||
"UIConfig": {
|
"UIConfig": {
|
||||||
"LeftPanelWidth": 170.0,
|
"LeftPanelWidth": 170.0,
|
||||||
"RightPanelWidth": 120.0
|
"RightPanelWidth": 120.0,
|
||||||
|
"GenerateAnnotatedImage": true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user