mirror of
https://github.com/azaion/annotations.git
synced 2026-04-22 19:56:31 +00:00
splitting python complete
This commit is contained in:
@@ -94,6 +94,7 @@ public class AnnotationService : IAnnotationService
|
||||
await SaveAnnotationInner(
|
||||
msg.CreatedDate,
|
||||
msg.OriginalMediaName,
|
||||
msg.Name,
|
||||
msg.Time,
|
||||
JsonConvert.DeserializeObject<List<Detection>>(msg.Detections) ?? [],
|
||||
msg.Source,
|
||||
@@ -136,16 +137,16 @@ public class AnnotationService : IAnnotationService
|
||||
public async Task<Annotation> SaveAnnotation(AnnotationImage a, CancellationToken ct = default)
|
||||
{
|
||||
a.Time = TimeSpan.FromMilliseconds(a.Milliseconds);
|
||||
return await SaveAnnotationInner(DateTime.UtcNow, a.OriginalMediaName, a.Time, a.Detections.ToList(),
|
||||
return await SaveAnnotationInner(DateTime.UtcNow, a.OriginalMediaName, a.Name, a.Time, a.Detections.ToList(),
|
||||
SourceEnum.AI, new MemoryStream(a.Image), _api.CurrentUser.Role, _api.CurrentUser.Email, token: ct);
|
||||
}
|
||||
|
||||
//Manual
|
||||
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,
|
||||
public async Task<Annotation> SaveAnnotation(string originalMediaName, string annotationName, TimeSpan time, List<Detection> detections, Stream? stream = null, CancellationToken token = default) =>
|
||||
await SaveAnnotationInner(DateTime.UtcNow, originalMediaName, annotationName, time, detections, SourceEnum.Manual, stream,
|
||||
_api.CurrentUser.Role, _api.CurrentUser.Email, token: token);
|
||||
|
||||
private async Task<Annotation> SaveAnnotationInner(DateTime createdDate, string originalMediaName, TimeSpan time,
|
||||
private async Task<Annotation> SaveAnnotationInner(DateTime createdDate, string originalMediaName, string annotationName, TimeSpan time,
|
||||
List<Detection> detections, SourceEnum source, Stream? stream,
|
||||
RoleEnum userRole,
|
||||
string createdEmail,
|
||||
@@ -153,21 +154,20 @@ public class AnnotationService : IAnnotationService
|
||||
CancellationToken token = default)
|
||||
{
|
||||
var status = AnnotationStatus.Created;
|
||||
var fName = originalMediaName.ToTimeName(time);
|
||||
var annotation = await _dbFactory.RunWrite(async db =>
|
||||
{
|
||||
var ann = await db.Annotations
|
||||
.LoadWith(x => x.Detections)
|
||||
.FirstOrDefaultAsync(x => x.Name == fName, token: token);
|
||||
.FirstOrDefaultAsync(x => x.Name == annotationName, token: token);
|
||||
|
||||
await db.Detections.DeleteAsync(x => x.AnnotationName == fName, token: token);
|
||||
await db.Detections.DeleteAsync(x => x.AnnotationName == annotationName, token: token);
|
||||
|
||||
if (ann != null) //Annotation is already exists
|
||||
{
|
||||
status = AnnotationStatus.Edited;
|
||||
|
||||
var annotationUpdatable = db.Annotations
|
||||
.Where(x => x.Name == fName)
|
||||
.Where(x => x.Name == annotationName)
|
||||
.Set(x => x.Source, source);
|
||||
|
||||
if (userRole.IsValidator() && source == SourceEnum.Manual)
|
||||
@@ -188,7 +188,7 @@ public class AnnotationService : IAnnotationService
|
||||
ann = new Annotation
|
||||
{
|
||||
CreatedDate = createdDate,
|
||||
Name = fName,
|
||||
Name = annotationName,
|
||||
OriginalMediaName = originalMediaName,
|
||||
Time = time,
|
||||
ImageExtension = Constants.JPG_EXT,
|
||||
@@ -264,6 +264,6 @@ public class AnnotationService : IAnnotationService
|
||||
public interface IAnnotationService
|
||||
{
|
||||
Task<Annotation> SaveAnnotation(AnnotationImage a, CancellationToken ct = default);
|
||||
Task<Annotation> SaveAnnotation(string originalMediaName, TimeSpan time, List<Detection> detections, Stream? stream = null, CancellationToken token = default);
|
||||
Task<Annotation> SaveAnnotation(string originalMediaName, string annotationName, TimeSpan time, List<Detection> detections, Stream? stream = null, CancellationToken token = default);
|
||||
Task ValidateAnnotations(List<string> annotationNames, bool fromQueue = false, CancellationToken token = default);
|
||||
}
|
||||
@@ -237,11 +237,11 @@ public class GalleryService(
|
||||
.ToList();
|
||||
if (annotation.Detections.Any())
|
||||
{
|
||||
var labelsMinX = labels.Min(x => x.X);
|
||||
var labelsMaxX = labels.Max(x => x.X + x.Width);
|
||||
var labelsMinX = labels.Min(x => x.Left);
|
||||
var labelsMaxX = labels.Max(x => x.Left + x.Width);
|
||||
|
||||
var labelsMinY = labels.Min(x => x.Y);
|
||||
var labelsMaxY = labels.Max(x => x.Y + x.Height);
|
||||
var labelsMinY = labels.Min(x => x.Top);
|
||||
var labelsMaxY = labels.Max(x => x.Top + x.Height);
|
||||
|
||||
var labelsHeight = labelsMaxY - labelsMinY + 2 * border;
|
||||
var labelsWidth = labelsMaxX - labelsMinX + 2 * border;
|
||||
@@ -270,7 +270,7 @@ public class GalleryService(
|
||||
var color = _annotationConfig.DetectionClassesDict[label.ClassNumber].Color;
|
||||
var brush = new SolidBrush(Color.FromArgb(color.A, color.R, color.G, color.B));
|
||||
|
||||
g.DrawRectangle(new Pen(brush, width: 3), (float)((label.X - frameX) / scale), (float)((label.Y - frameY) / scale), (float)(label.Width / scale), (float)(label.Height / scale));
|
||||
g.DrawRectangle(new Pen(brush, width: 3), (float)((label.Left - frameX) / scale), (float)((label.Top - frameY) / scale), (float)(label.Width / scale), (float)(label.Height / scale));
|
||||
}
|
||||
|
||||
bitmap.Save(annotation.ThumbPath, ImageFormat.Jpeg);
|
||||
@@ -291,10 +291,10 @@ public class GalleryService(
|
||||
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);
|
||||
g.DrawRectangle(new Pen(brush, width: 3), (float)det.Left, (float)det.Top, (float)det.Width, (float)det.Height);
|
||||
|
||||
var label = detection.Confidence >= 0.995 ? detClass.UIName : $"{detClass.UIName}: {detection.Confidence * 100:F0}%";
|
||||
g.DrawTextBox(label, new PointF((float)(det.X + det.Width / 2.0), (float)(det.Y - 24)), brush, Brushes.Black);
|
||||
g.DrawTextBox(label, new PointF((float)(det.Left + det.Width / 2.0), (float)(det.Top - 24)), brush, Brushes.Black);
|
||||
}
|
||||
|
||||
var imagePath = Path.Combine(_dirConfig.ResultsDirectory, $"{annotation.Name}{Constants.RESULT_PREFIX}.jpg");
|
||||
|
||||
@@ -49,7 +49,7 @@ public class InferenceClient : IInferenceClient
|
||||
Arguments = $"-p {_inferenceClientConfig.ZeroMqPort} -lp {_loaderClientConfig.ZeroMqPort} -a {_inferenceClientConfig.ApiUrl}",
|
||||
CreateNoWindow = true
|
||||
};
|
||||
process.Start();
|
||||
//process.Start();
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
|
||||
@@ -18,10 +18,8 @@ public class TileResult
|
||||
|
||||
public static class TileProcessor
|
||||
{
|
||||
private const int MaxTileWidth = 1280;
|
||||
private const int MaxTileHeight = 1280;
|
||||
private const int Border = 10;
|
||||
|
||||
public const int BORDER = 10;
|
||||
|
||||
public static List<TileResult> Split(Size originalSize, List<CanvasLabel> detections, CancellationToken cancellationToken)
|
||||
{
|
||||
var results = new List<TileResult>();
|
||||
@@ -30,7 +28,7 @@ public static class TileProcessor
|
||||
while (processingDetectionList.Count > 0 && !cancellationToken.IsCancellationRequested)
|
||||
{
|
||||
var topMostDetection = processingDetectionList
|
||||
.OrderBy(d => d.Y)
|
||||
.OrderBy(d => d.Top)
|
||||
.First();
|
||||
|
||||
var result = GetDetectionsInTile(originalSize, topMostDetection, processingDetectionList);
|
||||
@@ -42,11 +40,8 @@ public static class TileProcessor
|
||||
|
||||
private static TileResult GetDetectionsInTile(Size originalSize, CanvasLabel startDet, List<CanvasLabel> allDetections)
|
||||
{
|
||||
var tile = new CanvasLabel(
|
||||
left: Math.Max(startDet.X - Border, 0),
|
||||
right: Math.Min(startDet.Right + Border, originalSize.Width),
|
||||
top: Math.Max(startDet.Y - Border, 0),
|
||||
bottom: Math.Min(startDet.Bottom + Border, originalSize.Height));
|
||||
var tile = new CanvasLabel(startDet.Left, startDet.Right, startDet.Top, startDet.Bottom);
|
||||
var maxSize = new List<double> { startDet.Width + BORDER, startDet.Height + BORDER, Constants.AI_TILE_SIZE }.Max();
|
||||
var selectedDetections = new List<CanvasLabel>{startDet};
|
||||
|
||||
foreach (var det in allDetections)
|
||||
@@ -55,26 +50,26 @@ public static class TileProcessor
|
||||
continue;
|
||||
|
||||
var commonTile = new CanvasLabel(
|
||||
left: Math.Max(Math.Min(tile.X, det.X) - Border, 0),
|
||||
right: Math.Min(Math.Max(tile.Right, det.Right) + Border, originalSize.Width),
|
||||
top: Math.Max(Math.Min(tile.Y, det.Y) - Border, 0),
|
||||
bottom: Math.Min(Math.Max(tile.Bottom, det.Bottom) + Border, originalSize.Height)
|
||||
left: Math.Min(tile.Left, det.Left),
|
||||
right: Math.Max(tile.Right, det.Right),
|
||||
top: Math.Min(tile.Top, det.Top),
|
||||
bottom: Math.Max(tile.Bottom, det.Bottom)
|
||||
);
|
||||
|
||||
if (commonTile.Width > MaxTileWidth || commonTile.Height > MaxTileHeight)
|
||||
|
||||
if (commonTile.Width + BORDER > maxSize || commonTile.Height + BORDER > maxSize)
|
||||
continue;
|
||||
|
||||
tile = commonTile;
|
||||
selectedDetections.Add(det);
|
||||
}
|
||||
|
||||
//normalization, width and height should be at least half of 1280px
|
||||
tile.Width = Math.Max(tile.Width, MaxTileWidth / 2.0);
|
||||
tile.Height = Math.Max(tile.Height, MaxTileHeight / 2.0);
|
||||
|
||||
//boundaries check after normalization
|
||||
tile.Right = Math.Min(tile.Right, originalSize.Width);
|
||||
tile.Bottom = Math.Min(tile.Bottom, originalSize.Height);
|
||||
// boundary-aware centering
|
||||
var centerX = selectedDetections.Average(x => x.CenterX);
|
||||
var centerY = selectedDetections.Average(d => d.CenterY);
|
||||
tile.Width = maxSize;
|
||||
tile.Height = maxSize;
|
||||
tile.Left = Math.Max(0, Math.Min(originalSize.Width - maxSize, centerX - tile.Width / 2.0));
|
||||
tile.Top = Math.Max(0, Math.Min(originalSize.Height - maxSize, centerY - tile.Height / 2.0));
|
||||
|
||||
return new TileResult(tile, selectedDetections);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user