123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201 |
- using AI.Common;
- using AI.Common.Log;
- using AI.Common.Tools;
- using UsHepatoRenalRatioDetectLib.InferenceNetworks.Onnx;
- using System;
- using System.Collections.Generic;
- using System.IO;
- namespace UsHepatoRenalRatioDetectLib.OrganSegProcessModule
- {
- public class OrganSegProcess : IOrganSegProcess
- {
- #region private
- private IInferenceNetwork _inferNet;
- private string _netDir = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Networks");
- private InferenceCore _inferCore = null;
- private volatile bool _initialized = false;
- #endregion
- #region 实现接口
- /// <summary>
- /// 构造函数
- /// </summary>
- public OrganSegProcess()
- {
- }
- /// <summary>
- /// 通知订阅者,有log要记
- /// </summary>
- public event EventHandler<LogEventArgs> NotifyLog;
- /// <summary>
- /// 通知订阅者,推理过程中发生了错误
- /// </summary>
- public event EventHandler<ErrorEventArgs> NotifyError;
- ///// <summary>
- ///// 通知订阅者,脏器分割结果有更新
- ///// </summary>
- //public event EventHandler<OrganSegUpdateEventArgs> NotifyOrganSegProcessFinish;
- /// <summary>
- /// 初始化
- /// </summary>
- /// <param name="modelNames"></param>
- /// <param name="modelDir"></param>
- /// <returns></returns>
- public void Init(InferenceCore inferCore, EnumDeviceType deviceType, string netDir)
- {
- _inferNet = new InferNetOnnxOrganDetectorAbdomen();
- if (_netDir != string.Empty && Directory.Exists(netDir))
- {
- _netDir = netDir;
- }
- _inferCore = inferCore;
- _initialized = true;
- }
- /// <summary>
- /// 加载模型
- /// </summary>
- /// <param name="modelName"></param>
- public void LoadGuideInferNet()
- {
- if (!_initialized)
- {
- throw new Exception("UsImageAnalyser should be initialized before use.");
- }
- try
- {
- if (!_inferNet.ModelLoaded)
- {
- //string netDir = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Networks");
- byte[] trainedNetwork = InferenceNetworkUtils.ReadNetworkDataFromFile(_netDir, _inferNet.NetworkName, _inferNet.HashCode);
- // 设置inferCore的参数
- //_inferenceCore.SetConfig(EnumInferCoreConfigKey.CPU_THREADS_NUM, numCpu.ToString(), EnumDeviceType.CPU);
- _inferNet.LoadNetwork(_inferCore, EnumDeviceType.CPU, trainedNetwork);
- }
- }
- catch (Exception excep)
- {
- throw new Exception("Failed at Loading network:" + excep);
- }
- }
- /// <summary>
- /// 卸载模型
- /// </summary>
- /// <param name="modelName"></param>
- public void UnLoadGuideInferNet()
- {
- if (!_initialized)
- {
- throw new Exception("UsImageAnalyser should be initialized before use.");
- }
- if (_inferNet.ModelLoaded)
- {
- _inferNet?.Dispose();
- }
- }
- /// <summary>
- /// 推理一幅图像
- /// </summary>
- /// <param name="image"></param>
- /// <returns></returns>
- public List<DetectedOrgan> EvaluateOneImage(RawImage image, bool isCropped)
- {
- List<DetectedOrgan> detectedOrgansPerImg = new List<DetectedOrgan>();
- if (!_initialized)
- {
- throw new Exception("UsImageAnalyser should be initialized before use.");
- }
- if (!_inferNet.ModelLoaded)
- {
- throw new Exception("InferNet should be loaded before the calling of func: EvaluateOneImage.");
- }
- Rect cropRect;
- if (isCropped)
- {
- cropRect = new Rect(0, 0, image.Width, image.Height);
- }
- else
- {
- if (!UsImageRegionSegHelper.CropWithCvCore(image, out cropRect))
- {
- NotifyLog?.Invoke(this, new LogEventArgs(EnumLogType.WarnLog, "Failed at UsImageRegionSegUtils.CropWithCvCore."));
- }
- }
- InferenceNetworkInputImage inferInput = new InferenceNetworkInputImage(image, cropRect);
- var inferResult = _inferNet.Process(inferInput);
- foreach (var detectedOb in inferResult)
- {
- var detectedObTrans = (DetectedOrgan)detectedOb;
- // 考虑到一幅图上同一个脏器,可能被分到多个detectedOb里,这里要把同一个脏器的多个轮廓合并到一起
- // 如,肝脏,在同一个mask中被分成了两部分,将作为两个DetectedOrgan输出,虽然目前只允许面积最大的连通区域作为
- // 最终肝脏mask输出(这种情况下不会出现多个同为肝脏的DetectedOrgan),
- // 但是,程序上先兼容同一个脏器被分成多个DetectedOrgan的情况,以免影响后续功能扩展
- var organExistIndex = detectedOrgansPerImg.FindIndex(x => x.Organ == detectedObTrans.Organ);
- if (organExistIndex != -1)
- {
- detectedOrgansPerImg[organExistIndex].AddContours(detectedObTrans.Confidence,
- detectedObTrans.BoundingBox, detectedObTrans.Contours);
- }
- else
- {
- detectedOrgansPerImg.Add(detectedObTrans);
- }
- }
- return detectedOrgansPerImg;
- }
- /// <summary>
- /// 主动销毁
- /// </summary>
- public void Dispose()
- {
- DoDispose();
- GC.SuppressFinalize(this);
- LogHelper.InfoLog("UsImageAnalyser.Disposed manually.", string.Empty);
- }
- /// <summary>
- /// 析构
- /// </summary>
- ~OrganSegProcess()
- {
- DoDispose();
- LogHelper.InfoLog("UsImageAnalyser.Disposed by destructor.", string.Empty);
- }
- #endregion
- #region private funcs
- private void OnInferNetLogWrite(object sender, LogEventArgs e)
- {
- NotifyLog?.Invoke(this, e);
- }
- private void DoDispose()
- {
- if (_inferNet != null)
- {
- _inferNet?.Dispose();
- _inferNet = null;
- }
- }
- #endregion
- }
- }
|