LuJiaYi/SimboObjectDetection.cs
2024-08-17 18:00:59 +08:00

305 lines
8.7 KiB
C#
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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.Runtime.InteropServices;
using Newtonsoft.Json;
public class SegResult
{
public List<Result> SegmentResult;
public class Result
{
public double fScore;
public int classId;
public string classname;
public double area;
public List<int> rect;
}
}
/// <summary>
/// 实例分割 maskrcnn
/// </summary>
public class SimboObjectDetection
{
IntPtr Model;
public bool Load(string ModelFile, string InferenceDevice, string InputNodeName, int InferenceWidth, int InferenceHeight)
{
bool res = false;
try
{
Model = MLEngine.InitModel(ModelFile,
InferenceDevice,
InputNodeName,
1, 3,
InferenceWidth,
InferenceHeight);
res = true;
#if USE_MULTI_THREAD
IsCreated = true;
if (IsCreated)
{
if (_runHandleBefore == null)
{
_runHandleBefore = new AutoResetEvent(false);
}
if (_runHandleAfter == null)
{
_runHandleAfter = new ManualResetEvent(false);
}
if (_runTask == null)
{
_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 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
}
public static int LableCount(string json, string targetLabel)//出现的标签数
{
// 解析 JSON 结果
SegResult detResult = JsonConvert.DeserializeObject<SegResult>(json);
if (detResult == null)
{
throw new ArgumentException("Invalid JSON format.");
}
// 统计目标标签的数量
int labelCount = detResult.SegmentResult
.Count(det => det.classname.Equals(targetLabel, StringComparison.OrdinalIgnoreCase));
return labelCount;
}
public static Rect RectMes(string json, string targetLabel)
{
SegResult detResult = JsonConvert.DeserializeObject<SegResult>(json);
if (detResult == null)
{
throw new ArgumentException("Invalid JSON format.");
}
// 获取第一个指定标签的框信息
var result = detResult.SegmentResult
.FirstOrDefault(det => det.classname.Equals(targetLabel, StringComparison.OrdinalIgnoreCase));
// 如果找到匹配的结果,返回其矩形框;否则返回 null
return new Rect(result.rect[0], result.rect[1], result.rect[2], result.rect[3]);
}
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);
SegResult detResult = JsonConvert.DeserializeObject<SegResult>(json);
if (detResult == null)
{
return;
}
int iNum = detResult.SegmentResult.Count;
int IokNum = 0;
for (int ix = 0; ix < iNum; ix++)
{
var det = detResult.SegmentResult[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 = det.area;
// detectionResultDetail.InferenceResult = ResultState.NG;
result.ResultDetails.Add(detectionResultDetail);
}
result.ResultDetails.Sort((s1, s2) => s1.Rect.X.CompareTo(s2.Rect.X));
}
[HandleProcessCorruptedStateExceptions]
public MLResult RunInferenceFixed(MLRequest req)
{
MLResult mlResult = new MLResult();
Mat originMat = new Mat();
try
{
// resize
originMat = req.currentMat;//1ms
int iWidth = originMat.Cols;
int iHeight = originMat.Rows;
//输入数据转化为字节
var inputByte = new byte[originMat.Total() * 3];//这里必须乘以通道数不然数组越界也可以用w*h*c差不多
Marshal.Copy(originMat.Data, inputByte, 0, inputByte.Length);
byte[] labellist = new byte[20480]; //新建字节数组label1_str label2_str
byte[] outputByte = new byte[originMat.Total() * 3];
Stopwatch sw = new Stopwatch();
sw.Start();
unsafe
{
mlResult.IsSuccess = MLEngine.det_ModelPredict(Model,
inputByte,
iWidth, iHeight, 3,
req.out_node_name,
req.in_lable_path,
req.confThreshold, req.iouThreshold,
ref outputByte[0],
ref labellist[0]);
//mlResult.IsSuccess = true;
}
sw.Stop();
if (mlResult.IsSuccess)
{
mlResult.ResultMessage = $"深度学习推理成功,耗时:{sw.ElapsedMilliseconds} ms";
Mat maskWeighted = new Mat(iHeight, iWidth, MatType.CV_8UC3, outputByte);
mlResult.ResultMap = BitmapConverter.ToBitmap(maskWeighted);//4ms
//将字节数组转换为字符串
// mlResult.ResultMap = originMat.ToBitmap();//4ms
mlResult.JsonString = System.Text.Encoding.Default.GetString(labellist, 0, labellist.Length);
ConvertJsonResult(mlResult.JsonString, ref mlResult);
maskWeighted?.Dispose();
maskWeighted = null;
// 解析json字符串
return mlResult;
}
else
{
mlResult.ResultMessage = $"异常:深度学习执行推理失败!";
return mlResult;
}
}
catch (Exception ex)
{
//mlResult.ResultMessage = $"深度学习执行推理异常:{ex.GetExceptionMessage()}";
return mlResult;
}
finally
{
// originMat?.Dispose();
// originMat = null;
// GC.Collect();
}
}
}