104 lines
4.5 KiB
C#
104 lines
4.5 KiB
C#
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<WaferRecognitionFrameResult> 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<FindDiesResult> 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<double> rowsReal = new List<double>();
|
|
List<double> columnsReal = new List<double>();
|
|
List<double> angles = new List<double>();
|
|
List<double> overlapRows = new List<double>();
|
|
List<double> overlapColumns = new List<double>();
|
|
List<double> overlapAngles = new List<double>();
|
|
|
|
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;
|
|
}
|
|
}
|
|
} |