|
@@ -9,6 +9,10 @@ using Emgu.CV.Util;
|
|
|
using WingAIDiagnosisService.Carotid.Utilities.CntkSeg;
|
|
|
using WingServerCommon.Log;
|
|
|
using WingAIDiagnosisService.Carotid.MathTools;
|
|
|
+using AI.DiagSystem;
|
|
|
+using AI.Common;
|
|
|
+using System.IO;
|
|
|
+using AI.Common.Log;
|
|
|
|
|
|
namespace WingAIDiagnosisService.Carotid.Utilities
|
|
|
{
|
|
@@ -93,61 +97,104 @@ namespace WingAIDiagnosisService.Carotid.Utilities
|
|
|
|
|
|
public class GetModelVesselAndPlaque : IDisposable
|
|
|
{
|
|
|
- private int _batchImageSize;
|
|
|
|
|
|
- private bool _isInitializationSuccess = false;
|
|
|
+ #region private variable
|
|
|
|
|
|
+ private AIDiagSystem _diagSystem;
|
|
|
private static GetModelVesselAndPlaque _instance;
|
|
|
+ private bool _isInitializationSuccess = false;
|
|
|
+ private ModelSize _modelSize = new ModelSize();
|
|
|
+ private List<OneImageArteryContours> _allArteryContours = new List<OneImageArteryContours>();
|
|
|
+ private List<OnePlaqueContours> _allPlaqueContours = new List<OnePlaqueContours>();
|
|
|
+ private static readonly object _locker = new object();
|
|
|
+ private RawImage _image = new RawImage(EnumColorType.Gray8);
|
|
|
+
|
|
|
+ #endregion
|
|
|
+
|
|
|
+
|
|
|
+ #region public funcs
|
|
|
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
public static GetModelVesselAndPlaque Instance
|
|
|
{
|
|
|
get => _instance ?? (_instance = new GetModelVesselAndPlaque());
|
|
|
}
|
|
|
|
|
|
- private CntkDetect _arteryDetect = new CntkDetect();
|
|
|
-
|
|
|
- private CntkDetect _plaqueDetect = new CntkDetect();
|
|
|
-
|
|
|
- private ModelSize _modelSize = new ModelSize();
|
|
|
-
|
|
|
- private List<OneImageArteryContours> _allArteryContours = new List<OneImageArteryContours>();
|
|
|
-
|
|
|
- private List<OnePlaqueContours> _allPlaqueContours = new List<OnePlaqueContours>();
|
|
|
-
|
|
|
- private static readonly object _locker = new object();
|
|
|
-
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
public bool InitializationStatus()
|
|
|
{
|
|
|
return _isInitializationSuccess;
|
|
|
}
|
|
|
|
|
|
- public bool Initialization(string modelArtery, string modelPlaque)
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ public bool Initialization(EnumPerformance performance, string modelFolder)
|
|
|
{
|
|
|
- _batchImageSize = 8;
|
|
|
- if (!_arteryDetect.Initialization(modelArtery, 1))
|
|
|
- {
|
|
|
- Logger.WriteLineError($"GetModelVesselAndPlaque Initialization artery model fail," + modelArtery);
|
|
|
- return false;
|
|
|
- }
|
|
|
- if (!_plaqueDetect.Initialization(modelPlaque, 1))
|
|
|
- {
|
|
|
- Logger.WriteLineError($"GetModelVesselAndPlaque Initialization plaque model fail," + modelArtery);
|
|
|
- return false;
|
|
|
- }
|
|
|
+ _diagSystem = new AIDiagSystem(performance, modelFolder, EnumInferWorkName.CarotidArteryPlaque, isCropped: true);
|
|
|
+ _diagSystem.EnableDebugImageWrite = true;
|
|
|
+ _diagSystem.NotifyError += AIdiagSystem_NotifyError;
|
|
|
+ _diagSystem.NotifyLog += AIdiagSystem_NotifyLog;
|
|
|
_isInitializationSuccess = true;
|
|
|
return true;
|
|
|
}
|
|
|
|
|
|
+ private void AIdiagSystem_NotifyError(object sender, ErrorEventArgs e)
|
|
|
+ {
|
|
|
+ Logger.WriteLineError("AIdiagSystem_NotifyError:" + e.GetException());
|
|
|
+ }
|
|
|
+
|
|
|
+ private void AIdiagSystem_NotifyLog(object sender, LogEventArgs e)
|
|
|
+ {
|
|
|
+ if (e != null && !string.IsNullOrEmpty(e.Msg))
|
|
|
+ {
|
|
|
+ switch (e.LogType)
|
|
|
+ {
|
|
|
+ case EnumLogType.InfoLog:
|
|
|
+ Logger.WriteLineInfo($"AIdiagSystem_NotifyLog:{e.Msg}");
|
|
|
+ break;
|
|
|
+ case EnumLogType.ErrorLog:
|
|
|
+ Logger.WriteLineError($"AIdiagSystem_NotifyLog:{e.Msg}");
|
|
|
+ break;
|
|
|
+ case EnumLogType.WarnLog:
|
|
|
+ Logger.WriteLineWarn($"AIdiagSystem_NotifyLog:{e.Msg}");
|
|
|
+ break;
|
|
|
+ case EnumLogType.FatalLog:
|
|
|
+ Logger.WriteLineError($"AIdiagSystem_NotifyLog:{e.Msg}");
|
|
|
+ break;
|
|
|
+ default:
|
|
|
+ Logger.WriteLineInfo(e.Msg);
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
public List<OnePlaqueContours> GetAllPlaqueContours()
|
|
|
{
|
|
|
return _allPlaqueContours;
|
|
|
}
|
|
|
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
public List<OneImageArteryContours> GetIntimaVessel()
|
|
|
{
|
|
|
- lock (_locker)
|
|
|
+ try
|
|
|
{
|
|
|
- try
|
|
|
+ lock (_locker)
|
|
|
{
|
|
|
var count = _allArteryContours.Count;
|
|
|
if (count == 0)
|
|
@@ -168,14 +215,13 @@ namespace WingAIDiagnosisService.Carotid.Utilities
|
|
|
arteryContoursList1.Add(_allArteryContours[i]);
|
|
|
if (_allArteryContours[i].SerialNumber > maxIndex) break;
|
|
|
}
|
|
|
-
|
|
|
return arteryContoursList1;
|
|
|
}
|
|
|
- catch (Exception e)
|
|
|
- {
|
|
|
- Logger.WriteLineError($"GetModelVesselAndPlaque GetIntimaVessel have an error{e}");
|
|
|
- return new List<OneImageArteryContours>();
|
|
|
- }
|
|
|
+ }
|
|
|
+ catch (Exception e)
|
|
|
+ {
|
|
|
+ Logger.WriteLineError($"GetModelVesselAndPlaque GetIntimaVessel have an error{e}");
|
|
|
+ return new List<OneImageArteryContours>();
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -188,21 +234,27 @@ namespace WingAIDiagnosisService.Carotid.Utilities
|
|
|
int count = 0;
|
|
|
int sumTopY = 0;
|
|
|
int sumBottomY = 0;
|
|
|
- foreach (var countour in _allArteryContours)
|
|
|
+ lock (_locker)
|
|
|
{
|
|
|
- if (countour.ArteryContours.Count > 0)
|
|
|
+ foreach (var countour in _allArteryContours)
|
|
|
{
|
|
|
- count++;
|
|
|
- sumTopY += countour.ArteryContours[0].Rect.Top;
|
|
|
- sumBottomY += countour.ArteryContours[0].Rect.Bottom;
|
|
|
+ if (countour.ArteryContours.Count > 0)
|
|
|
+ {
|
|
|
+ count++;
|
|
|
+ sumTopY += countour.ArteryContours[0].Rect.Top;
|
|
|
+ sumBottomY += countour.ArteryContours[0].Rect.Bottom;
|
|
|
+ }
|
|
|
}
|
|
|
}
|
|
|
-
|
|
|
int avgTopY = sumTopY / count;
|
|
|
int avgBottomY = sumBottomY / count;
|
|
|
return new VesselYEdge { AvgTop = avgTopY, AvgBottom = avgBottomY };
|
|
|
}
|
|
|
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
public List<OneImageArteryContours> GetYBeginVessel()
|
|
|
{
|
|
|
lock (_locker)
|
|
@@ -229,6 +281,10 @@ namespace WingAIDiagnosisService.Carotid.Utilities
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
public List<OneImageArteryContours> GetYEndVessel()
|
|
|
{
|
|
|
lock (_locker)
|
|
@@ -251,27 +307,87 @@ namespace WingAIDiagnosisService.Carotid.Utilities
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
public bool DoDetect(byte[][] modelSource, ModelSize modelSize)
|
|
|
{
|
|
|
_modelSize = modelSize;
|
|
|
- lock (_locker)
|
|
|
- {
|
|
|
- _allArteryContours.Clear();
|
|
|
- _allPlaqueContours.Clear();
|
|
|
- }
|
|
|
+ _image = RawImage.ReadRawImageFromFile(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "80d9c34c23d943cea6206d1a6a128d83-142.txt"));
|
|
|
+ var diagResult2 = _diagSystem.EvaluateOneImage(_image);
|
|
|
+ Logger.WriteLineInfo($"{Newtonsoft.Json.JsonConvert.SerializeObject(diagResult2)}");
|
|
|
+
|
|
|
try
|
|
|
{
|
|
|
-
|
|
|
- var arteryImageList = DetectArterys(modelSource);
|
|
|
- if (arteryImageList.Count < 1)
|
|
|
+ var vesselList = new List<OneImageArteryContours>();
|
|
|
+ var plaqueList = new List<OnePlaqueContours>();
|
|
|
+
|
|
|
+ int modelImgCount = _modelSize.ModelLengthZ;
|
|
|
+ int interval = 1;
|
|
|
+ for (int ni = 0; ni < modelImgCount; ni += interval)
|
|
|
{
|
|
|
- return false;
|
|
|
+
|
|
|
+ _image.CopyFrom(modelSource[ni], _modelSize.ModelLengthX, _modelSize.ModelLengthY);
|
|
|
+
|
|
|
+ var diagResult = _diagSystem.EvaluateOneImage(_image);
|
|
|
+ if (diagResult == null)
|
|
|
+ {
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+
|
|
|
+ List<CntkDetectResult> detectedArtery = new List<CntkDetectResult>();
|
|
|
+ foreach (var organ in diagResult.DiagResultsForEachOrgan)
|
|
|
+ {
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ if (organ.Organ == EnumOrgans.CarotidArtery && organ.OrganContours?.Length == 1)
|
|
|
+ {
|
|
|
+
|
|
|
+
|
|
|
+ var oneArtery = GenCntkDetectResult(0.8f, CntkLabelType.LabelOne, organ.OrganBoundBox,
|
|
|
+ organ.OrganContours[0]);
|
|
|
+
|
|
|
+ detectedArtery.Add(oneArtery);
|
|
|
+
|
|
|
+
|
|
|
+ foreach (var detectedObject in organ.DetectedObjects)
|
|
|
+ {
|
|
|
+ var onePlaque = GenCntkDetectResult(detectedObject.Confidence, CntkLabelType.LabelOne,
|
|
|
+ detectedObject.BoundingBox, detectedObject.Contours[0]);
|
|
|
+ OnePlaqueContours onePlaqueContours = new OnePlaqueContours();
|
|
|
+ onePlaqueContours.ArteryContour = oneArtery.Contour;
|
|
|
+ onePlaqueContours.ImageRect = GetExtendRect(oneArtery.Rect, new Size(_image.Width, _image.Height));
|
|
|
+ onePlaqueContours.PlaqueContour = onePlaque.Contour;
|
|
|
+ onePlaqueContours.Credibility = onePlaque.Credibility;
|
|
|
+ onePlaqueContours.SerialNumber = ni;
|
|
|
+ onePlaqueContours.PlaqueArea = GetArea(onePlaque.Contour);
|
|
|
+ plaqueList.Add(onePlaqueContours);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ if (detectedArtery.Count > 0)
|
|
|
+ {
|
|
|
+ vesselList.Add(new OneImageArteryContours(ni, detectedArtery));
|
|
|
+ }
|
|
|
}
|
|
|
+
|
|
|
+ var selectedPlaqueList = RemoveAbnormalImage(vesselList, plaqueList);
|
|
|
|
|
|
-
|
|
|
- _allPlaqueContours = GetAllPlaqueContours(arteryImageList);
|
|
|
-
|
|
|
- DisposeImage(arteryImageList);
|
|
|
+
|
|
|
+ lock (_locker)
|
|
|
+ {
|
|
|
+ _allArteryContours = vesselList;
|
|
|
+ if (_allArteryContours.Count == 0)
|
|
|
+ {
|
|
|
+ Logger.WriteLineWarn($"GetModelVesselAndPlaque DetectArtery get zero artery contours.");
|
|
|
+ }
|
|
|
+ _allPlaqueContours = selectedPlaqueList;
|
|
|
+ }
|
|
|
return true;
|
|
|
}
|
|
|
catch (Exception e)
|
|
@@ -281,32 +397,99 @@ namespace WingAIDiagnosisService.Carotid.Utilities
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- private void DisposeImage(List<ArteryImage> arteryImageList)
|
|
|
+
|
|
|
+
|
|
|
+
|
|
|
+ public void Dispose()
|
|
|
{
|
|
|
- var count = arteryImageList.Count;
|
|
|
- for (var i = 0; i < count; ++i)
|
|
|
+ _diagSystem.Dispose();
|
|
|
+ _diagSystem = null;
|
|
|
+ _instance = null;
|
|
|
+ }
|
|
|
+
|
|
|
+ #endregion
|
|
|
+
|
|
|
+
|
|
|
+ #region private funcs
|
|
|
+
|
|
|
+ private CntkDetectResult GenCntkDetectResult(float confidence, CntkLabelType label, Rect boundingBox, Point2D[] contour)
|
|
|
+ {
|
|
|
+ CntkDetectResult result = new CntkDetectResult();
|
|
|
+ result.Credibility = confidence;
|
|
|
+ result.LabelType = label;
|
|
|
+ result.Rect = new Rectangle(boundingBox.Left, boundingBox.Top,
|
|
|
+ boundingBox.Width, boundingBox.Height);
|
|
|
+ int contourLen = contour.Length;
|
|
|
+ Point[] contourDst = new Point[contourLen];
|
|
|
+ for (int ki = 0; ki < contourLen; ki++)
|
|
|
{
|
|
|
- arteryImageList[i].Image?.Dispose();
|
|
|
+ contourDst[ki].X = contour[ki].X;
|
|
|
+ contourDst[ki].Y = contour[ki].Y;
|
|
|
}
|
|
|
+ result.Contour = contourDst;
|
|
|
+
|
|
|
+ result.ContourArea = (float)CvInvoke.ContourArea(new VectorOfPoint(contourDst));
|
|
|
+ return result;
|
|
|
+ }
|
|
|
+
|
|
|
+ private Rectangle GetExtendRect(Rectangle rect1, Size imageSize)
|
|
|
+ {
|
|
|
+ var change = 20;
|
|
|
+ var left = Math.Max(0, rect1.Left - change);
|
|
|
+ var top = Math.Max(0, rect1.Top - change);
|
|
|
+ var endW = Math.Min(left + rect1.Width + 2 * change, imageSize.Width - 1);
|
|
|
+ var endH = Math.Min(top + rect1.Height + 2 * change, imageSize.Height - 1);
|
|
|
+ return new Rectangle(left, top, endW - left, endH - top);
|
|
|
+ }
|
|
|
+
|
|
|
+ private double GetArea(Point[] points)
|
|
|
+ {
|
|
|
+ var vector = new VectorOfPoint(points);
|
|
|
+ return CvInvoke.ContourArea(vector);
|
|
|
}
|
|
|
|
|
|
- private List<ArteryImage> RemoveAbnormalImage(List<ArteryImage> allArteryImage)
|
|
|
+ private List<OnePlaqueContours> RemoveAbnormalImage(List<OneImageArteryContours> vesselList, List<OnePlaqueContours> plaqueList)
|
|
|
{
|
|
|
-
|
|
|
- var count = allArteryImage.Count;
|
|
|
+ if (plaqueList.Count <= 0)
|
|
|
+ {
|
|
|
+ return plaqueList;
|
|
|
+ }
|
|
|
+
|
|
|
+ var count = vesselList.Count;
|
|
|
if (count < 10)
|
|
|
{
|
|
|
- return allArteryImage;
|
|
|
+ return plaqueList;
|
|
|
}
|
|
|
-
|
|
|
+
|
|
|
List<Point> points = new List<Point>();
|
|
|
for (var i = 0; i < count; ++i)
|
|
|
{
|
|
|
- var x = allArteryImage[i].RectCenterPoint.X;
|
|
|
- var y = allArteryImage[i].RectCenterPoint.Y;
|
|
|
+
|
|
|
+ int left = 0, top = 0, right = 0, bottom = 0;
|
|
|
+ var arterys = vesselList[i].ArteryContours;
|
|
|
+ for (int ni = 0; ni < arterys.Count; ni++)
|
|
|
+ {
|
|
|
+ if (ni == 0)
|
|
|
+ {
|
|
|
+ left = arterys[ni].Rect.Left;
|
|
|
+ top = arterys[ni].Rect.Top;
|
|
|
+ right = arterys[ni].Rect.Right;
|
|
|
+ bottom = arterys[ni].Rect.Bottom;
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ left = Math.Min(left, arterys[ni].Rect.Left);
|
|
|
+ top = Math.Min(top, arterys[ni].Rect.Top);
|
|
|
+ right = Math.Max(right, arterys[ni].Rect.Right);
|
|
|
+ bottom = Math.Max(bottom, arterys[ni].Rect.Bottom);
|
|
|
+ }
|
|
|
+ }
|
|
|
+ var x = (left + right) / 2;
|
|
|
+ var y = (top + bottom) / 2;
|
|
|
points.Add(new Point(x, y));
|
|
|
}
|
|
|
|
|
|
+
|
|
|
var line = MathTools2D.CalculateFittedLine(points);
|
|
|
var pointDiff = new LineFittingError[count];
|
|
|
|
|
@@ -315,17 +498,17 @@ namespace WingAIDiagnosisService.Carotid.Utilities
|
|
|
for (var i = 0; i < count; ++i)
|
|
|
{
|
|
|
|
|
|
- double diff = MathTools2D.GetDistaceBetweenPointAndLine(line, allArteryImage[i].RectCenterPoint);
|
|
|
+ double diff = MathTools2D.GetDistaceBetweenPointAndLine(line, points[i]);
|
|
|
sumDiff += diff;
|
|
|
pointDiff[i] = new LineFittingError()
|
|
|
{
|
|
|
SerialNumber = i,
|
|
|
- OriginalPoint = allArteryImage[i].RectCenterPoint,
|
|
|
+ OriginalPoint = points[i],
|
|
|
DiffValue = diff
|
|
|
};
|
|
|
}
|
|
|
|
|
|
- var averageDiff = sumDiff / allArteryImage.Count;
|
|
|
+ var averageDiff = sumDiff / count;
|
|
|
double sumStd = 0;
|
|
|
for (var i = 0; i < count; ++i)
|
|
|
{
|
|
@@ -337,11 +520,17 @@ namespace WingAIDiagnosisService.Carotid.Utilities
|
|
|
var minDiff = averageDiff - 3 * sumStd;
|
|
|
var maxDiff = averageDiff + 3 * sumStd;
|
|
|
|
|
|
+ List<int> removeFlag = new List<int>();
|
|
|
for (var i = 0; i < count; ++i)
|
|
|
{
|
|
|
var diff = pointDiff[i].DiffValue;
|
|
|
if (diff < minDiff || diff > maxDiff)
|
|
|
{
|
|
|
+ int serialNumber = vesselList[i].SerialNumber;
|
|
|
+ if (!removeFlag.Contains(serialNumber))
|
|
|
+ {
|
|
|
+ removeFlag.Add(serialNumber);
|
|
|
+ }
|
|
|
pointDiff[i].DiffValue = -100000;
|
|
|
}
|
|
|
}
|
|
@@ -350,282 +539,31 @@ namespace WingAIDiagnosisService.Carotid.Utilities
|
|
|
var diffList = pointDiff.ToList().OrderByDescending(o => o.DiffValue);
|
|
|
var diffList1 = diffList.Skip(count1).ToList();
|
|
|
var maxDiffValue = diffList1[0].DiffValue;
|
|
|
-
|
|
|
- var arteryImageList = new List<ArteryImage>();
|
|
|
- for (var i = 0; i < allArteryImage.Count; ++i)
|
|
|
- {
|
|
|
-
|
|
|
- if (pointDiff[i].DiffValue != -100000)
|
|
|
- {
|
|
|
- if (pointDiff[i].DiffValue <= maxDiffValue)
|
|
|
- {
|
|
|
- arteryImageList.Add(allArteryImage[i]);
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- allArteryImage[i].Image?.Dispose();
|
|
|
- }
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- allArteryImage[i].Image?.Dispose();
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- return arteryImageList;
|
|
|
- }
|
|
|
-
|
|
|
- private List<OnePlaqueContours> GetAllPlaqueContours(List<ArteryImage> allArteryImage)
|
|
|
- {
|
|
|
- try
|
|
|
+ for (var i = 0; i < count; ++i)
|
|
|
{
|
|
|
-
|
|
|
- allArteryImage = RemoveAbnormalImage(allArteryImage);
|
|
|
- int count = allArteryImage.Count;
|
|
|
- List<OnePlaqueContours> allPlaquecontours = new List<OnePlaqueContours>();
|
|
|
- var images = new Image<Gray, byte>[_batchImageSize];
|
|
|
- var imagesDetect = new List<Image<Gray, byte>>();
|
|
|
- var detectNum = _batchImageSize;
|
|
|
- var detectResultList = new List<List<CntkDetectResult>>();
|
|
|
- for (var i = 0; i < count; i += _batchImageSize)
|
|
|
+ if (pointDiff[i].DiffValue > maxDiffValue)
|
|
|
{
|
|
|
- if (i + _batchImageSize > count)
|
|
|
- {
|
|
|
- detectNum = count - i;
|
|
|
- }
|
|
|
- for (var j = 0; j < detectNum; ++j)
|
|
|
- {
|
|
|
- images[j] = allArteryImage[i + j].Image;
|
|
|
- }
|
|
|
- detectResultList.Clear();
|
|
|
- if (detectNum == images.Length)
|
|
|
- {
|
|
|
- detectResultList = _plaqueDetect.DetectImage(images);
|
|
|
- }
|
|
|
- else
|
|
|
+ int serialNumber = vesselList[i].SerialNumber;
|
|
|
+ if (!removeFlag.Contains(serialNumber))
|
|
|
{
|
|
|
- detectResultList = _plaqueDetect.DetectImage(images.Take(detectNum).ToArray());
|
|
|
- }
|
|
|
- if (detectResultList.Count == 0)
|
|
|
- {
|
|
|
- continue;
|
|
|
- }
|
|
|
-
|
|
|
- for (var z = 0; z < detectNum; z++)
|
|
|
- {
|
|
|
- var arteryImage = allArteryImage[z + i];
|
|
|
- var detectResultTemp = detectResultList[z];
|
|
|
- if (detectResultTemp.Count == 0) continue;
|
|
|
-
|
|
|
- List<CntkDetectResult> plaqueDetectResult = new List<CntkDetectResult>();
|
|
|
-
|
|
|
- for (var j = 0; j < detectResultTemp.Count; ++j)
|
|
|
- {
|
|
|
- if (detectResultTemp[j].LabelType == CntkLabelType.LabelOne)
|
|
|
- {
|
|
|
- plaqueDetectResult.Add(detectResultTemp[j]);
|
|
|
- }
|
|
|
-
|
|
|
- }
|
|
|
- if (plaqueDetectResult.Count > 0)
|
|
|
- {
|
|
|
- for (var j = 0; j < plaqueDetectResult.Count; j++)
|
|
|
- {
|
|
|
- var plaquePoint = plaqueDetectResult[j].Contour;
|
|
|
- if (IsInContour(arteryImage.ArteryContour, plaquePoint))
|
|
|
- {
|
|
|
- OnePlaqueContours onePlaqueContours = new OnePlaqueContours();
|
|
|
-
|
|
|
- onePlaqueContours.ArteryContour = arteryImage.ArteryContour;
|
|
|
- onePlaqueContours.ImageRect = arteryImage.Rect;
|
|
|
- onePlaqueContours.PlaqueContour = plaqueDetectResult[j].Contour;
|
|
|
- onePlaqueContours.Credibility = plaqueDetectResult[j].Credibility;
|
|
|
- onePlaqueContours.SerialNumber = arteryImage.SerialNumber;
|
|
|
- onePlaqueContours.PlaqueArea = GetArea(onePlaqueContours.PlaqueContour);
|
|
|
- allPlaquecontours.Add(onePlaqueContours);
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
+ removeFlag.Add(serialNumber);
|
|
|
}
|
|
|
-
|
|
|
}
|
|
|
- for (var i = 0; i < images.Length; ++i)
|
|
|
- {
|
|
|
- images[i]?.Dispose();
|
|
|
- }
|
|
|
-
|
|
|
- return allPlaquecontours;
|
|
|
- }
|
|
|
- catch (Exception e)
|
|
|
- {
|
|
|
- Logger.WriteLineError($"GetModelVesselAndPlaque DoDetect have an error{e}");
|
|
|
- return new List<OnePlaqueContours>();
|
|
|
}
|
|
|
- }
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
- private List<ArteryImage> DetectArterys(byte[][] modelSource)
|
|
|
- {
|
|
|
- try
|
|
|
+ int plaqueCount = plaqueList.Count;
|
|
|
+ for (var i = plaqueCount - 1; i >= 0; i--)
|
|
|
{
|
|
|
- var arteryImageList = new List<ArteryImage>();
|
|
|
- var vesselList = new List<OneImageArteryContours>();
|
|
|
-
|
|
|
- int beginIndex = 0;
|
|
|
- int endIndex = _modelSize.ModelLengthZ;
|
|
|
-
|
|
|
- var interval = 3;
|
|
|
- var imageNums = new List<int>();
|
|
|
- for (var i = beginIndex; i < endIndex; i += interval)
|
|
|
- {
|
|
|
- imageNums.Add(i);
|
|
|
- }
|
|
|
-
|
|
|
- var images = new Image<Gray, byte>[_batchImageSize];
|
|
|
- for (var i = 0; i < _batchImageSize; i++)
|
|
|
- {
|
|
|
- images[i] = new Image<Gray, byte>(_modelSize.ModelLengthX, _modelSize.ModelLengthY);
|
|
|
- }
|
|
|
-
|
|
|
-
|
|
|
- var imageNumsCount = imageNums.Count;
|
|
|
- var detectNum = _batchImageSize;
|
|
|
- var detectResultList = new List<List<CntkDetectResult>>();
|
|
|
- for (var i = 0; i < imageNumsCount; i += _batchImageSize)
|
|
|
- {
|
|
|
-
|
|
|
- if (i + _batchImageSize > imageNumsCount)
|
|
|
- {
|
|
|
- detectNum = imageNumsCount - i;
|
|
|
- }
|
|
|
- for (var j = 0; j < detectNum; ++j)
|
|
|
- {
|
|
|
- Marshal.Copy(modelSource[imageNums[i + j]], 0, images[j].Mat.DataPointer, _modelSize.OneFacePixelsNum);
|
|
|
- }
|
|
|
- detectResultList.Clear();
|
|
|
- if (detectNum == images.Length)
|
|
|
- {
|
|
|
- detectResultList = _arteryDetect.DetectImage(images);
|
|
|
- }
|
|
|
- else
|
|
|
- {
|
|
|
- detectResultList = _arteryDetect.DetectImage(images.Take(detectNum).ToArray());
|
|
|
- }
|
|
|
- if (detectResultList.Count == 0)
|
|
|
- {
|
|
|
- continue;
|
|
|
- }
|
|
|
-
|
|
|
- if (detectResultList.Count < detectNum)
|
|
|
- {
|
|
|
- continue;
|
|
|
- }
|
|
|
- for (var z = 0; z < detectNum; ++z)
|
|
|
- {
|
|
|
- var serialNumber = imageNums[z + i];
|
|
|
- if (detectResultList[z].Count == 0)
|
|
|
- {
|
|
|
- continue;
|
|
|
- }
|
|
|
-
|
|
|
-
|
|
|
- var biggestContor = detectResultList[z][0];
|
|
|
-
|
|
|
- List<CntkDetectResult> arteryDetectResult = new List<CntkDetectResult>();
|
|
|
- if (biggestContor.LabelType == CntkLabelType.LabelOne)
|
|
|
- {
|
|
|
- if (biggestContor.Rect.Width < 50 || biggestContor.Rect.Height < 50)
|
|
|
- {
|
|
|
- continue;
|
|
|
- }
|
|
|
- arteryDetectResult.Add(biggestContor);
|
|
|
-
|
|
|
- var rect = GetExtendRect(biggestContor.Rect, images[z].Size);
|
|
|
- var arteryImage = images[z].Copy(rect);
|
|
|
- Point[] arteryContour = new Point[biggestContor.Contour.Length];
|
|
|
- biggestContor.Contour.CopyTo(arteryContour, 0);
|
|
|
- var oneArteryImage = new ArteryImage(serialNumber, arteryContour, arteryImage, rect);
|
|
|
-
|
|
|
- arteryImageList.Add(oneArteryImage);
|
|
|
- }
|
|
|
-
|
|
|
- if (arteryDetectResult.Count > 0)
|
|
|
- {
|
|
|
- vesselList.Add(new OneImageArteryContours(serialNumber, arteryDetectResult));
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- for (var i = 0; i < images.Length; ++i)
|
|
|
- {
|
|
|
- images[i]?.Dispose();
|
|
|
- }
|
|
|
-
|
|
|
- _allArteryContours = vesselList;
|
|
|
- if (_allArteryContours.Count == 0)
|
|
|
+ var serialNumber = plaqueList[i].SerialNumber;
|
|
|
+ if (removeFlag.Contains(serialNumber))
|
|
|
{
|
|
|
- Logger.WriteLineWarn($"GetModelVesselAndPlaque DetectArtery get zero artery contours.");
|
|
|
+ plaqueList.RemoveAt(i);
|
|
|
}
|
|
|
- return arteryImageList;
|
|
|
- }
|
|
|
- catch (Exception e)
|
|
|
- {
|
|
|
- Logger.WriteLineError($"GetModelVesselAndPlaque DetectArtery have an error{e}");
|
|
|
- return new List<ArteryImage>();
|
|
|
}
|
|
|
+ return plaqueList;
|
|
|
}
|
|
|
|
|
|
- private Rectangle GetExtendRect(Rectangle rect1, Size imageSize)
|
|
|
- {
|
|
|
- var change = 20;
|
|
|
- var left = Math.Max(0, rect1.Left - change);
|
|
|
- var top = Math.Max(0, rect1.Top - change);
|
|
|
- var endW = Math.Min(left + rect1.Width + 2 * change, imageSize.Width - 1);
|
|
|
- var endH = Math.Min(top + rect1.Height + 2 * change, imageSize.Height - 1);
|
|
|
- return new Rectangle(left, top, endW - left, endH - top);
|
|
|
- }
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
-
|
|
|
- private bool IsInContour(Point[] contourSource, Point[] contourDst)
|
|
|
- {
|
|
|
- if (contourDst.Length < 10)
|
|
|
- {
|
|
|
- return false;
|
|
|
- }
|
|
|
- var vector = new VectorOfPoint(contourSource);
|
|
|
- for (var i = 0; i < contourDst.Length; ++i)
|
|
|
- {
|
|
|
- var temp = CvInvoke.PointPolygonTest(vector, new PointF(contourDst[i].X, contourDst[i].Y), false);
|
|
|
- if (temp > 0)
|
|
|
- {
|
|
|
- return true;
|
|
|
- }
|
|
|
- }
|
|
|
- return false;
|
|
|
- }
|
|
|
|
|
|
- private double GetArea(Point[] points)
|
|
|
- {
|
|
|
- var vector = new VectorOfPoint(points);
|
|
|
- return CvInvoke.ContourArea(vector);
|
|
|
- }
|
|
|
+ #endregion
|
|
|
|
|
|
- public void Dispose()
|
|
|
- {
|
|
|
- _arteryDetect.Dispose();
|
|
|
- _plaqueDetect.Dispose();
|
|
|
- _arteryDetect = null;
|
|
|
- _plaqueDetect = null;
|
|
|
- _instance = null;
|
|
|
- }
|
|
|
}
|
|
|
}
|