版本260406

This commit is contained in:
2026-04-06 22:04:05 +08:00
parent 7dc5e73af7
commit 0b150470be
216 changed files with 98993 additions and 33 deletions

View File

@@ -0,0 +1,164 @@
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using OrpaonVision.Core.Results;
using OrpaonVision.SiteApp.Runtime.Contracts;
using OrpaonVision.SiteApp.Runtime.Options;
using OrpaonVision.SiteApp.Runtime.Services;
namespace OrpaonVision.SiteApp.Runtime.Services;
/// <summary>
/// YOLO推理服务适配器将IYoloInferenceService适配到IInferenceService接口。
/// </summary>
public sealed class YoloInferenceAdapter : IInferenceService
{
private readonly ILogger<YoloInferenceAdapter> _logger;
private readonly IYoloInferenceService _yoloInferenceService;
private readonly RuntimeOptions _options;
/// <summary>
/// 构造函数。
/// </summary>
public YoloInferenceAdapter(
ILogger<YoloInferenceAdapter> logger,
IYoloInferenceService yoloInferenceService,
IOptions<RuntimeOptions> options)
{
_logger = logger;
_yoloInferenceService = yoloInferenceService;
_options = options.Value;
}
/// <inheritdoc />
public Result<InferenceResultDto> Predict(CameraFrameDto frame)
{
try
{
// 确保YOLO模型已初始化
if (!_yoloInferenceService.IsInitialized)
{
var initResult = _yoloInferenceService.Initialize();
if (!initResult.Succeeded)
{
return Result<InferenceResultDto>.Fail(initResult.Code, initResult.Message, initResult.Errors.ToArray());
}
}
// 执行YOLO推理
var predictResult = _yoloInferenceService.Predict(
frame.ImageData,
frame.Width,
frame.Height,
frame.PixelFormat);
if (!predictResult.Succeeded)
{
return Result<InferenceResultDto>.Fail(predictResult.Code, predictResult.Message, predictResult.Errors.ToArray());
}
var detections = predictResult.Data;
// 转换为InferenceResultDto格式
var inferenceResult = new InferenceResultDto
{
FrameId = frame.FrameId,
InferenceId = Guid.NewGuid(),
InferredAtUtc = DateTime.UtcNow,
ModelName = _yoloInferenceService.GetModelInfo().ModelName,
ModelVersion = _yoloInferenceService.GetModelInfo().ModelVersion,
InferenceTimeMs = _yoloInferenceService.GetModelInfo().InferenceTimeMs,
Detections = detections.Select(d => new DetectionDto
{
ClassId = d.ClassId,
ClassName = d.ClassName,
Confidence = d.Confidence,
X = d.X,
Y = d.Y,
Width = d.Width,
Height = d.Height,
CenterX = d.CenterX,
CenterY = d.CenterY,
Area = d.Area
}).ToList()
};
// 应用NG阈值
var hasHighConfidenceDetection = detections.Any(d => d.Confidence >= (float)_options.NgConfidenceThreshold);
inferenceResult.IsNg = hasHighConfidenceDetection;
_logger.LogDebug("YOLO推理完成检测到 {Count} 个目标NG判定: {IsNg}",
detections.Count, inferenceResult.IsNg);
return Result<InferenceResultDto>.Success(inferenceResult, message: "YOLO推理成功。");
}
catch (Exception ex)
{
var traceId = Guid.NewGuid().ToString("N");
_logger.LogError(ex, "YOLO推理适配失败。TraceId: {TraceId}", traceId);
var result = Result.FromException(ex, "YOLO_ADAPTER_PREDICT_FAILED", "YOLO推理适配失败。", traceId);
return Result<InferenceResultDto>.FailWithTrace(result.Code, result.Message, result.TraceId ?? traceId, result.Errors.ToArray());
}
}
/// <summary>
/// 初始化推理服务。
/// </summary>
public Result Initialize()
{
try
{
_logger.LogInformation("正在初始化YOLO推理适配器...");
var initResult = _yoloInferenceService.Initialize();
if (!initResult.Succeeded)
{
return initResult;
}
var modelInfo = _yoloInferenceService.GetModelInfo();
_logger.LogInformation("YOLO推理适配器初始化成功模型: {ModelName},类别数: {ClassCount}",
modelInfo.ModelName, modelInfo.ClassCount);
return Result.Success(message: "YOLO推理适配器初始化成功。");
}
catch (Exception ex)
{
var traceId = Guid.NewGuid().ToString("N");
_logger.LogError(ex, "初始化YOLO推理适配器失败。TraceId: {TraceId}", traceId);
var result = Result.FromException(ex, "YOLO_ADAPTER_INIT_FAILED", "初始化YOLO推理适配器失败。", traceId);
return Result.FailWithTrace(result.Code, result.Message, result.TraceId ?? traceId, result.Errors.ToArray());
}
}
/// <summary>
/// 获取模型信息。
/// </summary>
public YoloModelInfo GetModelInfo()
{
return _yoloInferenceService.GetModelInfo();
}
/// <summary>
/// 获取支持的类别。
/// </summary>
public IReadOnlyList<string> GetSupportedClasses()
{
return _yoloInferenceService.GetSupportedClasses();
}
/// <summary>
/// 清理资源。
/// </summary>
public void Cleanup()
{
try
{
_yoloInferenceService.Dispose();
_logger.LogInformation("YOLO推理适配器清理完成");
}
catch (Exception ex)
{
_logger.LogError(ex, "清理YOLO推理适配器时发生异常");
}
}
}