Jeremy 2 years ago
parent
commit
a755f11274

BIN
AIDiagnosis/AI.Common.dll


BIN
AIDiagnosis/AI.DiagSystem.dll


BIN
AIDiagnosis/Cntk.Core.Managed-2.7.dll


+ 12 - 8
Carotid/ResampleModel.cs

@@ -17,6 +17,7 @@ using WingAIDiagnosisService.Carotid.CarotidInterFacesData;
 using WingServerCommon.Log;
 using Vinno.vCloud.Common.Vid2.Visuals;
 using System.Runtime.InteropServices;
+using AI.DiagSystem;
 
 namespace WingAIDiagnosisService.Carotid
 {
@@ -118,7 +119,7 @@ namespace WingAIDiagnosisService.Carotid
         /// 执行模型重采样的入口函数
         /// </summary>
         /// <returns></returns>
-        public ResampleResult Resample(VinnoImageData vinnoImageData, ResampleInputData inputData)
+        public ResampleResult Resample(VinnoImageData vinnoImageData, ResampleInputData inputData, EnumPerformance performance)
         {
             try
             {
@@ -158,13 +159,16 @@ namespace WingAIDiagnosisService.Carotid
                     isReadedModel = GetModelVesselAndPlaque.Instance.InitializationStatus();
                     if (isReadedModel == false)
                     {
-                        //Ai检测血管和斑块
-                        //读取模型文件
-                        string plaqueModelName = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Networks", "Carotid",
-                              Environment.OSVersion.Platform == PlatformID.Unix ? "PlaqueModel" : "PlaqueModel.emd");
-                        string arteryModelName = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Networks", "Carotid",
-                         Environment.OSVersion.Platform == PlatformID.Unix ? "ArteryModel" : "ArteryModel.emd");
-                        isReadedModel = GetModelVesselAndPlaque.Instance.Initialization(arteryModelName, plaqueModelName);
+
+                        GetModelVesselAndPlaque.Instance.Initialization(performance, Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Networks"));
+                        isReadedModel = true;
+                        // //Ai检测血管和斑块
+                        // //读取模型文件
+                        // string plaqueModelName = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Networks", "Carotid",
+                        //       Environment.OSVersion.Platform == PlatformID.Unix ? "PlaqueModel" : "PlaqueModel.emd");
+                        // string arteryModelName = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Networks", "Carotid",
+                        //  Environment.OSVersion.Platform == PlatformID.Unix ? "ArteryModel" : "ArteryModel.emd");
+                        // isReadedModel = GetModelVesselAndPlaque.Instance.Initialization(EnumPerformance.Medium, plaqueModelName);
                     }
 
                     List<Vector3D> points = new List<Vector3D>();

+ 1 - 1
Carotid/Utilities/CNTKUtility.cs

@@ -36,7 +36,7 @@ namespace WingAIDiagnosisService.Carotid.Utilities
                     break;
             }
 
-            CNTK.Utils.SetMaxNumCPUThreads(numWorker);
+            //CNTK.Utils.SetMaxNumCPUThreads(numWorker);
         }
     }
 }

+ 357 - 358
Carotid/Utilities/CntkSeg/CntkCpu.cs

@@ -1,6 +1,5 @@
 using System;
 using System.Collections.Generic;
-using CNTK;
 using Emgu.CV;
 using Emgu.CV.Structure;
 using System.Drawing;
@@ -34,361 +33,361 @@ namespace WingAIDiagnosisService.Carotid.Utilities.CntkSeg
         public Rectangle Rect;
     }
 
-    public class CntkCpu : IDisposable
-    {
-        private DeviceDescriptor _device;
-
-        private Function _cntkDetct = null;
-
-        //模型检测文件大小
-        private int _modelImageWidth = 256;
-        private int _modelImageHeight = 256;
-
-        //识别目标种类个数
-        private int _labelNum = 2;
-
-        private Variable _inputVar = null;
-        private Variable _outputVar = null;
-
-        private Image<Gray, float>[] _detectImages = null;
-        private Image<Gray, float>[] _resizedImages = null;
-        private Image<Gray, float>[][] _imageMarkList = null;
-        private Image<Gray, float> _imageBinarySmallFloat = null;
-        private Image<Gray, byte> _imageBinarySmall = null;
-        private Image<Gray, byte> _imageBinaryBig = null;
-
-
-        public void Dispose()
-        {
-            _cntkDetct?.Dispose();
-            _inputVar?.Dispose();
-            _outputVar?.Dispose();
-
-            if (_detectImages != null)
-            {
-                for (var i = 0; i < _detectImages.Length; ++i)
-                {
-                    _detectImages[i]?.Dispose();
-                }
-            }
-
-            if (_resizedImages != null)
-            {
-                for (var i = 0; i < _resizedImages.Length; ++i)
-                {
-                    _resizedImages[i]?.Dispose();
-                }
-            }
-
-            if (_imageMarkList != null)
-            {
-                for (var i = 0; i < _imageMarkList.Length; ++i)
-                {
-                    if (_imageMarkList[i] != null)
-                    {
-                        for (var j = 0; j < _imageMarkList[i].Length; ++i)
-                        {
-                            _imageMarkList[i][j]?.Dispose();
-                        }
-                    }
-                }
-            }
-
-            _imageBinarySmall?.Dispose();
-            _imageBinaryBig?.Dispose();
-
-            _cntkDetct = null;
-            _inputVar = null;
-            _outputVar = null;
-
-            _detectImages = null;
-            _resizedImages = null;
-            _imageMarkList = null;
-            _imageBinarySmallFloat = null;
-            _imageBinarySmall = null;
-            _imageBinaryBig = null;
-        }
-
-        public bool Initialization(byte[] modelData, int labelNum)
-        {
-            try
-            {
-                _cntkDetct?.Dispose();
-                _device = DeviceDescriptor.CPUDevice;
-                _cntkDetct = Function.Load(modelData, _device);
-                Logger.WriteLineInfo("function load success");
-
-                //获得模型检测尺寸
-                Variable inputVar = _cntkDetct.Arguments[0];
-                NDShape inputShape = inputVar.Shape;
-                _modelImageWidth = inputShape[0];
-                _modelImageHeight = inputShape[1];
-                _labelNum = labelNum;
-
-                // Get input variable. The model has only one single input.
-                // The same way described above for output variable can be used here to get input variable by name.
-                _inputVar = _cntkDetct.Arguments[0];
-
-                // The model has only one output.
-                // You can also use the following way to get output variable by name:
-                // Variable outputVar = modelFunc.Outputs.Where(variable => string.Equals(variable.Name, outputName)).Single();
-                _outputVar = _cntkDetct.Output;
-                // Create output data map. Using null as Value to indicate using system allocated memory.
-                // Alternatively, create a Value object and add it to the data map.
-
-                return true;
-            }
-            catch (Exception e)
-            {
-                Logger.WriteLineWarn($"CntkCpu Initialization have an error{e}");
-                return false;
-            }
-        }
-
-        /// <summary>
-        /// The example shows
-        /// - how to load model.
-        /// - how to prepare input data for a batch of samples.
-        /// - how to prepare input and output data map.
-        /// - how to evaluate a model.
-        /// - how to retrieve evaluation result and retrieve output data in dense format.
-        /// </summary>
-        /// <param name="device">Specify on which device to run the evaluation.</param>
-        public List<List<CntkDetectResult>> EvaluationBatchOfImages(Image<Gray, byte>[] images)
-        {
-            try
-            {
-                var imageCount = images.Length;
-                if (_detectImages == null)
-                {
-                    _detectImages = new Image<Gray, float>[imageCount];
-                    _resizedImages = new Image<Gray, float>[imageCount];
-                    _imageMarkList = new Image<Gray, float>[imageCount][];
-                    for (var i = 0; i < imageCount; ++i)
-                    {
-                        //有几个目标就新建几个图像
-                        _imageMarkList[i] = new Image<Gray, float>[_labelNum];
-                        for (int j = 0; j < _labelNum; j++)
-                        {
-                            _imageMarkList[i][j] = new Image<Gray, float>(_modelImageWidth, _modelImageHeight);
-                        }
-                    }
-
-                    _imageBinarySmallFloat = new Image<Gray, float>(_modelImageWidth, _modelImageHeight);
-                    _imageBinarySmall = new Image<Gray, byte>(_modelImageWidth, _modelImageHeight);
-                    _imageBinaryBig = new Image<Gray, byte>(images[0].Width, images[0].Height);
-                }
-
-                List<Size> imagesSize = new List<Size>();
-                List<Size> resizedImagesSize = new List<Size>();
-                var imageLength = _modelImageWidth * _modelImageHeight;
-                var seqData = new float[imageLength * imageCount];
-                for (int i = 0; i < imageCount; i++)
-                {
-                    _detectImages[i]?.Dispose();
-                    if (images[i] == null)
-                    {
-                        return new List<List<CntkDetectResult>>();
-                    }
-                    _detectImages[i] = images[i].Convert<Gray, float>();
-                    imagesSize.Add(_detectImages[i].Size);
-                    _resizedImages[i]?.Dispose();
-                    _resizedImages[i] = _detectImages[i].Resize(_modelImageWidth, _modelImageHeight, Emgu.CV.CvEnum.Inter.Linear);
-                    resizedImagesSize.Add(_resizedImages[i].Size);
-                    NormalizedImage(_resizedImages[i], seqData, i);
-                }
-                // Create Value for the batch data.
-                var inputVal = Value.CreateBatch(_inputVar.Shape, seqData, _device);
-                // Create input data map.
-                var inputDataMap = new Dictionary<Variable, Value>();
-                inputDataMap.Add(_inputVar, inputVal);
-
-                var outputDataMap = new Dictionary<Variable, Value>();
-                outputDataMap.Add(_outputVar, null);
-
-                // Evaluate the model against the batch input
-                _cntkDetct.Evaluate(inputDataMap, outputDataMap, _device);
-
-                // Retrieve the evaluation result.
-                var outputVal = outputDataMap[_outputVar];
-                var outputData = outputVal.GetDenseData<float>(_outputVar);
-
-                var result = ChangeToCntkResult(outputData, imageCount, _labelNum, resizedImagesSize, imagesSize);
-
-                #region 画出结果------------------------------------------
-                ////画出结果
-                //for (var i = 0; i < imageCount; ++i)
-                //{
-                //    var imageBgr = images[i].Convert<Bgr, byte>();
-                //    var bgr = new Bgr(0, 255, 255);
-                //    var bgr1 = new Bgr(0, 0, 255);
-                //    for (var j = 0; j < result[i].Count; ++j)
-                //    {
-                //        if (result[i][j].LabelType == CntkLabelType.LabelOne)
-                //        {
-                //            imageBgr.Draw(result[i][j].Contour, bgr, 2);
-                //        }
-                //        else
-                //        {
-                //            imageBgr.Draw(result[i][j].Contour, bgr1, 2);
-                //        }
-
-                //    }
-                //    imageBgr.Save(System.IO.Path.Combine(@"C:\carotid\test\detect result", i + ".jpg"));
-                //}
-                #endregion
-
-                return result;
-            }
-            catch (Exception e)
-            {
-                Logger.WriteLineError($"CntkCpu EvaluationBatchOfImages have a error{e}");
-                return new List<List<CntkDetectResult>>();
-            }
-        }
-
-        /// <summary>
-        /// 转换成结果
-        /// </summary>
-        /// <param name="outputData"></param>
-        /// <param name="imageNums"></param>
-        /// <param name="labelNum"></param>
-        /// <param name="resizedImageSize"></param>
-        /// <param name="imageSize"></param>
-        /// <returns></returns>
-        private List<List<CntkDetectResult>> ChangeToCntkResult(IList<IList<float>> outputData, int imageNums, int labelNum, List<Size> resizedImageSize, List<Size> imageSize)
-        {
-            List<List<CntkDetectResult>> detectResults = new List<List<CntkDetectResult>>();
-            try
-            {
-                for (var i = 0; i < imageNums; ++i)
-                {
-                    var dectectList = new List<CntkDetectResult>();
-                    int imageLength = resizedImageSize[i].Width * resizedImageSize[i].Height;
-                    var listFloat = outputData[i];
-                    if (listFloat.Count != (labelNum + 1) * imageLength)
-                    {
-                        Logger.WriteLineWarn("The number of detection targets and the number to be detected are different!");
-                        return new List<List<CntkDetectResult>>();
-                    }
-
-                    for (int j = 0; j < labelNum; j++)
-                    {
-                        var oenImageOutData = outputData[i].ToArray();
-                        //j+1是因为要跳过结果中添加的背景
-                        Marshal.Copy(oenImageOutData, imageLength * (j + 1), _imageMarkList[i][j].Mat.DataPointer, imageLength);
-                        dectectList.AddRange(GetDetectResult(_imageMarkList[i][j], 0.8f, j, imageSize[i]));
-                    }
-                    detectResults.Add(dectectList);
-                }
-                return detectResults;
-            }
-            catch (Exception e)
-            {
-                Logger.WriteLineError($"CntkCpu ChangeToCntkResult have a error{e}");
-                return detectResults;
-            }
-        }
-
-        private List<CntkDetectResult> GetDetectResult(Image<Gray, float> image, float threshold, int labelNum, Size imageSize)
-        {
-            try
-            {
-                //计算连通域,获得轮廓
-                CvInvoke.Threshold(image, _imageBinarySmallFloat, threshold, 255, ThresholdType.Binary);
-                _imageBinarySmall = _imageBinarySmallFloat.Convert<Gray, byte>();
-                //原图像尺寸的轮廓二值化图像              
-                var contoursSmall = new VectorOfVectorOfPoint();
-                CvInvoke.FindContours(_imageBinarySmall, contoursSmall, null, RetrType.Tree, ChainApproxMethod.ChainApproxNone);
-
-                var detectResultList = new List<CntkDetectResult>();
-                for (var n = 0; n < contoursSmall.Size; ++n)
-                {
-                    if (contoursSmall[n] != null)
-                    {
-                        var contoursBig = GetContourBig(contoursSmall[n].ToArray(), imageSize);
-                        var cntkResult = new CntkDetectResult();
-                        cntkResult.Rect = CvInvoke.BoundingRectangle(new VectorOfPoint(contoursBig));
-                        cntkResult.Credibility = GetImageMean(image, contoursSmall[n], threshold);
-                        cntkResult.Contour = contoursBig;
-                        cntkResult.ContourArea = (float)CvInvoke.ContourArea(new VectorOfPoint(contoursBig));
-                        cntkResult.LabelType = labelNum + 1 > 1 ? CntkLabelType.LabelTwo : CntkLabelType.LabelOne;
-                        detectResultList.Add(cntkResult);
-                    }
-                }
-                detectResultList = detectResultList.OrderByDescending(o => o.ContourArea).ToList();
-                return detectResultList;
-            }
-            catch (Exception e)
-            {
-                Logger.WriteLineError($"CntkCpu GetDetectResult have a error{e}");
-                return new List<CntkDetectResult>();
-            }
-        }
-
-        private Point[] GetContourBig(Point[] smallContourPoints, Size imageSize)
-        {
-            var wRatio = imageSize.Width / (float)_modelImageWidth;
-            var hRatio = imageSize.Height / (float)_modelImageHeight;
-
-            var pointList = new List<Point>();
-            for (var i = 0; i < smallContourPoints.Length; ++i)
-            {
-                var x = smallContourPoints[i].X * wRatio;
-                var y = smallContourPoints[i].Y * hRatio;
-
-                var xx = Math.Min(x, imageSize.Width - 1);
-                var yy = Math.Min(y, imageSize.Height - 1);
-                pointList.Add(new Point((int)Math.Round(xx, 0, MidpointRounding.AwayFromZero),
-                                                 (int)Math.Round(yy, 0, MidpointRounding.AwayFromZero)));
-
-            }
-            return pointList.Distinct().ToArray();
-        }
-
-        private float GetImageMean(Image<Gray, float> image, VectorOfPoint contour, float threshold)
-        {
-            var rect = CvInvoke.BoundingRectangle(contour);
-            var minW = rect.Left;
-            var maxW = rect.Left + rect.Width;
-            var minH = rect.Top;
-            var maxH = rect.Top + rect.Height;
-            float sum = 0;
-            int num = 0;
-            for (var h = minH; h < maxH; h++)
-            {
-                for (var w = minW; w < maxW; w++)
-                {
-                    if (image.Data[h, w, 0] > threshold)
-                    {
-                        sum += image.Data[h, w, 0];
-                        num++;
-                    }
-                }
-            }
-            if (num > 0)
-            {
-                return sum / num;
-            }
-            else
-            {
-                return 0;
-            }
-        }
-
-        /// <summary>
-        /// 归一化图像数据
-        /// </summary>
-        /// <param name="image"></param>
-        /// <returns></returns>
-        private void NormalizedImage(Image<Gray, float> image, float[] imageData, int index)
-        {
-            //求平均这和标注差
-            var imageLenght = image.Width * image.Height;
-            using Image<Gray, float> imageNormalize = new Image<Gray, float>(image.Width, image.Height);
-            CvInvoke.Normalize(image, imageNormalize, 0, 1, Emgu.CV.CvEnum.NormType.MinMax);
-            Marshal.Copy(imageNormalize.Mat.DataPointer, imageData, imageLenght * index, imageLenght);
-        }
-
-    }
+    // public class CntkCpu : IDisposable
+    // {
+    //     private DeviceDescriptor _device;
+
+    //     private Function _cntkDetct = null;
+
+    //     //模型检测文件大小
+    //     private int _modelImageWidth = 256;
+    //     private int _modelImageHeight = 256;
+
+    //     //识别目标种类个数
+    //     private int _labelNum = 2;
+
+    //     private Variable _inputVar = null;
+    //     private Variable _outputVar = null;
+
+    //     private Image<Gray, float>[] _detectImages = null;
+    //     private Image<Gray, float>[] _resizedImages = null;
+    //     private Image<Gray, float>[][] _imageMarkList = null;
+    //     private Image<Gray, float> _imageBinarySmallFloat = null;
+    //     private Image<Gray, byte> _imageBinarySmall = null;
+    //     private Image<Gray, byte> _imageBinaryBig = null;
+
+
+    //     public void Dispose()
+    //     {
+    //         _cntkDetct?.Dispose();
+    //         _inputVar?.Dispose();
+    //         _outputVar?.Dispose();
+
+    //         if (_detectImages != null)
+    //         {
+    //             for (var i = 0; i < _detectImages.Length; ++i)
+    //             {
+    //                 _detectImages[i]?.Dispose();
+    //             }
+    //         }
+
+    //         if (_resizedImages != null)
+    //         {
+    //             for (var i = 0; i < _resizedImages.Length; ++i)
+    //             {
+    //                 _resizedImages[i]?.Dispose();
+    //             }
+    //         }
+
+    //         if (_imageMarkList != null)
+    //         {
+    //             for (var i = 0; i < _imageMarkList.Length; ++i)
+    //             {
+    //                 if (_imageMarkList[i] != null)
+    //                 {
+    //                     for (var j = 0; j < _imageMarkList[i].Length; ++i)
+    //                     {
+    //                         _imageMarkList[i][j]?.Dispose();
+    //                     }
+    //                 }
+    //             }
+    //         }
+
+    //         _imageBinarySmall?.Dispose();
+    //         _imageBinaryBig?.Dispose();
+
+    //         _cntkDetct = null;
+    //         _inputVar = null;
+    //         _outputVar = null;
+
+    //         _detectImages = null;
+    //         _resizedImages = null;
+    //         _imageMarkList = null;
+    //         _imageBinarySmallFloat = null;
+    //         _imageBinarySmall = null;
+    //         _imageBinaryBig = null;
+    //     }
+
+    //     public bool Initialization(byte[] modelData, int labelNum)
+    //     {
+    //         try
+    //         {
+    //             _cntkDetct?.Dispose();
+    //             _device = DeviceDescriptor.CPUDevice;
+    //             _cntkDetct = Function.Load(modelData, _device);
+    //             Logger.WriteLineInfo("function load success");
+
+    //             //获得模型检测尺寸
+    //             Variable inputVar = _cntkDetct.Arguments[0];
+    //             NDShape inputShape = inputVar.Shape;
+    //             _modelImageWidth = inputShape[0];
+    //             _modelImageHeight = inputShape[1];
+    //             _labelNum = labelNum;
+
+    //             // Get input variable. The model has only one single input.
+    //             // The same way described above for output variable can be used here to get input variable by name.
+    //             _inputVar = _cntkDetct.Arguments[0];
+
+    //             // The model has only one output.
+    //             // You can also use the following way to get output variable by name:
+    //             // Variable outputVar = modelFunc.Outputs.Where(variable => string.Equals(variable.Name, outputName)).Single();
+    //             _outputVar = _cntkDetct.Output;
+    //             // Create output data map. Using null as Value to indicate using system allocated memory.
+    //             // Alternatively, create a Value object and add it to the data map.
+
+    //             return true;
+    //         }
+    //         catch (Exception e)
+    //         {
+    //             Logger.WriteLineWarn($"CntkCpu Initialization have an error{e}");
+    //             return false;
+    //         }
+    //     }
+
+    //     /// <summary>
+    //     /// The example shows
+    //     /// - how to load model.
+    //     /// - how to prepare input data for a batch of samples.
+    //     /// - how to prepare input and output data map.
+    //     /// - how to evaluate a model.
+    //     /// - how to retrieve evaluation result and retrieve output data in dense format.
+    //     /// </summary>
+    //     /// <param name="device">Specify on which device to run the evaluation.</param>
+    //     public List<List<CntkDetectResult>> EvaluationBatchOfImages(Image<Gray, byte>[] images)
+    //     {
+    //         try
+    //         {
+    //             var imageCount = images.Length;
+    //             if (_detectImages == null)
+    //             {
+    //                 _detectImages = new Image<Gray, float>[imageCount];
+    //                 _resizedImages = new Image<Gray, float>[imageCount];
+    //                 _imageMarkList = new Image<Gray, float>[imageCount][];
+    //                 for (var i = 0; i < imageCount; ++i)
+    //                 {
+    //                     //有几个目标就新建几个图像
+    //                     _imageMarkList[i] = new Image<Gray, float>[_labelNum];
+    //                     for (int j = 0; j < _labelNum; j++)
+    //                     {
+    //                         _imageMarkList[i][j] = new Image<Gray, float>(_modelImageWidth, _modelImageHeight);
+    //                     }
+    //                 }
+
+    //                 _imageBinarySmallFloat = new Image<Gray, float>(_modelImageWidth, _modelImageHeight);
+    //                 _imageBinarySmall = new Image<Gray, byte>(_modelImageWidth, _modelImageHeight);
+    //                 _imageBinaryBig = new Image<Gray, byte>(images[0].Width, images[0].Height);
+    //             }
+
+    //             List<Size> imagesSize = new List<Size>();
+    //             List<Size> resizedImagesSize = new List<Size>();
+    //             var imageLength = _modelImageWidth * _modelImageHeight;
+    //             var seqData = new float[imageLength * imageCount];
+    //             for (int i = 0; i < imageCount; i++)
+    //             {
+    //                 _detectImages[i]?.Dispose();
+    //                 if (images[i] == null)
+    //                 {
+    //                     return new List<List<CntkDetectResult>>();
+    //                 }
+    //                 _detectImages[i] = images[i].Convert<Gray, float>();
+    //                 imagesSize.Add(_detectImages[i].Size);
+    //                 _resizedImages[i]?.Dispose();
+    //                 _resizedImages[i] = _detectImages[i].Resize(_modelImageWidth, _modelImageHeight, Emgu.CV.CvEnum.Inter.Linear);
+    //                 resizedImagesSize.Add(_resizedImages[i].Size);
+    //                 NormalizedImage(_resizedImages[i], seqData, i);
+    //             }
+    //             // Create Value for the batch data.
+    //             var inputVal = Value.CreateBatch(_inputVar.Shape, seqData, _device);
+    //             // Create input data map.
+    //             var inputDataMap = new Dictionary<Variable, Value>();
+    //             inputDataMap.Add(_inputVar, inputVal);
+
+    //             var outputDataMap = new Dictionary<Variable, Value>();
+    //             outputDataMap.Add(_outputVar, null);
+
+    //             // Evaluate the model against the batch input
+    //             _cntkDetct.Evaluate(inputDataMap, outputDataMap, _device);
+
+    //             // Retrieve the evaluation result.
+    //             var outputVal = outputDataMap[_outputVar];
+    //             var outputData = outputVal.GetDenseData<float>(_outputVar);
+
+    //             var result = ChangeToCntkResult(outputData, imageCount, _labelNum, resizedImagesSize, imagesSize);
+
+    //             #region 画出结果------------------------------------------
+    //             ////画出结果
+    //             //for (var i = 0; i < imageCount; ++i)
+    //             //{
+    //             //    var imageBgr = images[i].Convert<Bgr, byte>();
+    //             //    var bgr = new Bgr(0, 255, 255);
+    //             //    var bgr1 = new Bgr(0, 0, 255);
+    //             //    for (var j = 0; j < result[i].Count; ++j)
+    //             //    {
+    //             //        if (result[i][j].LabelType == CntkLabelType.LabelOne)
+    //             //        {
+    //             //            imageBgr.Draw(result[i][j].Contour, bgr, 2);
+    //             //        }
+    //             //        else
+    //             //        {
+    //             //            imageBgr.Draw(result[i][j].Contour, bgr1, 2);
+    //             //        }
+
+    //             //    }
+    //             //    imageBgr.Save(System.IO.Path.Combine(@"C:\carotid\test\detect result", i + ".jpg"));
+    //             //}
+    //             #endregion
+
+    //             return result;
+    //         }
+    //         catch (Exception e)
+    //         {
+    //             Logger.WriteLineError($"CntkCpu EvaluationBatchOfImages have a error{e}");
+    //             return new List<List<CntkDetectResult>>();
+    //         }
+    //     }
+
+    //     /// <summary>
+    //     /// 转换成结果
+    //     /// </summary>
+    //     /// <param name="outputData"></param>
+    //     /// <param name="imageNums"></param>
+    //     /// <param name="labelNum"></param>
+    //     /// <param name="resizedImageSize"></param>
+    //     /// <param name="imageSize"></param>
+    //     /// <returns></returns>
+    //     private List<List<CntkDetectResult>> ChangeToCntkResult(IList<IList<float>> outputData, int imageNums, int labelNum, List<Size> resizedImageSize, List<Size> imageSize)
+    //     {
+    //         List<List<CntkDetectResult>> detectResults = new List<List<CntkDetectResult>>();
+    //         try
+    //         {
+    //             for (var i = 0; i < imageNums; ++i)
+    //             {
+    //                 var dectectList = new List<CntkDetectResult>();
+    //                 int imageLength = resizedImageSize[i].Width * resizedImageSize[i].Height;
+    //                 var listFloat = outputData[i];
+    //                 if (listFloat.Count != (labelNum + 1) * imageLength)
+    //                 {
+    //                     Logger.WriteLineWarn("The number of detection targets and the number to be detected are different!");
+    //                     return new List<List<CntkDetectResult>>();
+    //                 }
+
+    //                 for (int j = 0; j < labelNum; j++)
+    //                 {
+    //                     var oenImageOutData = outputData[i].ToArray();
+    //                     //j+1是因为要跳过结果中添加的背景
+    //                     Marshal.Copy(oenImageOutData, imageLength * (j + 1), _imageMarkList[i][j].Mat.DataPointer, imageLength);
+    //                     dectectList.AddRange(GetDetectResult(_imageMarkList[i][j], 0.8f, j, imageSize[i]));
+    //                 }
+    //                 detectResults.Add(dectectList);
+    //             }
+    //             return detectResults;
+    //         }
+    //         catch (Exception e)
+    //         {
+    //             Logger.WriteLineError($"CntkCpu ChangeToCntkResult have a error{e}");
+    //             return detectResults;
+    //         }
+    //     }
+
+    //     private List<CntkDetectResult> GetDetectResult(Image<Gray, float> image, float threshold, int labelNum, Size imageSize)
+    //     {
+    //         try
+    //         {
+    //             //计算连通域,获得轮廓
+    //             CvInvoke.Threshold(image, _imageBinarySmallFloat, threshold, 255, ThresholdType.Binary);
+    //             _imageBinarySmall = _imageBinarySmallFloat.Convert<Gray, byte>();
+    //             //原图像尺寸的轮廓二值化图像              
+    //             var contoursSmall = new VectorOfVectorOfPoint();
+    //             CvInvoke.FindContours(_imageBinarySmall, contoursSmall, null, RetrType.Tree, ChainApproxMethod.ChainApproxNone);
+
+    //             var detectResultList = new List<CntkDetectResult>();
+    //             for (var n = 0; n < contoursSmall.Size; ++n)
+    //             {
+    //                 if (contoursSmall[n] != null)
+    //                 {
+    //                     var contoursBig = GetContourBig(contoursSmall[n].ToArray(), imageSize);
+    //                     var cntkResult = new CntkDetectResult();
+    //                     cntkResult.Rect = CvInvoke.BoundingRectangle(new VectorOfPoint(contoursBig));
+    //                     cntkResult.Credibility = GetImageMean(image, contoursSmall[n], threshold);
+    //                     cntkResult.Contour = contoursBig;
+    //                     cntkResult.ContourArea = (float)CvInvoke.ContourArea(new VectorOfPoint(contoursBig));
+    //                     cntkResult.LabelType = labelNum + 1 > 1 ? CntkLabelType.LabelTwo : CntkLabelType.LabelOne;
+    //                     detectResultList.Add(cntkResult);
+    //                 }
+    //             }
+    //             detectResultList = detectResultList.OrderByDescending(o => o.ContourArea).ToList();
+    //             return detectResultList;
+    //         }
+    //         catch (Exception e)
+    //         {
+    //             Logger.WriteLineError($"CntkCpu GetDetectResult have a error{e}");
+    //             return new List<CntkDetectResult>();
+    //         }
+    //     }
+
+    //     private Point[] GetContourBig(Point[] smallContourPoints, Size imageSize)
+    //     {
+    //         var wRatio = imageSize.Width / (float)_modelImageWidth;
+    //         var hRatio = imageSize.Height / (float)_modelImageHeight;
+
+    //         var pointList = new List<Point>();
+    //         for (var i = 0; i < smallContourPoints.Length; ++i)
+    //         {
+    //             var x = smallContourPoints[i].X * wRatio;
+    //             var y = smallContourPoints[i].Y * hRatio;
+
+    //             var xx = Math.Min(x, imageSize.Width - 1);
+    //             var yy = Math.Min(y, imageSize.Height - 1);
+    //             pointList.Add(new Point((int)Math.Round(xx, 0, MidpointRounding.AwayFromZero),
+    //                                              (int)Math.Round(yy, 0, MidpointRounding.AwayFromZero)));
+
+    //         }
+    //         return pointList.Distinct().ToArray();
+    //     }
+
+    //     private float GetImageMean(Image<Gray, float> image, VectorOfPoint contour, float threshold)
+    //     {
+    //         var rect = CvInvoke.BoundingRectangle(contour);
+    //         var minW = rect.Left;
+    //         var maxW = rect.Left + rect.Width;
+    //         var minH = rect.Top;
+    //         var maxH = rect.Top + rect.Height;
+    //         float sum = 0;
+    //         int num = 0;
+    //         for (var h = minH; h < maxH; h++)
+    //         {
+    //             for (var w = minW; w < maxW; w++)
+    //             {
+    //                 if (image.Data[h, w, 0] > threshold)
+    //                 {
+    //                     sum += image.Data[h, w, 0];
+    //                     num++;
+    //                 }
+    //             }
+    //         }
+    //         if (num > 0)
+    //         {
+    //             return sum / num;
+    //         }
+    //         else
+    //         {
+    //             return 0;
+    //         }
+    //     }
+
+    //     /// <summary>
+    //     /// 归一化图像数据
+    //     /// </summary>
+    //     /// <param name="image"></param>
+    //     /// <returns></returns>
+    //     private void NormalizedImage(Image<Gray, float> image, float[] imageData, int index)
+    //     {
+    //         //求平均这和标注差
+    //         var imageLenght = image.Width * image.Height;
+    //         using Image<Gray, float> imageNormalize = new Image<Gray, float>(image.Width, image.Height);
+    //         CvInvoke.Normalize(image, imageNormalize, 0, 1, Emgu.CV.CvEnum.NormType.MinMax);
+    //         Marshal.Copy(imageNormalize.Mat.DataPointer, imageData, imageLenght * index, imageLenght);
+    //     }
+
+    // }
 }

+ 39 - 39
Carotid/Utilities/CntkSeg/CntkDetect.cs

@@ -7,50 +7,50 @@ using WingServerCommon.Log;
 
 namespace WingAIDiagnosisService.Carotid.Utilities.CntkSeg
 {
-    public class CntkDetect:IDisposable
-    {
+    // public class CntkDetect:IDisposable
+    // {
       
-        private CntkCpu _cntkDtect = null;
+    //     private CntkCpu _cntkDtect = null;
 
-        private static CntkDetect _instance;
-        /// <summary>
-        /// Instance of CntkDetect detector.
-        /// </summary>
-        public static CntkDetect Instance
-        {
-            get => _instance ?? (_instance = new CntkDetect());
-        }
+    //     private static CntkDetect _instance;
+    //     /// <summary>
+    //     /// Instance of CntkDetect detector.
+    //     /// </summary>
+    //     public static CntkDetect Instance
+    //     {
+    //         get => _instance ?? (_instance = new CntkDetect());
+    //     }
 
-        public bool Initialization(string modelFilePath, int detectObjectNum)
-        {
-            try
-            {
-                _cntkDtect?.Dispose();
-                _cntkDtect = new CntkCpu();             
-                // 读入
-                byte[] fileDataEncrypted = AESUtility.AESDecrypt(File.ReadAllBytes(modelFilePath));
-                _cntkDtect.Initialization(fileDataEncrypted, detectObjectNum);
-                return true;
-            }
-            catch (Exception e)
-            {
-                Logger.WriteLineError($"CntkDetect Initialization have an error{e}");
-                return false;
-            }  
-        }
+    //     public bool Initialization(string modelFilePath, int detectObjectNum)
+    //     {
+    //         try
+    //         {
+    //             _cntkDtect?.Dispose();
+    //             _cntkDtect = new CntkCpu();             
+    //             // 读入
+    //             byte[] fileDataEncrypted = AESUtility.AESDecrypt(File.ReadAllBytes(modelFilePath));
+    //             _cntkDtect.Initialization(fileDataEncrypted, detectObjectNum);
+    //             return true;
+    //         }
+    //         catch (Exception e)
+    //         {
+    //             Logger.WriteLineError($"CntkDetect Initialization have an error{e}");
+    //             return false;
+    //         }  
+    //     }
 
-        public List<List<CntkDetectResult>> DetectImage(Image<Gray, byte>[] images)
-        {
-            var result = _cntkDtect.EvaluationBatchOfImages(images);
-            return result;
-        }
+    //     public List<List<CntkDetectResult>> DetectImage(Image<Gray, byte>[] images)
+    //     {
+    //         var result = _cntkDtect.EvaluationBatchOfImages(images);
+    //         return result;
+    //     }
 
 
-        public void Dispose()
-        {
-            _cntkDtect.Dispose();
-            _instance = null;
-        }
+    //     public void Dispose()
+    //     {
+    //         _cntkDtect.Dispose();
+    //         _instance = null;
+    //     }
 
-    }
+    // }
 }

+ 268 - 330
Carotid/Utilities/GetModelVesselAndPlaque.cs

@@ -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
 
+        /// <summary>
+        /// 得到一个AAAA的实例
+        /// </summary>
         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();
-
+        /// <summary>
+        /// 是否已初始化
+        /// </summary>
+        /// <returns></returns>
         public bool InitializationStatus()
         {
             return _isInitializationSuccess;
         }
 
-        public bool Initialization(string modelArtery, string modelPlaque)
+        /// <summary>
+        /// 初始化
+        /// </summary>
+        /// <param name="modelArtery"></param>
+        /// <param name="modelPlaque"></param>
+        /// <returns></returns>
+        public bool Initialization(EnumPerformance performance, string modelFolder)
         {
-            _batchImageSize = 8;//Config.GetValue("Carotid", "BatchImageSize", 2);todo
-            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;
+                }
+            }
+        }
+
+        /// <summary>
+        /// 获得所有斑块的轮廓
+        /// </summary>
+        /// <returns></returns>
         public List<OnePlaqueContours> GetAllPlaqueContours()
         {
             return _allPlaqueContours;
         }
 
+        /// <summary>
+        /// 获得有内膜的血管(颈动脉?)
+        /// </summary>
+        /// <returns></returns>
         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 };
         }
 
+        /// <summary>
+        /// 获得Y形的起始位置?
+        /// </summary>
+        /// <returns></returns>
         public List<OneImageArteryContours> GetYBeginVessel()
         {
             lock (_locker)
@@ -229,6 +281,10 @@ namespace WingAIDiagnosisService.Carotid.Utilities
             }
         }
 
+        /// <summary>
+        /// 获得Y形的终止位置?
+        /// </summary>
+        /// <returns></returns>
         public List<OneImageArteryContours> GetYEndVessel()
         {
             lock (_locker)
@@ -251,27 +307,87 @@ namespace WingAIDiagnosisService.Carotid.Utilities
             }
         }
 
+        /// <summary>
+        /// 进行检测
+        /// </summary>
+        /// <param name="modelSource"></param>
+        /// <param name="modelSize"></param>
+        /// <returns></returns>
         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>();
+                // 每隔3帧算一次
+                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)
+                    {
+                        // 只取每一个颈动脉OrganContours里的第一条轮廓
+                        // 注意:如有多个颈动脉,则会有多个organ=EnumOrgans.CarotidArtery的结果,每个organ里还是只有一条轮廓
+                        // (目前一个目标有多条轮廓只适用于圆环形心肌这种情况,这时心肌需要用内外两条线才能完整表示一个目标)
+                        if (organ.Organ == EnumOrgans.CarotidArtery && organ.OrganContours?.Length == 1)
+                        {
+                            // 目前AIDiagSystem中未返回organ的置信度,因此这里暂时全设为0.8 (该值不影响后续的流程)
+                            // 斑块和颈动脉 好像都是CntkLabelType.LabelOne
+                            var oneArtery = GenCntkDetectResult(0.8f, CntkLabelType.LabelOne, organ.OrganBoundBox,
+                                organ.OrganContours[0]);
+                            // 将当前轮廓添加到detectedArtery里
+                            detectedArtery.Add(oneArtery);
+
+                            // 将当前血管上找到的斑块 转成所需的格式 放到plaqueList里
+                            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);
+                            }
+                        }
+                    }
+                    // 将有动脉的那些帧的序号和对应的动脉轮廓,存到vesselList里
+                    if (detectedArtery.Count > 0)
+                    {
+                        vesselList.Add(new OneImageArteryContours(ni, detectedArtery));
+                    }
                 }
+                // 去除从异常位置的颈动脉血管上找到的斑块
+                var selectedPlaqueList = RemoveAbnormalImage(vesselList, plaqueList);
 
-                //检测斑块
-                _allPlaqueContours = GetAllPlaqueContours(arteryImageList);
-                //释放不用的图像
-                DisposeImage(arteryImageList);
+                // 更新_allArteryContours 和 _allPlaqueContours
+                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)
+        /// <summary>
+        /// 销毁
+        /// </summary>
+        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)
             {
                 //var newX = line[0] * points[i].X + line[2];
-                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;
             //删除差值大于平均值加减3倍的标准差的点
+            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>();
             }
-        }
-
-        /// <summary>
-        /// 识别动脉
-        /// </summary>
-        /// <param name="modelSource"></param>
-        /// <returns></returns>
-        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;
-                        }
-
-                        //返回的结果已经按血管轮廓的ContourArea降序排过,所以这里的第一个,就是血管轮廓最大的。
-                        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);
-        }
-
-        /// <summary>
-        /// 判断contourDst是否在contourSource内
-        /// </summary>
-        /// <param name="contourSource"></param>
-        /// <param name="contourDst"></param>
-        /// <returns></returns>
-        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;
-        }
     }
 }

+ 2 - 1
Service/AIDiagnosisService.cs

@@ -319,7 +319,7 @@ namespace WingAIDiagnosisService.Service
             resampleInputData.ScanDistance = scanDistance;
             resampleInputData.ScanType = scanType;
             resampleInputData.CarotidScanDirection = direction;
-            resampleResult = ResampleModel.Instance.Resample(vinnoImageData, resampleInputData);
+            resampleResult = ResampleModel.Instance.Resample(vinnoImageData, resampleInputData, _workerLevel);
             return resampleResult;
         }
 
@@ -596,6 +596,7 @@ namespace WingAIDiagnosisService.Service
                 {
                     // FileTypeEnum = fileTypeEnum,
                     // ApplicantTypeEnum = ApplicantTypeEnum.Server,
+                    FileName = fileName,
                     Token = defaultToken
                 });
             requestHeads.Add("Authorization", authorizationRet.Authorization);

+ 2 - 2
WingAIDiagnosisService.csproj

@@ -26,9 +26,9 @@
     <Reference Include="AI.DiagSystem">
       <HintPath>AIDiagnosis\AI.DiagSystem.dll</HintPath>
     </Reference>
-    <Reference Include="Cntk.Core.Managed-2.7">
+    <!-- <Reference Include="Cntk.Core.Managed-2.7">
       <HintPath>AIDiagnosis\Cntk.Core.Managed-2.7.dll</HintPath>
-    </Reference>
+    </Reference> -->
   </ItemGroup>
   
   <ItemGroup>