256 lines
9.0 KiB
C#
256 lines
9.0 KiB
C#
//#define USE_MULTI_THREAD
|
||
|
||
using OpenCvSharp;
|
||
using OpenCvSharp.Extensions;
|
||
using System;
|
||
using System.Collections.Generic;
|
||
using System.Diagnostics;
|
||
using System.Drawing;
|
||
using System.Linq;
|
||
using System.Runtime.ExceptionServices;
|
||
using System.Threading;
|
||
using System.Threading.Tasks;
|
||
using System.Security.Cryptography.Xml;
|
||
using System.Runtime.InteropServices;
|
||
using Newtonsoft.Json;
|
||
using DH.Commons.Enums;
|
||
|
||
|
||
|
||
namespace DH.Devices.Vision
|
||
{
|
||
|
||
|
||
/// <summary>
|
||
/// 目标检测 GPU
|
||
/// </summary>
|
||
public class SimboDetection : SimboVisionMLBase
|
||
{
|
||
|
||
public override bool Load(MLInit mLInit)
|
||
{
|
||
bool res = false;
|
||
try
|
||
{
|
||
Model = MLGPUEngine.InitModel(mLInit.ModelFile, 1, mLInit.Score_thre, mLInit.GPUId, 3, 8);
|
||
|
||
//Model = MLEngine.InitModel(mLInit.ModelFile, 1, 0.45f, 0, 3);
|
||
|
||
res = true;
|
||
|
||
#if USE_MULTI_THREAD
|
||
IsCreated = true;
|
||
if (IsCreated)
|
||
{
|
||
_runHandleBefore ??= new AutoResetEvent(false);
|
||
_runHandleAfter ??= new ManualResetEvent(false);
|
||
|
||
_runTask ??= Task.Factory.StartNew(() =>
|
||
{
|
||
while (IsCreated)
|
||
{
|
||
_runHandleBefore.WaitOne();
|
||
|
||
if (IsCreated)
|
||
{
|
||
_result = RunInferenceFixed(_req);
|
||
_runHandleAfter.Set();
|
||
}
|
||
}
|
||
}, TaskCreationOptions.LongRunning);
|
||
}
|
||
#endif
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
throw ex;
|
||
}
|
||
return res;
|
||
}
|
||
#if USE_MULTI_THREAD
|
||
MLRequest _req = null;
|
||
MLResult _result = null;
|
||
public bool IsCreated { get; set; } = false;
|
||
Task _runTask = null;
|
||
AutoResetEvent _runHandleBefore = new AutoResetEvent(false);
|
||
ManualResetEvent _runHandleAfter = new ManualResetEvent(false);
|
||
object _runLock = new object();
|
||
#endif
|
||
[HandleProcessCorruptedStateExceptions]
|
||
public override MLResult RunInference(MLRequest req)
|
||
{
|
||
#if USE_MULTI_THREAD
|
||
MLResult mlResult = null;
|
||
lock (_runLock)
|
||
{
|
||
_result = new MLResult();
|
||
|
||
_req = req;
|
||
|
||
_runHandleAfter.Reset();
|
||
_runHandleBefore.Set();
|
||
_runHandleAfter.WaitOne();
|
||
|
||
mlResult = _result;
|
||
}
|
||
|
||
return mlResult;
|
||
#else
|
||
return RunInferenceFixed(req);
|
||
#endif
|
||
}
|
||
private void ConvertJsonResult(string json, ref MLResult result)
|
||
{
|
||
// json = "{\"FastDetResult\":[{\"cls_id\":0,\"cls\":\"liewen\",\"fScore\":0.654843,\"rect\":[175,99,110,594]},{\"cls_id\":0,\"cls\":\"liewen\",\"fScore\":0.654589,\"rect\":[2608,19,104,661]},{\"cls_id\":0,\"cls\":\"liewen\",\"fScore\":0.654285,\"rect\":[1275,19,104,662]},{\"cls_id\":0,\"cls\":\"liewen\",\"fScore\":0.620762,\"rect\":[1510,95,107,600]},{\"cls_id\":0,\"cls\":\"liewen\",\"fScore\":0.617812,\"rect\":[2844,93,106,602]}]}";
|
||
//
|
||
Console.WriteLine("检测结果JSON:" + json);
|
||
#pragma warning disable CS8600 // 将 null 字面量或可能为 null 的值转换为非 null 类型
|
||
HYoloResult detResult = JsonConvert.DeserializeObject<HYoloResult>(json);
|
||
#pragma warning restore CS8600 // 将 null 字面量或可能为 null 的值转换为非 null 类型
|
||
if (detResult == null)
|
||
{
|
||
return;
|
||
}
|
||
|
||
int iNum = detResult.HYolo.Count;
|
||
#pragma warning disable CS0219 // 变量已被赋值,但从未使用过它的值
|
||
int IokNum = 0;
|
||
#pragma warning restore CS0219 // 变量已被赋值,但从未使用过它的值
|
||
for (int ix = 0; ix < iNum; ix++)
|
||
{
|
||
var det = detResult.HYolo[ix];
|
||
|
||
var rect = det.rect;
|
||
DetectionResultDetail detectionResultDetail = new DetectionResultDetail();
|
||
// detectionResultDetail.LabelNo = det.classId;
|
||
//todo: 标签名相对应
|
||
detectionResultDetail.LabelDisplay = det.classname;
|
||
detectionResultDetail.Rect = new Rectangle(rect[0], rect[1], rect[2], rect[3]);
|
||
detectionResultDetail.Score = det.fScore;
|
||
detectionResultDetail.LabelName = det.classname;
|
||
detectionResultDetail.Area = rect[2] * rect[3];
|
||
detectionResultDetail.InferenceResult = ResultState.DetectNG;
|
||
|
||
result.ResultDetails.Add(detectionResultDetail);
|
||
|
||
|
||
}
|
||
|
||
}
|
||
|
||
[HandleProcessCorruptedStateExceptions]
|
||
public MLResult RunInferenceFixed(MLRequest req)
|
||
{
|
||
MLResult mlResult = new MLResult();
|
||
Mat originMat = new Mat();
|
||
Mat detectMat = new Mat();
|
||
|
||
#pragma warning disable CS0168 // 声明了变量,但从未使用过
|
||
try
|
||
{
|
||
if (req.mImage == null)
|
||
{
|
||
mlResult.IsSuccess = false;
|
||
mlResult.ResultMessage = "异常:mat为null,无法执行推理!";
|
||
return mlResult;
|
||
}
|
||
|
||
// resize
|
||
detectMat = req.mImage;//1ms
|
||
|
||
|
||
|
||
int iWidth = detectMat.Cols;
|
||
int iHeight = detectMat.Rows;
|
||
|
||
// 如果是单通道图像,转换为三通道 RGB 格式
|
||
if (detectMat.Channels() == 1)
|
||
{
|
||
// 将灰度图像转换为RGB格式(三通道)
|
||
|
||
Cv2.CvtColor(detectMat, originMat, ColorConversionCodes.GRAY2BGR);
|
||
|
||
}
|
||
else if (detectMat.Channels() == 3)
|
||
{
|
||
// 如果已经是三通道(BGR),则直接转换为RGB
|
||
|
||
Cv2.CvtColor(detectMat, originMat, ColorConversionCodes.BGR2RGB);
|
||
|
||
}
|
||
|
||
//输入数据转化为字节
|
||
var inputByte = new byte[originMat.Total() * 3];//这里必须乘以通道数,不然数组越界,也可以用w*h*c,差不多
|
||
Marshal.Copy(originMat.Data, inputByte, 0, inputByte.Length);
|
||
|
||
byte[] labellist = new byte[40960]; //新建字节数组:label1_str label2_str
|
||
|
||
byte[] outputByte = new byte[originMat.Total() * 3];
|
||
|
||
Stopwatch sw = new Stopwatch();
|
||
sw.Start();
|
||
|
||
//mlResult.IsSuccess = true;
|
||
unsafe
|
||
{
|
||
//mlResult.IsSuccess = MLGPUEngine.Inference(Model, inputByte, iWidth, iHeight, 3, req.in_lable_path, ref outputByte[0], ref labellist[0]);
|
||
|
||
mlResult.IsSuccess = MLGPUEngine.Inference2(Model, inputByte, iWidth, iHeight, 3, req.in_lable_path, ref labellist[0]);
|
||
}
|
||
|
||
sw.Stop();
|
||
|
||
|
||
if (mlResult.IsSuccess)
|
||
{
|
||
mlResult.ResultMessage = $"深度学习推理成功,耗时:{sw.ElapsedMilliseconds} ms";
|
||
|
||
//将字节数组转换为字符串
|
||
mlResult.ResultMap = originMat.ToBitmap();//4ms
|
||
string strGet = System.Text.Encoding.Default.GetString(labellist, 0, labellist.Length);
|
||
|
||
if (strGet == null)
|
||
{
|
||
mlResult.ResultMessage = $"异常:深度学习执行推理失败!";
|
||
return mlResult;
|
||
}
|
||
|
||
ConvertJsonResult(strGet, ref mlResult);
|
||
|
||
return mlResult;
|
||
}
|
||
else
|
||
{
|
||
mlResult.ResultMessage = $"异常:深度学习执行推理失败!";
|
||
return mlResult;
|
||
}
|
||
}
|
||
catch (Exception ex)
|
||
{
|
||
mlResult.ResultMessage = $"深度学习执行推理异常";
|
||
return mlResult;
|
||
}
|
||
finally
|
||
{
|
||
|
||
originMat?.Dispose();
|
||
#pragma warning disable CS8600 // 将 null 字面量或可能为 null 的值转换为非 null 类型
|
||
originMat = null;
|
||
#pragma warning restore CS8600 // 将 null 字面量或可能为 null 的值转换为非 null 类型
|
||
//maskMat?.Dispose();
|
||
// maskMat = null;
|
||
detectMat?.Dispose();
|
||
#pragma warning disable CS8600 // 将 null 字面量或可能为 null 的值转换为非 null 类型
|
||
detectMat = null;
|
||
#pragma warning restore CS8600 // 将 null 字面量或可能为 null 的值转换为非 null 类型
|
||
// maskWeighted?.Dispose();
|
||
// maskWeighted = null;
|
||
// GC.Collect();
|
||
}
|
||
#pragma warning restore CS0168 // 声明了变量,但从未使用过
|
||
}
|
||
|
||
|
||
}
|
||
}
|