194 lines
7.7 KiB
C#
194 lines
7.7 KiB
C#
|
|
using MainShell.Log;
|
|||
|
|
using MainShell.Models;
|
|||
|
|
using MaxwellFramework.Core.Attributes;
|
|||
|
|
using System;
|
|||
|
|
using System.Threading;
|
|||
|
|
using System.Threading.Tasks;
|
|||
|
|
|
|||
|
|
namespace MainShell.Vision
|
|||
|
|
{
|
|||
|
|
/// <summary>
|
|||
|
|
/// <20><><EFBFBD><EFBFBD>ʶ<EFBFBD><CAB6><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʵ<EFBFBD>֡<EFBFBD>
|
|||
|
|
/// </summary>
|
|||
|
|
[Singleton]
|
|||
|
|
public class FindCenterService : IFindCenterService
|
|||
|
|
{
|
|||
|
|
private readonly IImageCaptureService _imageCaptureService;
|
|||
|
|
|
|||
|
|
public FindCenterService(IImageCaptureService imageCaptureService)
|
|||
|
|
{
|
|||
|
|
_imageCaptureService = imageCaptureService ?? throw new ArgumentNullException(nameof(imageCaptureService));
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
public async Task<VisionProcessResult<FindCenterResult>> ProcessAsync(
|
|||
|
|
FindCenterRequest request,
|
|||
|
|
CancellationToken cancellationToken = default(CancellationToken))
|
|||
|
|
{
|
|||
|
|
if (request == null)
|
|||
|
|
{
|
|||
|
|
throw new ArgumentNullException(nameof(request));
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
ImageCaptureResult captureResult = null;
|
|||
|
|
MxImage image = null;
|
|||
|
|
|
|||
|
|
try
|
|||
|
|
{
|
|||
|
|
captureResult = await _imageCaptureService.CaptureAsync(
|
|||
|
|
request.CameraSource,
|
|||
|
|
request.CaptureOptions,
|
|||
|
|
cancellationToken).ConfigureAwait(false);
|
|||
|
|
|
|||
|
|
if (captureResult == null)
|
|||
|
|
{
|
|||
|
|
string message = string.Format(
|
|||
|
|
"FindCenterService: image capture returned null result for camera '{0}'.",
|
|||
|
|
request.CameraSource);
|
|||
|
|
message.LogSysError();
|
|||
|
|
return VisionProcessResult<FindCenterResult>.Failure(message);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (!captureResult.Succeeded)
|
|||
|
|
{
|
|||
|
|
return VisionProcessResult<FindCenterResult>.Failure(captureResult.Message, captureResult.Exception);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
image = captureResult.Image;
|
|||
|
|
if (image == null)
|
|||
|
|
{
|
|||
|
|
string message = string.Format(
|
|||
|
|
"FindCenterService: image capture succeeded but returned null image for camera '{0}'.",
|
|||
|
|
request.CameraSource);
|
|||
|
|
message.LogSysError();
|
|||
|
|
return VisionProcessResult<FindCenterResult>.Failure(message);
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
FindCenterImageRequest imageRequest = new FindCenterImageRequest();
|
|||
|
|
imageRequest.TimeoutMilliseconds = request.TimeoutMilliseconds;
|
|||
|
|
imageRequest.Parameters = request.Parameters;
|
|||
|
|
|
|||
|
|
return await ProcessImageAsync(image, imageRequest, cancellationToken).ConfigureAwait(false);
|
|||
|
|
}
|
|||
|
|
catch (OperationCanceledException ex)
|
|||
|
|
{
|
|||
|
|
string message = "FindCenterService: process was cancelled.";
|
|||
|
|
message.LogInfo();
|
|||
|
|
return VisionProcessResult<FindCenterResult>.Failure(message, ex);
|
|||
|
|
}
|
|||
|
|
catch (Exception ex)
|
|||
|
|
{
|
|||
|
|
string message = string.Format("FindCenterService: process failed. {0}", ex.Message);
|
|||
|
|
message.LogSysError();
|
|||
|
|
return VisionProcessResult<FindCenterResult>.Failure(message, ex);
|
|||
|
|
}
|
|||
|
|
finally
|
|||
|
|
{
|
|||
|
|
if (image != null)
|
|||
|
|
{
|
|||
|
|
image.Dispose();
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
public Task<VisionProcessResult<FindCenterResult>> ProcessImageAsync(
|
|||
|
|
MxImage image,
|
|||
|
|
FindCenterImageRequest request,
|
|||
|
|
CancellationToken cancellationToken = default(CancellationToken))
|
|||
|
|
{
|
|||
|
|
if (image == null)
|
|||
|
|
{
|
|||
|
|
throw new ArgumentNullException(nameof(image));
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (request == null)
|
|||
|
|
{
|
|||
|
|
throw new ArgumentNullException(nameof(request));
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
FindCenterImageRequest normalizedRequest = NormalizeRequest(request);
|
|||
|
|
VisionProcessResult validationResult = ValidateRequest(normalizedRequest);
|
|||
|
|
if (validationResult != null)
|
|||
|
|
{
|
|||
|
|
return Task.FromResult(VisionProcessResult<FindCenterResult>.Failure(validationResult.Message, validationResult.Exception));
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
try
|
|||
|
|
{
|
|||
|
|
cancellationToken.ThrowIfCancellationRequested();
|
|||
|
|
|
|||
|
|
string message = string.Format(
|
|||
|
|
"FindCenterService: algorithm is not implemented. RoiName={0}, UseRoi={1}, MinScore={2}.",
|
|||
|
|
normalizedRequest.Parameters != null ? normalizedRequest.Parameters.RoiName : null,
|
|||
|
|
normalizedRequest.Parameters != null && normalizedRequest.Parameters.UseRoi,
|
|||
|
|
normalizedRequest.Parameters != null ? normalizedRequest.Parameters.MinScore : 0.0);
|
|||
|
|
|
|||
|
|
message.LogSysError();
|
|||
|
|
return Task.FromResult(VisionProcessResult<FindCenterResult>.Failure(message));
|
|||
|
|
}
|
|||
|
|
catch (OperationCanceledException ex)
|
|||
|
|
{
|
|||
|
|
string message = string.Format(
|
|||
|
|
"FindCenterService: process image was cancelled. Timeout={0} ms.",
|
|||
|
|
normalizedRequest.TimeoutMilliseconds);
|
|||
|
|
message.LogInfo();
|
|||
|
|
return Task.FromResult(VisionProcessResult<FindCenterResult>.Failure(message, ex));
|
|||
|
|
}
|
|||
|
|
catch (Exception ex)
|
|||
|
|
{
|
|||
|
|
string message = string.Format("FindCenterService: process image failed. {0}", ex.Message);
|
|||
|
|
message.LogSysError();
|
|||
|
|
return Task.FromResult(VisionProcessResult<FindCenterResult>.Failure(message, ex));
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
private static FindCenterImageRequest NormalizeRequest(FindCenterImageRequest request)
|
|||
|
|
{
|
|||
|
|
FindCenterImageRequest normalizedRequest = new FindCenterImageRequest();
|
|||
|
|
normalizedRequest.TimeoutMilliseconds = request.TimeoutMilliseconds > 0 ? request.TimeoutMilliseconds : 3000;
|
|||
|
|
normalizedRequest.Parameters = CloneParameters(request.Parameters);
|
|||
|
|
return normalizedRequest;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
private static VisionProcessResult ValidateRequest(FindCenterImageRequest request)
|
|||
|
|
{
|
|||
|
|
if (request.Parameters == null)
|
|||
|
|
{
|
|||
|
|
return VisionProcessResult.Failure("FindCenterService: parameters cannot be null.");
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (request.TimeoutMilliseconds <= 0 || request.TimeoutMilliseconds > 60000)
|
|||
|
|
{
|
|||
|
|
return VisionProcessResult.Failure(
|
|||
|
|
string.Format("FindCenterService: TimeoutMilliseconds {0} is invalid. Expected range is [1, 60000].", request.TimeoutMilliseconds));
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (request.Parameters.MinScore <= 0d || request.Parameters.MinScore > 1d)
|
|||
|
|
{
|
|||
|
|
return VisionProcessResult.Failure(
|
|||
|
|
string.Format("FindCenterService: MinScore {0} is invalid. Expected range is (0, 1].", request.Parameters.MinScore));
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
if (request.Parameters.UseRoi && string.IsNullOrWhiteSpace(request.Parameters.RoiName))
|
|||
|
|
{
|
|||
|
|
return VisionProcessResult.Failure("FindCenterService: RoiName cannot be empty when UseRoi is true.");
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
return null;
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
private static FindCenterParameters CloneParameters(FindCenterParameters parameters)
|
|||
|
|
{
|
|||
|
|
if (parameters == null)
|
|||
|
|
{
|
|||
|
|
return new FindCenterParameters();
|
|||
|
|
}
|
|||
|
|
|
|||
|
|
FindCenterParameters clone = new FindCenterParameters();
|
|||
|
|
clone.UseRoi = parameters.UseRoi;
|
|||
|
|
clone.RoiName = parameters.RoiName;
|
|||
|
|
clone.MinScore = parameters.MinScore;
|
|||
|
|
return clone;
|
|||
|
|
}
|
|||
|
|
}
|
|||
|
|
}
|