Files
annotations/Azaion.Common/Services/TileProcessor.cs
T
Oleksandr Bezdieniezhnykh b6b6751c37 fix loader bug with _CACHED_HW_INFO
put tile size to name and set it dynamically for AI recognition
2025-09-02 13:59:23 +03:00

71 lines
2.7 KiB
C#

using System.Windows;
using System.Windows.Media.Imaging;
using Azaion.Common.DTO;
namespace Azaion.Common.Services;
public class TileResult(CanvasLabel tile, List<CanvasLabel> detections)
{
public CanvasLabel Tile { get; set; } = tile;
public List<CanvasLabel> Detections { get; set; } = detections;
}
public static class TileProcessor
{
public const int BORDER = 10;
public static List<TileResult> Split(Size originalSize, List<CanvasLabel> detections, CancellationToken cancellationToken)
{
var results = new List<TileResult>();
var processingDetectionList = new List<CanvasLabel>(detections);
while (processingDetectionList.Count > 0 && !cancellationToken.IsCancellationRequested)
{
var topMostDetection = processingDetectionList
.OrderBy(d => d.Top)
.First();
var result = GetDetectionsInTile(originalSize, topMostDetection, processingDetectionList);
processingDetectionList.RemoveAll(x => result.Detections.Contains(x));
results.Add(result);
}
return results;
}
private static TileResult GetDetectionsInTile(Size originalSize, CanvasLabel startDet, List<CanvasLabel> allDetections)
{
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_DEFAULT }.Max();
var selectedDetections = new List<CanvasLabel>{startDet};
foreach (var det in allDetections)
{
if (det == startDet)
continue;
var commonTile = new CanvasLabel(
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 + BORDER > maxSize || commonTile.Height + BORDER > maxSize)
continue;
tile = commonTile;
selectedDetections.Add(det);
}
// 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);
}
}