using System.Windows; using System.Windows.Media.Imaging; using Azaion.Common.DTO; namespace Azaion.Common.Services; public class TileResult(CanvasLabel tile, List detections) { public CanvasLabel Tile { get; set; } = tile; public List Detections { get; set; } = detections; } public static class TileProcessor { public const int BORDER = 10; public static List Split(Size originalSize, List detections, CancellationToken cancellationToken) { var results = new List(); var processingDetectionList = new List(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 allDetections) { var tile = new CanvasLabel(startDet.Left, startDet.Right, startDet.Top, startDet.Bottom); var maxSize = new List { startDet.Width + BORDER, startDet.Height + BORDER, Constants.AI_TILE_SIZE_DEFAULT }.Max(); var selectedDetections = new List{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); } }