|
@@ -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);
|
|
|
+ // }
|
|
|
+
|
|
|
+ // }
|
|
|
}
|