using MainShell.Vision; using SemiconductorVisionAlgorithm.SemiParams; using System; using System.Collections.Generic; using System.Threading; using System.Threading.Tasks; namespace MainShell.Process { public class WaferDieRecognizer : IWaferDieRecognizer { private readonly IFindDieService _findDieService; public WaferDieRecognizer(IFindDieService findDieService) { _findDieService = findDieService ?? throw new ArgumentNullException(nameof(findDieService)); } public FindDieImageRequest BuildRequest(WaferCaptureFrame frame, WaferDiePositionContext context) { FindDieImageRequest request = new FindDieImageRequest(); FindDieParameters parameters = new FindDieParameters(); parameters.CurrentRuler = frame == null ? new Point(0.0d, 0.0d) : new Point(frame.TriggerPoint.X, frame.TriggerPoint.Y); parameters.OverlapX = context != null && context.ScanSettings != null ? context.ScanSettings.OverlapRateX : 0d; parameters.OverlapY = context != null && context.ScanSettings != null ? context.ScanSettings.OverlapRateY : 0d; parameters.DieWidth = context != null && context.WaferRecipe != null && context.WaferRecipe.WaferInfo != null ? context.WaferRecipe.WaferInfo.DieSizeX : 0d; parameters.DieHeight = context != null && context.WaferRecipe != null && context.WaferRecipe.WaferInfo != null ? context.WaferRecipe.WaferInfo.DieSizeY : 0d; parameters.ScoreThreshold = 0.8d; parameters.TemplatePath = string.Empty; parameters.SerialNumber = string.Empty; request.Parameters = parameters; request.TimeoutMilliseconds = 3000; return request; } public async Task RecognizeAsync(WaferCaptureFrame frame, WaferDiePositionContext context, CancellationToken cancellationToken) { if (frame == null) { throw new ArgumentNullException(nameof(frame)); } WaferRecognitionFrameResult frameResult = new WaferRecognitionFrameResult(); frameResult.SequenceId = frame.SequenceId; if (frame.Image == null) { frameResult.IsSuccess = false; frameResult.ErrorMessage = "DiePosition: capture frame image is null."; return frameResult; } FindDieImageRequest request = BuildRequest(frame, context); VisionProcessResult result = await _findDieService.ProcessMultipleImageAsync(frame.Image, request, cancellationToken).ConfigureAwait(false); if (result == null || !result.Succeeded || result.Data == null) { frameResult.IsSuccess = false; frameResult.ErrorMessage = result == null ? "DiePosition: recognition returned null result." : result.Message; return frameResult; } List rowsReal = new List(); List columnsReal = new List(); List angles = new List(); List overlapRows = new List(); List overlapColumns = new List(); List overlapAngles = new List(); foreach (FindDieResult item in result.Data.Items) { if (item.IsOverlap) { overlapRows.Add(item.CenterY); overlapColumns.Add(item.CenterX); overlapAngles.Add(item.Angle); } else { rowsReal.Add(item.CenterY); columnsReal.Add(item.CenterX); angles.Add(item.Angle); } } frameResult.IsSuccess = true; frameResult.ErrorMessage = null; frameResult.RowsReal = rowsReal.ToArray(); frameResult.ColumnsReal = columnsReal.ToArray(); frameResult.Angles = angles.ToArray(); frameResult.OverlapRows = overlapRows.ToArray(); frameResult.OverlapColumns = overlapColumns.ToArray(); frameResult.OverlapAngles = overlapAngles.ToArray(); frameResult.UniqueCount = frameResult.RowsReal.Length; frameResult.OverlapCount = frameResult.OverlapRows.Length; return frameResult; } } }