using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Windows; using System.Windows.Controls; using System.Windows.Data; using System.Windows.Documents; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Imaging; using System.Windows.Navigation; using System.Windows.Shapes; using Microsoft.Win32; using System.Drawing; using System.Threading; using System.Windows.Threading; using System.Drawing.Imaging; using System.IO; using System.Runtime.InteropServices; using AI.Common.Interface; using RawImageShowUtilsLib; using System.Reflection; using System.Runtime.InteropServices.ComTypes; using AI.Common.Implements; using AIModuleResultShowUtilsLib; using System.ComponentModel; namespace SegmentDescribDemo { enum ContourShape //轮廓形状 { NoneShape = 0, Oval = 1, // 椭圆 Round = 2, // 类圆 Irregular = 3 // 不规则 }; enum Orientation //生长方向 { NoneOrientation = 0, Parallel = 1, // 平行 NonParallel = 2 // 非平行 }; enum EchoPattern //回声类型 { NoneEcho = 0, Anechoic = 1, // 无回声 Hypoechoic = 2, // 低回声 Hyperechoic = 3, // 高回声 Strongechoic = 4, // 强回声 Complex = 5, // 混合回声 Isoechoic = 6, // 等回声 }; enum Boundary //边界清晰度 { NoneBoundary = 0, AbruptInterface = 1, //清晰 EchogenicHalo = 2 //不清晰,模糊 }; enum MarginEnum //边缘光整度 { NoneMargin = 0, Circumscribed = 1, //光整 NonCircumscribed = 2 //不光整 }; enum Calcifications { NoneCalc = 0, NoCalcifications = 1, //无钙化 Macrocalcifications = 2, //粗大钙化 CalcificationsInMass = 3, //内部微钙化 CalcificationsOutOfMass = 4 //外部微钙化 }; //局灶性强回声 enum EchogenicFociEnum { NoCifications = 0, //无钙化 Coarsecalcifications = 1, //粗钙化 Microcalcifications = 2, //微钙化 }; public struct roiCoor { public int x; public int y; public int width; public int height; } /// /// MainWindow.xaml 的交互逻辑 /// public partial class MainWindow : Window { #region private variables private BitmapImage _origimg; private BitmapImage _dstimg; private Queue _imagesReadyToDrawBox = new Queue(); private Queue _testDatas = new Queue(); private bool _stop = false; private bool _reuseimg = false; private System.Windows.Media.Brush _roiColor = System.Windows.Media.Brushes.Orange; private System.Drawing.Point _startpoint; private System.Drawing.Point _endpoint; private System.Drawing.Rectangle _drawingroi = System.Drawing.Rectangle.Empty; private volatile bool _roidrawn = false; private int _currentImgIdex; private string _currentImgId; private Bitmap _currentimg; private Queue _imgNameQueue = new Queue(); // 图像文件名(循环读图) private List _imgNameList = new List(); // 图像文件名 private List _imgROIList = new List(); private List _allImages = new List(); //private AIDiagSystem _aiSeg; private IModule _module; private string _currentPath; private InferenceConfig _inferConfig = new InferenceConfig(); private string _netDir = System.IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Networks"); private volatile string _processId = string.Empty; private volatile string _caseId = string.Empty; private volatile string _dataId = string.Empty; private volatile bool _readingVideo; private volatile int _frameIndex; //回声 private int _Anechoic_Anechoi_num = 0; //无回声 判为 无回声 的数目 private int _Anechoic_Hyperechoic_num = 0; //无回声 判为 高回声 的数目 private int _Anechoic_Isoechoic_num = 0; private int _Anechoic_Hypoechoic_num = 0; private int _Anechoic_HypoechoicLower_num = 0; private int _Hyperechoic_Hyperechoic_num = 0; //高回声 判为 高回声 private int _Hyperechoic_Anechoic_num = 0; private int _Hyperechoic_Isoechoic_num = 0; private int _Hyperechoic_Hypoechoic_num = 0; private int _Hyperechoic_HypoechoicLower_num = 0; private int _Isoechoic_Isoechoic_num = 0; //等回声 判为 等回声 private int _Isoechoic_Anechoic_num = 0; private int _Isoechoic_Hyperechoic_num = 0; private int _Isoechoic_Hypoechoic_num = 0; private int _Isoechoic_HypoechoicLower_num = 0; private int _Hypoechoic_Hypoechoic_num = 0; //低回声 判为 低回声 private int _Hypoechoic_Anechoic_num = 0; private int _Hypoechoic_Hyperechoic_num = 0; private int _Hypoechoic_Isoechoic_num = 0; private int _Hypoechoic_HypoechoicLower_num = 0; private int _HypoechoicLower_HypoechoicLower_num = 0; //极低回声 判为 极低回声 private int _HypoechoicLower_Anechoicr_num = 0; private int _HypoechoicLower_Hyperechoic_num = 0; private int _HypoechoicLower_Isoechoic_num = 0; private int _HypoechoicLower_Hypoechoic_num = 0; private int _Oval_Oval_num = 0; //椭圆 判为 椭圆 private int _Oval_Round_num = 0; //椭圆 判为 类圆 private int _Oval_Irregular_num = 0;//椭圆 判为 不规则 private int _Round_Oval_num = 0; private int _Round_Round_num = 0; private int _Round_Irregular_num = 0; private int _Irregular_Oval_num = 0; private int _Irregular_Round_num = 0; private int _Irregular_Irregular_num = 0; private int _Circumscribed_Circumscribed_num = 0; //光整 判为 光整 private int _Circumscribed_NonCircumscribed_num = 0; //光整 判为 不光整 private int _NonCircumscribed_Circumscribed_num = 0; private int _NonCircumscribed_NonCircumscribed_num = 0; private int _AbruptInterface_AbruptInterface_num = 0; //清晰 判为 清晰 private int _AbruptInterface_EchogenicHalo_num = 0; //清晰 判为 不清晰,模糊 private int _EchogenicHalo_AbruptInterface_num = 0; private int _EchogenicHalo_EchogenicHalo_num = 0; private int _Parallel_Parallel_num = 0; //平行 判为 平行 private int _Parallel_NonParallel_num = 0; //平行 判为 非平行 private int _NonParallel_Parallel_num = 0; private int _NonParallel_NonParallel_num = 0; private int _Shadowing = 0; private int _Enhancement = 0; private int _Absent = 0; private int _Combined = 0; #endregion [DllImport(@"LesionDescription.dll", CallingConvention = CallingConvention.Cdecl)] public static extern void BreastDescriptionHaveModelProcess(byte[] img_data, int channels, int img_w, int img_h, roiCoor roi_vec, int num_pts, MyPoint[] contour_points, int contourNum, int[] contourLen, MyPoint[] calcificationPts, ref LesionDescriNow lesionDescr); [DllImport(@"tools.dll", CallingConvention = CallingConvention.Cdecl)] public static extern void BreastDescriptionLesionsRect(int img_w, int img_h, MyPoint[] contour_points, int contourLen, roiCoor lesionRectPr, ref int sameLesion); [DllImport(@"tools.dll", CallingConvention = CallingConvention.Cdecl)] public static extern void DescriptionLesionsRect(int img_w, int img_h, MyPoint[] contour_points, int contourLen, ref roiCoor lesionRectPr); [DllImport(@"LesionAxis.dll", CallingConvention = CallingConvention.Cdecl)] public static extern void LesionVerHorAxis(int img_w, int img_h, int contourLen, MyPoint[] contour_points, ref AxisPoint axisPt); [DllImport(@"LesionAxis.dll", CallingConvention = CallingConvention.Cdecl)] public static extern void MyLesionAxisProcess(roiCoor lesionRect, int contourLen, MyPoint[] contour_points, ref AxisPoint axisPt); #region 窗体响应 public MainWindow() { InitializeComponent(); _origimg = null; _dstimg = null; OrigImage.Source = _origimg; DstImage.Source = _dstimg; _currentPath = System.Environment.CurrentDirectory; _module = new AI.Vaid.Modules.BreastLesionDetect.BreastLesionDetect(_netDir, _inferConfig, EnumDeviceType.CPU); } private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e) { //ImageUtility.Dispose(); } private void OnLoadOneImageClick(object sender, RoutedEventArgs e) // 加载1张图像 { OpenFileDialog openFileDialog = new OpenFileDialog(); openFileDialog.Filter = "图片文件|*.png;*.bmp;*.jpg;*.jpeg"; openFileDialog.Multiselect = false; openFileDialog.Title = "选择一幅图像"; if (openFileDialog.ShowDialog() ?? false) { Bitmap img = new Bitmap(openFileDialog.FileName); _imagesReadyToDrawBox.Enqueue(img); DoROIDrawing(); } string tmp = System.IO.Path.GetFileNameWithoutExtension(openFileDialog.FileName); _imgNameQueue.Enqueue(tmp); } private void OnStartContinuousTestClick(object sender, RoutedEventArgs e) // 加载多张图像 { if (_imagesReadyToDrawBox.Count > 0 || _testDatas.Count > 0) { MessageBox.Show("请先停止连续测试."); return; } OpenFileDialog openFileDialog = new OpenFileDialog(); openFileDialog.Filter = "图片文件|*.png;*.bmp;*.jpg;*.jpeg"; openFileDialog.Multiselect = true; openFileDialog.Title = "选择一幅或多幅图像"; if (openFileDialog.ShowDialog() ?? false) { foreach (string filename in openFileDialog.FileNames) { Bitmap img = new Bitmap(filename); _imagesReadyToDrawBox.Enqueue(img); //string tmp = System.IO.Path.GetFileName(filename); string imgName = System.IO.Path.GetFileNameWithoutExtension(filename); _imgNameQueue.Enqueue(imgName); // 图像文件名 _imgNameList.Add(imgName); } _reuseimg = true; DoROIDrawing(); //画ROI } } private void OnUseCurrentROIClick(object sender, RoutedEventArgs e) // 使用当前的ROI { if (!_startpoint.IsEmpty && !_endpoint.IsEmpty && _currentimg != null) { int roileft = Math.Min(_startpoint.X, _endpoint.X); int roiright = Math.Max(_startpoint.X, _endpoint.X); int roitop = Math.Min(_startpoint.Y, _endpoint.Y); int roibottom = Math.Max(_startpoint.Y, _endpoint.Y); if (roileft == roiright || roitop == roibottom) { MessageBox.Show("绘制的矩形框尺寸不能为0."); return; } _drawingroi = new System.Drawing.Rectangle(roileft, roitop, roiright - roileft, roibottom - roitop); SegDataInput data; if (_currentimg.PixelFormat == System.Drawing.Imaging.PixelFormat.Format24bppRgb || _currentimg.PixelFormat == System.Drawing.Imaging.PixelFormat.Format8bppIndexed) { data = new SegDataInput(_currentimg, _drawingroi); } else { data = new SegDataInput(_currentimg.Clone(new System.Drawing.Rectangle(0, 0, _currentimg.Width, _currentimg.Height), System.Drawing.Imaging.PixelFormat.Format24bppRgb), _drawingroi); } _testDatas.Enqueue(data); _roidrawn = true; _imgROIList.Add(_drawingroi); /// 开始图像分割 if (_imagesReadyToDrawBox.Count > 0) { DoROIDrawing(); } else { if (FuncFCM.IsChecked.Value) { DoTest("FCM"); } else if (FuncACWE.IsChecked.Value) { DoTest("ACWE"); // ACWE活动轮廓算法 } else if (FuncDRLSE.IsChecked.Value) { DoTest("DRLSE"); // DRLSE活动轮廓算法 } else if (FuncLBF.IsChecked.Value) { DoTest("LBF"); // LBF活动轮廓算法 } else if (FuncLSEWR.IsChecked.Value) { DoTest("LSEWR"); } else if (FuncBLS.IsChecked.Value) { DoTest("BLS"); } } } else { MessageBox.Show("请先加载待测图像并绘制ROI"); } } private void OnStopContinuousTestClick(object sender, RoutedEventArgs e) { _stop = true; _reuseimg = false; } private void Canvas_SizeChanged(object sender, SizeChangedEventArgs e) { MyCanvas.Width = GridOrigImg.ActualWidth; MyCanvas.Height = GridOrigImg.ActualHeight; ImageUpdated(); DrawingROIUpdated(); } private void Canvas_MouseLeftBtnDown(object sender, MouseButtonEventArgs e) { int x = Convert.ToInt32(e.GetPosition(OrigImage).X / OrigImage.ActualWidth * _origimg.Width); int y = Convert.ToInt32(e.GetPosition(OrigImage).Y / OrigImage.ActualHeight * _origimg.Height); _startpoint = new System.Drawing.Point(x, y); } private void Canvas_MouseMove(object sender, MouseEventArgs e) { int x = Convert.ToInt32(e.GetPosition(OrigImage).X / OrigImage.ActualWidth * _origimg.Width); int y = Convert.ToInt32(e.GetPosition(OrigImage).Y / OrigImage.ActualHeight * _origimg.Height); MousePosition.Text = x.ToString() + "," + y.ToString(); if (e.LeftButton == MouseButtonState.Pressed) { _endpoint = new System.Drawing.Point(x, y); DrawingROIUpdated(); } } #endregion #region private funcs private void DoROIDrawing() { System.Threading.Tasks.Task.Run(() => { if (_stop) { _stop = false; _imagesReadyToDrawBox.Clear(); return; } if (_imagesReadyToDrawBox.Count <= 0) { return; } Bitmap origimage = _imagesReadyToDrawBox.Dequeue(); DrawROIForOneImage(origimage); //对ROI坐标赋值 }); } private void DrawROIForOneImage(Bitmap image) { _origimg = ImageUtility.BitmapToBitmapImage(image); _currentimg = image; _drawingroi = System.Drawing.Rectangle.Empty; _roidrawn = false; Dispatcher.BeginInvoke(DispatcherPriority.Normal, new Action(() => { _dstimg = null; DstImage.Source = _dstimg; ImageUpdated(); _startpoint = System.Drawing.Point.Empty; _endpoint = System.Drawing.Point.Empty; DrawingROIUpdated(); ROI.Text = string.Empty; })); while (!_roidrawn) { Thread.Sleep(100); } } private void DoTest(string algriType) //循环处理已经选中的图像 { System.Threading.Tasks.Task.Run(() => { if (_testDatas.Count <= 0 || _stop) { _stop = false; _testDatas.Clear(); return; } SegDataInput data = _testDatas.Dequeue(); string img_name; if (_imgNameQueue.Count == 1) { img_name = _imgNameQueue.Peek(); // 返回队列开头的元素但不移除该元素 } else { img_name = _imgNameQueue.Dequeue(); } // 移除队列开头的元素并返回该元素 TestOneImage(data, algriType, img_name); // 处理图像 if (_reuseimg) { _testDatas.Enqueue(data); } Thread.Sleep(50); DoTest(algriType); }); } private unsafe void TestOneImage(SegDataInput data, string algriType, string imgName) // 调用接口函数 { var starttime = Environment.TickCount; System.Drawing.PointF[] contours = null; //待画的病灶轮廓 System.Drawing.PointF[] axis_h = new PointF[2]; System.Drawing.PointF[] axis_v = new PointF[2]; EnumSegMethod segMmethod = (EnumSegMethod)Enum.Parse(typeof(EnumSegMethod), algriType); contours = ImageUtility.ContourDetect(data, segMmethod); //调用病灶分割算法 DesDataInput desData = new DesDataInput(data.InputImage, data.InputRoi, contours); /// 病灶轮廓描述 AxisPoint axisPt = new AxisPoint(); LesionDescriptionResult lesionDescr = ImageUtility.BreastDescription(desData, axisPt); int shapeDescri = lesionDescr.Shape; // 形状描述 int growthDerec = lesionDescr.Orientation; // 生长方向 int echoType = lesionDescr.Echo; // 回声类型 int boundarySharpness = lesionDescr.Boundary; // 边界清晰度 int edgeSmooth = lesionDescr.Margin; // 边缘光整度 int echogenicFoci = lesionDescr.Calcification; // 钙化 Dispatcher.BeginInvoke(DispatcherPriority.Normal, new Action(() => { if (shapeDescri == (int)ContourShape.Oval) { ContourShapeDescri.Text = "椭圆形"; } else if (shapeDescri == (int)ContourShape.Round) { ContourShapeDescri.Text = "类圆形"; } else if (shapeDescri == (int)ContourShape.Irregular) { ContourShapeDescri.Text = "不规则形"; } else if (shapeDescri == (int)ContourShape.NoneShape) { ContourShapeDescri.Text = "未标注"; } if (growthDerec == (int)Orientation.NonParallel) { GrowDirectionDescri.Text = "非平行"; } else if (growthDerec == (int)Orientation.Parallel) { GrowDirectionDescri.Text = "平行"; } else if (growthDerec == (int)Orientation.NoneOrientation) { GrowDirectionDescri.Text = "未标注"; } if (echoType == (int)EchoPattern.Anechoic) // 1无回声 { EchoPatternDescri.Text = "无回声"; } else if (echoType == (int)EchoPattern.Hypoechoic) // 2低回声 { EchoPatternDescri.Text = "低回声"; } else if (echoType == (int)EchoPattern.Complex) // 5混合回声 { EchoPatternDescri.Text = "混合回声"; } else if (echoType == (int)EchoPattern.NoneEcho) { EchoPatternDescri.Text = "未标注"; } // 边界清晰度 if (boundarySharpness == (int)Boundary.AbruptInterface) { BoundaryBoundaryDescri.Text = "清晰"; } else if (boundarySharpness == (int)Boundary.EchogenicHalo) { BoundaryBoundaryDescri.Text = "不清晰"; } else if (boundarySharpness == (int)Boundary.NoneBoundary) { BoundaryBoundaryDescri.Text = "未标注"; } // 边缘光整度 if (edgeSmooth == (int)SegmentDescribDemo.MarginEnum.Circumscribed) { EdgeMarginDescri.Text = "光整"; } else if (edgeSmooth == (int)SegmentDescribDemo.MarginEnum.NonCircumscribed) { EdgeMarginDescri.Text = "不光整"; } else if (edgeSmooth == (int)SegmentDescribDemo.MarginEnum.NoneMargin) { EdgeMarginDescri.Text = "未标注"; } // 局灶性强回声:钙化 if (echogenicFoci == (int)Calcifications.NoCalcifications) { EdgeCificationDescri.Text = "无钙化"; } else if (echogenicFoci == (int)Calcifications.Macrocalcifications) { EdgeCificationDescri.Text = "粗钙化"; } else if (echogenicFoci == (int)Calcifications.CalcificationsInMass) { EdgeCificationDescri.Text = "微钙化"; } else { EdgeCificationDescri.Text = "未标注"; } })); var endtime = Environment.TickCount; Dispatcher.BeginInvoke(DispatcherPriority.Normal, new Action(() => { ElapsedTime.Text = (endtime - starttime).ToString(); })); Bitmap dstimage = (Bitmap)data.InputImage.Clone(); using (var g = Graphics.FromImage(dstimage)) { if (contours.Length > 0) { //画病灶轮廓 System.Drawing.Pen pen = new System.Drawing.Pen(System.Drawing.Brushes.Orange, 2); g.DrawLines(pen, contours); pen.Dispose(); } //画轮廓的长短轴 System.Drawing.Pen pen_h = new System.Drawing.Pen(System.Drawing.Brushes.PaleGreen, 2); g.DrawLines(pen_h, axis_h); //横轴,浅绿色 System.Drawing.Pen pen_v = new System.Drawing.Pen(System.Drawing.Brushes.Red, 2); g.DrawLines(pen_v, axis_v); //纵轴,红色 g.Dispose(); } _dstimg = ImageUtility.BitmapToBitmapImage(dstimage); Dispatcher.BeginInvoke(DispatcherPriority.Normal, new Action(() => { DstImage.Source = _dstimg; })); dstimage.Dispose(); } private void DrawingROIUpdated() { if (null == _origimg) { return; } System.Windows.Shapes.Rectangle drawingroi = MyCanvas.FindName("drawingroi") as System.Windows.Shapes.Rectangle; if (drawingroi != null) { MyCanvas.Children.Remove(drawingroi); MyCanvas.UnregisterName("drawingroi"); } if (_startpoint.IsEmpty || _endpoint.IsEmpty) { return; } // 在原始图像上的坐标 int roileft = Math.Min(_startpoint.X, _endpoint.X); int roiright = Math.Max(_startpoint.X, _endpoint.X); int roitop = Math.Min(_startpoint.Y, _endpoint.Y); int roibottom = Math.Max(_startpoint.Y, _endpoint.Y); ROI.Text = roileft.ToString() + "," + roitop + "," + roiright.ToString() + "," + roibottom.ToString(); // 求在画布上的坐标 double boxTopInCanvas = roitop * OrigImgScaleTramsform.ScaleY; double boxLeftInCanvas = roileft * OrigImgScaleTramsform.ScaleX; double boxWidthInCanvas = (roiright - roileft) * OrigImgScaleTramsform.ScaleX; double boxHeghtInCanvas = (roibottom - roitop) * OrigImgScaleTramsform.ScaleY; // 在画布上画矩形 drawingroi = new System.Windows.Shapes.Rectangle(); drawingroi.StrokeThickness = 3; drawingroi.Stroke = _roiColor; drawingroi.Width = boxWidthInCanvas; drawingroi.Height = boxHeghtInCanvas; Canvas.SetLeft(drawingroi, boxLeftInCanvas); Canvas.SetTop(drawingroi, boxTopInCanvas); MyCanvas.Children.Add(drawingroi); MyCanvas.RegisterName("drawingroi", drawingroi); } private void ImageUpdated() { if (null == _origimg) { return; } // 缩放 double ratioW = GridOrigImg.ActualWidth / _origimg.Width; double ratioH = GridOrigImg.ActualHeight / _origimg.Height; double ratio = ratioW < ratioH ? ratioW : ratioH; OrigImgScaleTramsform.CenterX = 0; OrigImgScaleTramsform.CenterY = 0; OrigImgScaleTramsform.ScaleX = ratio; OrigImgScaleTramsform.ScaleY = ratio; // 使图像居中,需要平移 double translateX = 0; double translateY = 0; if (Math.Abs(ratio - ratioW) < 0.0001) { translateY = 0.5 * (ratioH - ratio) * _origimg.Height; } else { translateX = 0.5 * (ratioW - ratio) * _origimg.Width; } // 更新画布尺寸,使其刚好只覆盖图像区域 MyCanvas.Width = ratio * _origimg.Width; MyCanvas.Height = ratio * _origimg.Height; Canvas.SetLeft(MyCanvas, translateX); Canvas.SetTop(MyCanvas, translateY); MyCanvas.ClipToBounds = true; OrigImage.Source = _origimg; } #endregion private void OnLoadDataBaseClick(object sender, RoutedEventArgs e) { OpenFileDialog openFileDialog = new OpenFileDialog(); openFileDialog.Filter = "数据库文件|*.db"; openFileDialog.Multiselect = false; openFileDialog.Title = "选择一个数据库文件"; string dbPath = ""; if (openFileDialog.ShowDialog() ?? false) { dbPath = openFileDialog.FileName; } DataBase dataBase = new DataBase(dbPath); dataBase.ReadDataBase(); if (dataBase._allImages.Count > 1) { _allImages = dataBase._allImages; if (_allImages.Count > 0) { MessageBox.Show("加载成功!"); } } else { MessageBox.Show("读取失败!"); } } private void OnLoadOneImagesClick(object sender, RoutedEventArgs e) { OpenFileDialog openFileDialog = new OpenFileDialog(); openFileDialog.Filter = "图片文件|*.png;*.bmp;*.jpg;*.jpeg"; openFileDialog.Multiselect = true; openFileDialog.Title = "选择一幅或多幅图像"; if (openFileDialog.ShowDialog() ?? false) { foreach (string filename in openFileDialog.FileNames) { Bitmap img = new Bitmap(filename); _currentimg = img; string temp; int idx = filename.LastIndexOf("\\"); temp = filename.Substring(idx); string[] strs1 = temp.Split('\\'); temp = strs1[1]; //string[] strs2 = temp.Split(new char[4] { '.', 'j', 'p', 'g' }, 2); //string ImgId = strs2[0]; string[] sArray = null; sArray = System.Text.RegularExpressions.Regex.Split(temp, ".jpg", System.Text.RegularExpressions.RegexOptions.IgnoreCase); string ImgId = sArray[0]; //WriteTxtToFile("E:\\image\\", "name.txt", ImgId, false); _currentImgId = ImgId; int imgIdx = _allImages.FindIndex(x => x.ImageId == _currentImgId); if (imgIdx < 0) { //return; continue; } else { _currentImgIdex = imgIdx; DoDescriAlgorithm(ImgId); } } Console.WriteLine("无回声 -> 无回声: " + _Anechoic_Anechoi_num); Console.WriteLine("无回声 -> 高回声: " + _Anechoic_Hyperechoic_num); Console.WriteLine("无回声 -> 等回声: " + _Anechoic_Isoechoic_num); Console.WriteLine("无回声 -> 低回声: " + _Anechoic_Hypoechoic_num); Console.WriteLine("无回声 -> 极低回声: " + _Anechoic_HypoechoicLower_num); Console.WriteLine("高回声 -> 高回声: " + _Hyperechoic_Hyperechoic_num); Console.WriteLine("高回声 -> 无回声: " + _Hyperechoic_Anechoic_num); Console.WriteLine("高回声 -> 等回声: " + _Hyperechoic_Isoechoic_num); Console.WriteLine("高回声 -> 低回声: " + _Hyperechoic_Hypoechoic_num); Console.WriteLine("高回声 -> 极低回声: " + _Hyperechoic_HypoechoicLower_num); Console.WriteLine("等回声 -> 等回声: " + _Isoechoic_Isoechoic_num); Console.WriteLine("等回声 -> 无回声: " + _Isoechoic_Anechoic_num); Console.WriteLine("等回声 -> 高回声: " + _Isoechoic_Hyperechoic_num); Console.WriteLine("等回声 -> 低回声: " + _Isoechoic_Hypoechoic_num); Console.WriteLine("等回声 -> 极低回声: " + _Isoechoic_HypoechoicLower_num); Console.WriteLine("低回声 -> 低回声: " + _Hypoechoic_Hypoechoic_num); Console.WriteLine("低回声 -> 无回声: " + _Hypoechoic_Anechoic_num); Console.WriteLine("低回声 -> 高回声: " + _Hypoechoic_Hyperechoic_num); Console.WriteLine("低回声 -> 等回声: " + _Hypoechoic_Isoechoic_num); Console.WriteLine("低回声 -> 极低回声: " + _Hypoechoic_HypoechoicLower_num); Console.WriteLine("极低回声 -> 极低回声: " + _HypoechoicLower_HypoechoicLower_num); Console.WriteLine("极低回声 -> 无回声: " + _HypoechoicLower_Anechoicr_num); Console.WriteLine("极低回声 -> 高回声: " + _HypoechoicLower_Hyperechoic_num); Console.WriteLine("极低回声 -> 等回声: " + _HypoechoicLower_Isoechoic_num); Console.WriteLine("极低回声 -> 低回声: " + _HypoechoicLower_Hypoechoic_num); /// Console.WriteLine("椭圆 -> 椭圆: " + _Oval_Oval_num); Console.WriteLine("椭圆 -> 类圆: " + _Oval_Round_num); Console.WriteLine("椭圆 -> 不规则: " + _Oval_Irregular_num); Console.WriteLine("类圆 -> 椭圆: " + _Round_Oval_num); Console.WriteLine("类圆 -> 类圆: " + _Round_Round_num); Console.WriteLine("类圆 -> 不规则: " + _Round_Irregular_num); Console.WriteLine("不规则 -> 椭圆: " + _Irregular_Oval_num); Console.WriteLine("不规则 -> 类圆: " + _Irregular_Round_num); Console.WriteLine("不规则 -> 不规则: " + _Irregular_Irregular_num); Console.WriteLine("光整 -> 光整: " + _Circumscribed_Circumscribed_num); Console.WriteLine("光整 -> 不光整: " + _Circumscribed_NonCircumscribed_num); Console.WriteLine("不光整 -> 光整: " + _NonCircumscribed_Circumscribed_num); Console.WriteLine("不光整 -> 不光整: " + _NonCircumscribed_NonCircumscribed_num); Console.WriteLine("清晰 -> 清晰: " + _AbruptInterface_AbruptInterface_num); Console.WriteLine("清晰 -> 不清晰: " + _AbruptInterface_EchogenicHalo_num); Console.WriteLine("不清晰 -> 清晰: " + _EchogenicHalo_AbruptInterface_num); Console.WriteLine("不清晰 -> 不清晰: " + _EchogenicHalo_EchogenicHalo_num); Console.WriteLine("平行 -> 平行: " + _Parallel_Parallel_num); Console.WriteLine("平行 -> 非平行: " + _Parallel_NonParallel_num); Console.WriteLine("非平行 -> 平行: " + _NonParallel_Parallel_num); Console.WriteLine("非平行 -> 非平行: " + _NonParallel_NonParallel_num); Console.WriteLine(); } } //描述算法调用接口 private void DoDescriAlgorithm(string name) { if (_currentimg == null) { MessageBox.Show("请先加载待测图像!"); return; } Bitmap bmp = _currentimg; //RawImage rawImg = BitmapToRawImage(bmp); roiCoor roi; roi.x = 0; roi.y = 0; roi.width = _currentimg.Width; roi.height = _currentimg.Height; int LesionsNum = _allImages[_currentImgIdex].Lesions.Count; //确定存在病灶 if (LesionsNum > 0) { Bitmap dstimage = (Bitmap)_currentimg.Clone(); //Bitmap oriimage = (Bitmap)_currentimg.Clone(); int lesionsNum = _allImages[_currentImgIdex].Lesions.Count; for (int ii = 0; ii < lesionsNum; ii++) { //获取病灶轮廓 int num2 = _allImages[_currentImgIdex].Lesions[ii].Contour.Count; MyPoint[] lesionPts = new MyPoint[num2]; System.Drawing.PointF[] lesionContour = new PointF[num2]; for (int i = 0; i < num2; i++) { lesionPts[i].x = _allImages[_currentImgIdex].Lesions[ii].Contour[i].x; lesionPts[i].y = _allImages[_currentImgIdex].Lesions[ii].Contour[i].y; lesionContour[i].X = _allImages[_currentImgIdex].Lesions[ii].Contour[i].x; lesionContour[i].Y = _allImages[_currentImgIdex].Lesions[ii].Contour[i].y; } EchoPattern echoGT = (EchoPattern)(_allImages[_currentImgIdex].Lesions[ii].EchoPattern) + 1; Boundary boundaryGT = (Boundary)(_allImages[_currentImgIdex].Lesions[ii].Boundary) + 1; MarginEnum marginGT = (MarginEnum)(_allImages[_currentImgIdex].Lesions[ii].Margin) + 1; ContourShape shapeCppGT = (ContourShape)(_allImages[_currentImgIdex].Lesions[ii].Shape) + 1; Orientation orientationGT = (Orientation)(_allImages[_currentImgIdex].Lesions[ii].Orientation) + 1; LesionDescriNow desCpp = new LesionDescriNow(); desCpp.echo = 0; desCpp.shape = 0; desCpp.margin = 0; desCpp.boundary = 0; desCpp.orientation = 0; desCpp.calcification = 0; //desCpp.echogenicFoci = 0; AxisPoint axisPtGt; axisPtGt = new AxisPoint(); axisPtGt.horizontalPt1 = new MyPoint { x = 0, y = 0 }; axisPtGt.horizontalPt2 = new MyPoint { x = 0, y = 0 }; axisPtGt.verticalPt1 = new MyPoint { x = 0, y = 0 }; axisPtGt.verticalPt2 = new MyPoint { x = 0, y = 0 }; System.Drawing.PointF[] axisH = new PointF[2]; System.Drawing.PointF[] axisV = new PointF[2]; //WriteTxtToFile("E:\\image\\", "usename.txt", name, false); System.Drawing.Rectangle rect = new System.Drawing.Rectangle(0, 0, 0, 0); SegDataInput data = new SegDataInput(_currentimg, rect); DesDataInput desData = new DesDataInput(data.InputImage, data.InputRoi, lesionContour); //roiCoor lesionRectPr = new roiCoor(); //DescriptionLesionsRect(_currentimg.Width, _currentimg.Height, lesionPts, lesionPts.Length, ref lesionRectPr); //AxisPoint axisPt = new AxisPoint(); //MyLesionAxisProcess(lesionRectPr, lesionPts.Length, lesionPts, ref axisPt); var starttime = Environment.TickCount; /// 病灶轮廓描述 GCHandle hObjectContour = GCHandle.Alloc(lesionPts, GCHandleType.Pinned); IntPtr pObjectContour = hObjectContour.AddrOfPinnedObject(); AxisPoint axisPt = new AxisPoint(); roiCoor lesionRectPr = new roiCoor(); DescriptionLesionsRect(_currentimg.Width, _currentimg.Height, lesionPts, lesionPts.Length, ref lesionRectPr); MyLesionAxisProcess(lesionRectPr, lesionPts.Length, lesionPts, ref axisPt); axisPtGt = axisPt; if (hObjectContour.IsAllocated) { hObjectContour.Free(); } LesionDescriptionResult lesionDescr = ImageUtility.BreastDescription(desData, axisPtGt); var endtime = Environment.TickCount; Dispatcher.BeginInvoke(DispatcherPriority.Normal, new Action(() => { ElapsedTime.Text = (endtime - starttime).ToString(); })); int shapeDescri = lesionDescr.Shape; // 形状描述 int orientation = lesionDescr.Orientation; // 生长方向 int echoType = lesionDescr.Echo ; // 回声类型 int boundarySharpness = lesionDescr.Boundary; // 边界清晰度 int margin = lesionDescr.Margin; // 边缘光整度 int calcification = lesionDescr.Calcification; // 钙化 AxisPoint axisPoint = axisPtGt; // 纵、横轴端点坐标 MyPoint pt1 = axisPoint.horizontalPt1; // 横轴 MyPoint pt2 = axisPoint.horizontalPt2; MyPoint pt3 = axisPoint.verticalPt1; // 纵轴 MyPoint pt4 = axisPoint.verticalPt2; axisH[0].X = pt1.x; axisH[0].Y = pt1.y; axisH[1].X = pt2.x; axisH[1].Y = pt2.y; axisV[0].X = pt3.x; axisV[0].Y = pt3.y; axisV[1].X = pt4.x; axisV[1].Y = pt4.y; int resCa = -1; int resEcho = -1; int resShape = -1; //Dispatcher.BeginInvoke(DispatcherPriority.Normal, new Action(() => { if (shapeDescri == (int)ContourShape.Oval) { ContourShapeDescriPr.Text = "椭圆形"; } else if (shapeDescri == (int)ContourShape.Round) { ContourShapeDescriPr.Text = "类圆形"; } else if (shapeDescri == (int)ContourShape.Irregular) { ContourShapeDescriPr.Text = "不规则形"; } else if (shapeDescri == (int)ContourShape.NoneShape) { ContourShapeDescriPr.Text = "未标注"; } if (orientation == (int)Orientation.NonParallel) { GrowDirectionDescriPr.Text = "非平行"; } else if (orientation == (int)Orientation.Parallel) { GrowDirectionDescriPr.Text = "平行"; } else if (orientation == (int)Orientation.NoneOrientation) { GrowDirectionDescriPr.Text = "未标注"; } if (echoType == (int)EchoPattern.Anechoic) // 1无回声 { EchoPatternDescriPr.Text = "无回声"; } else if (echoType == (int)EchoPattern.Hypoechoic) // 2低回声 { EchoPatternDescriPr.Text = "低回声"; } else if (echoType == (int)EchoPattern.Complex) // 5混合回声 { EchoPatternDescriPr.Text = "混合回声"; } else if (echoType == (int)EchoPattern.NoneEcho) { EchoPatternDescriPr.Text = "未标注"; } // 边界清晰度 if (boundarySharpness == (int)Boundary.AbruptInterface) { BoundaryBoundaryDescriPr.Text = "清晰"; } else if (boundarySharpness == (int)Boundary.EchogenicHalo) { BoundaryBoundaryDescriPr.Text = "不清晰"; } else if (boundarySharpness == (int)Boundary.NoneBoundary) { BoundaryBoundaryDescriPr.Text = "未标注"; } // 边缘光整度 if (margin == (int)SegmentDescribDemo.MarginEnum.Circumscribed) { EdgeMarginDescriPr.Text = "光整"; } else if (margin == (int)SegmentDescribDemo.MarginEnum.NonCircumscribed) { EdgeMarginDescriPr.Text = "不光整"; } else if (margin == (int)SegmentDescribDemo.MarginEnum.NoneMargin) { EdgeMarginDescriPr.Text = "未标注"; } /////////////////////////////////////////////////////////// if (shapeCppGT == ContourShape.Oval) { ContourShapeDescri.Text = "椭圆形"; } else if (shapeCppGT == ContourShape.Round) { ContourShapeDescri.Text = "类圆形"; } else if (shapeCppGT == ContourShape.Irregular) { ContourShapeDescri.Text = "不规则形"; } else if (shapeCppGT == ContourShape.NoneShape) { ContourShapeDescri.Text = "未标注"; } if (orientationGT == Orientation.NonParallel) { GrowDirectionDescri.Text = "非平行"; } else if (orientationGT == Orientation.Parallel) { GrowDirectionDescri.Text = "平行"; } else if (orientationGT == Orientation.NoneOrientation) { GrowDirectionDescri.Text = "未标注"; } if (echoGT == EchoPattern.Anechoic) // 1无回声 { EchoPatternDescri.Text = "无回声"; } else if (echoGT == EchoPattern.Hypoechoic) // 2低回声 { EchoPatternDescri.Text = "低回声"; } else if (echoGT == EchoPattern.Complex) // 5混合回声 { EchoPatternDescri.Text = "混合回声"; } else if (echoGT == EchoPattern.NoneEcho) { EchoPatternDescri.Text = "未标注"; } // 边界清晰度 if (boundaryGT == Boundary.AbruptInterface) { BoundaryBoundaryDescri.Text = "清晰"; } else if (boundaryGT == Boundary.EchogenicHalo) { BoundaryBoundaryDescri.Text = "不清晰"; } else if (boundaryGT == Boundary.NoneBoundary) { BoundaryBoundaryDescri.Text = "未标注"; } // 边缘光整度 if (marginGT == SegmentDescribDemo.MarginEnum.Circumscribed) { EdgeMarginDescri.Text = "光整"; } else if (marginGT == SegmentDescribDemo.MarginEnum.NonCircumscribed) { EdgeMarginDescri.Text = "不光整"; } else if (marginGT == SegmentDescribDemo.MarginEnum.NoneMargin) { EdgeMarginDescri.Text = "未标注"; } } ////)); //////////////// //string newPath = System.IO.Path.Combine(_currentPath, "result"); //if (resShape == 0) //{ // string nameSave = newPath + "\\00\\" + name + ".jpg"; // if (shapeCppGT == ShapeEnum.WiderThanTall) // { // //_currentImg.Save(nameSave, System.Drawing.Imaging.ImageFormat.Jpeg); // } //} //else if (resShape == 1) //{ // string nameSave = newPath + "\\01\\" + name + ".jpg"; // if (shapeCppGT == ShapeEnum.WiderThanTall) // { // // _currentImg.Save(nameSave, System.Drawing.Imaging.ImageFormat.Jpeg); // } // //_currentImg.Save(nameSave, System.Drawing.Imaging.ImageFormat.Jpeg); //} //if (echoFociGT == echoFoci) //{ // if (echoFoci == EchogenicFociEnum.NoCifications) // { // _NoCifications_NoCifications_num++; // //result = 1; // } // if (echoFoci == EchogenicFociEnum.Coarsecalcifications) // { // _Coarsecalcifications_Coarsecalcifications_num++; // //result = 2; // } // if (echoFoci == EchogenicFociEnum.Microcalcifications) // { // _Macrocalcifications_Macrocalcifications_num++; // //result = 3; // } //} //else //{ // if (echoFociGT == EchogenicFociEnum.NoCifications && echoFoci == EchogenicFociEnum.Coarsecalcifications) // { // _NoCifications_Coarsecalcifications_num++; // //result = 4; // } // if (echoFociGT == EchogenicFociEnum.NoCifications && echoFoci == EchogenicFociEnum.Microcalcifications) // { // _NoCifications_Macrocalcifications_num++; // //result = 5; // } // if (echoFociGT == EchogenicFociEnum.Coarsecalcifications && echoFoci == EchogenicFociEnum.NoCifications) // { // _Coarsecalcifications_NoCifications_num++; // //result = 6; // } // if (echoFociGT == EchogenicFociEnum.Coarsecalcifications && echoFoci == EchogenicFociEnum.Microcalcifications) // { // _Coarsecalcifications_Macrocalcifications_num++; // //result = 7; // } // if (echoFociGT == EchogenicFociEnum.Microcalcifications && echoFoci == EchogenicFociEnum.NoCifications) // { // _Macrocalcifications_NoCifications_num++; // //result = 8; // } // if (echoFociGT == EchogenicFociEnum.Microcalcifications && echoFoci == EchogenicFociEnum.Coarsecalcifications) // { // _Macrocalcifications_Coarsecalcifications_num++; // //result = 9; // } //} if ((int)echoGT == echoType) { if (echoType == (int)EchoPattern.Anechoic) { _Anechoic_Anechoi_num++; } if (echoType == (int)EchoPattern.Hyperechoic) { _Hyperechoic_Hyperechoic_num++; } if (echoType == (int)EchoPattern.Isoechoic) { _Isoechoic_Isoechoic_num++; } if (echoType == (int)EchoPattern.Hypoechoic) { _Hypoechoic_Hypoechoic_num++; } if (echoType == (int)EchoPattern.Complex) { _HypoechoicLower_HypoechoicLower_num++; } } else { //把无回声判为其它 if (echoGT == EchoPattern.Anechoic && echoType == (int)EchoPattern.Hyperechoic) { _Anechoic_Hyperechoic_num++; } if (echoGT == EchoPattern.Anechoic && echoType == (int)EchoPattern.Isoechoic) { _Anechoic_Isoechoic_num++; } if (echoGT == EchoPattern.Anechoic && echoType == (int)EchoPattern.Hypoechoic) { _Anechoic_Hypoechoic_num++; } if (echoGT == EchoPattern.Anechoic && echoType == (int)EchoPattern.Complex) { _Anechoic_HypoechoicLower_num++; } //把高回声判为其它 if (echoGT == EchoPattern.Hyperechoic && echoType == (int)EchoPattern.Anechoic) { _Hyperechoic_Anechoic_num++; } if (echoGT == EchoPattern.Hyperechoic && echoType == (int)EchoPattern.Isoechoic) { _Hyperechoic_Isoechoic_num++; } if (echoGT == EchoPattern.Hyperechoic && echoType == (int)EchoPattern.Hypoechoic) { _Hyperechoic_Hypoechoic_num++; } if (echoGT == EchoPattern.Hyperechoic && echoType == (int)EchoPattern.Complex) { _Hyperechoic_HypoechoicLower_num++; } //把等回声判为其它 if (echoGT == EchoPattern.Isoechoic && echoType == (int)EchoPattern.Anechoic) { _Isoechoic_Anechoic_num++; } if (echoGT == EchoPattern.Isoechoic && echoType == (int)EchoPattern.Hyperechoic) { _Isoechoic_Hyperechoic_num++; } if (echoGT == EchoPattern.Isoechoic && echoType == (int)EchoPattern.Hypoechoic) { _Isoechoic_Hypoechoic_num++; } if (echoGT == EchoPattern.Isoechoic && echoType == (int)EchoPattern.Complex) { _Isoechoic_HypoechoicLower_num++; } //低回声判为其它 if (echoGT == EchoPattern.Hypoechoic && echoType == (int)EchoPattern.Anechoic) { _Hypoechoic_Anechoic_num++; } if (echoGT == EchoPattern.Hypoechoic && echoType == (int)EchoPattern.Hyperechoic) { _Hypoechoic_Hyperechoic_num++; } if (echoGT == EchoPattern.Hypoechoic && echoType == (int)EchoPattern.Isoechoic) { _Hypoechoic_Isoechoic_num++; } if (echoGT == EchoPattern.Hypoechoic && echoType == (int)EchoPattern.Complex) { _Hypoechoic_HypoechoicLower_num++; } } if ((int)shapeCppGT == shapeDescri) { if (shapeDescri == (int)ContourShape.Oval) // 椭圆 { _Oval_Oval_num++; } if (shapeDescri == (int)ContourShape.Round) // 类圆 { _Round_Round_num++; } if (shapeDescri == (int)ContourShape.Irregular)// 不规则 { _Irregular_Irregular_num++; } } else { //把 宽大于高 判为 高大于宽 if (shapeCppGT == ContourShape.Oval && shapeDescri == (int)ContourShape.Round) { _Oval_Round_num++; } if (shapeCppGT == ContourShape.Oval && shapeDescri == (int)ContourShape.Irregular) { _Oval_Irregular_num++; } if (shapeCppGT == ContourShape.Round && shapeDescri == (int)ContourShape.Oval) { _Round_Oval_num++; } if (shapeCppGT == ContourShape.Round && shapeDescri == (int)ContourShape.Irregular) { _Round_Irregular_num++; } if (shapeCppGT == ContourShape.Irregular && shapeDescri == (int)ContourShape.Oval) { _Irregular_Oval_num++; } if (shapeCppGT == ContourShape.Irregular && shapeDescri == (int)ContourShape.Round) { _Irregular_Round_num++; } } if ((int)marginGT == margin) { if (margin == (int)MarginEnum.Circumscribed) { _Circumscribed_Circumscribed_num++; } if (margin == (int)MarginEnum.NonCircumscribed) { _NonCircumscribed_NonCircumscribed_num++; } } else { //把 边缘光整 判成其它 if (marginGT == MarginEnum.Circumscribed && margin == (int)MarginEnum.NonCircumscribed) { _Circumscribed_NonCircumscribed_num++; } if (marginGT == MarginEnum.NonCircumscribed && margin == (int)MarginEnum.Circumscribed) { _NonCircumscribed_Circumscribed_num++; } } if ((int)boundaryGT == boundarySharpness) { if (boundarySharpness == (int)Boundary.AbruptInterface) { _AbruptInterface_AbruptInterface_num++; } if (boundarySharpness == (int)Boundary.EchogenicHalo) { _EchogenicHalo_EchogenicHalo_num++; } } else { //把 边界清晰 判成其它 if (boundaryGT == Boundary.AbruptInterface && boundarySharpness == (int)Boundary.EchogenicHalo) { _AbruptInterface_EchogenicHalo_num++; } if (boundaryGT == Boundary.EchogenicHalo && boundarySharpness == (int)Boundary.AbruptInterface) { _EchogenicHalo_AbruptInterface_num++; } } if ((int)orientationGT == orientation) { if (orientation == (int)Orientation.Parallel) { _Parallel_Parallel_num++; } if (orientation == (int)Orientation.NonParallel) { _NonParallel_NonParallel_num++; } } else { //把 边界清晰 判成其它 if (orientationGT == Orientation.Parallel && orientation == (int)Orientation.NonParallel) { _Parallel_NonParallel_num++; } if (orientationGT == Orientation.NonParallel && orientation == (int)Orientation.Parallel) { _NonParallel_Parallel_num++; } } //using (var g = Graphics.FromImage(oriimage)) //{ // System.Drawing.Pen pen3 = new System.Drawing.Pen(System.Drawing.Brushes.Navy, 2); // Rectangle lesionBox = new Rectangle(roi.x, roi.y, roi.width, roi.height); // g.DrawRectangle(pen3, lesionBox); //画病灶矩形框 // if (lesionContour.Length > 5) // { // System.Drawing.Pen pen = new System.Drawing.Pen(System.Drawing.Brushes.Orange, 2); // g.DrawLines(pen, lesionContour); //画病灶轮廓 // System.Drawing.Pen pen2 = new System.Drawing.Pen(System.Drawing.Brushes.SeaGreen, 2); // if (lesionPts.Length > 0) // { // //g.DrawLines(pen2, lesionPts); //画肝脏轮廓 // } // pen.Dispose(); // } // //画轮廓的长短轴 // System.Drawing.Pen pen_h = new System.Drawing.Pen(System.Drawing.Brushes.PaleGreen, 2); // g.DrawLines(pen_h, axisH); //横轴,浅绿色 // System.Drawing.Pen pen_v = new System.Drawing.Pen(System.Drawing.Brushes.Red, 1); // g.DrawLines(pen_v, axisV); //纵轴,红色 // g.Dispose(); //} using (var g = Graphics.FromImage(dstimage)) { System.Drawing.Pen pen3 = new System.Drawing.Pen(System.Drawing.Brushes.Navy, 2); System.Drawing.Rectangle lesionBox = new System.Drawing.Rectangle(roi.x, roi.y, roi.width, roi.height); g.DrawRectangle(pen3, lesionBox); //画病灶矩形框 if (lesionContour.Length > 5) { System.Drawing.Pen pen = new System.Drawing.Pen(System.Drawing.Brushes.Orange, 2); g.DrawLines(pen, lesionContour); //画病灶轮廓 System.Drawing.Pen pen2 = new System.Drawing.Pen(System.Drawing.Brushes.SeaGreen, 2); if (lesionPts.Length > 0) { //g.DrawLines(pen2, lesionPts); //画肝脏轮廓 } pen.Dispose(); } //画轮廓的长短轴 System.Drawing.Pen pen_h = new System.Drawing.Pen(System.Drawing.Brushes.PaleGreen, 2); g.DrawLines(pen_h, axisH); //横轴,浅绿色 System.Drawing.Pen pen_v = new System.Drawing.Pen(System.Drawing.Brushes.Red, 1); g.DrawLines(pen_v, axisV); //纵轴,红色 g.Dispose(); } } _dstimg = ImageUtility.BitmapToBitmapImage(dstimage); Dispatcher.BeginInvoke(DispatcherPriority.Normal, new Action(() => { DstImage.Source = _dstimg; })); //oriimage.Dispose(); dstimage.Dispose(); } else { MessageBox.Show("未读取到病灶!"); } } private void OnModelsProcessClick(object sender, RoutedEventArgs e) { OpenFileDialog openFileDialog = new OpenFileDialog(); openFileDialog.Filter = "图片文件|*.png;*.bmp;*.jpg;*.jpeg"; openFileDialog.Multiselect = false; openFileDialog.Title = "选择一幅图像"; if (openFileDialog.ShowDialog() ?? false) { Bitmap img = new Bitmap(openFileDialog.FileName); _imagesReadyToDrawBox.Enqueue(img); _currentimg = img; var filename = openFileDialog.FileName; int idx = openFileDialog.FileName.LastIndexOf("\\"); string temp = filename.Substring(idx); string[] strs1 = temp.Split('\\'); temp = strs1[1]; string[] sArray = null; sArray = System.Text.RegularExpressions.Regex.Split(temp, ".jpg", System.Text.RegularExpressions.RegexOptions.IgnoreCase); string ImgId = sArray[0]; //WriteTxtToFile("E:\\image\\", "name.txt", ImgId, false); _currentImgId = ImgId; int imgIdx = _allImages.FindIndex(x => x.ImageId == _currentImgId); _currentImgIdex = imgIdx; if (imgIdx < 0) { //return; //continue; } else { _currentImgIdex = imgIdx; } DescriAlgorithmModelAll(img, openFileDialog.FileName); } string tmp = System.IO.Path.GetFileNameWithoutExtension(openFileDialog.FileName); _imgNameQueue.Enqueue(tmp); } private void OnLoadOneImageDBClick(object sender, RoutedEventArgs e) { } //单张处理图像对应的函数 private unsafe void DescriAlgorithmModelAll(Bitmap bmp, string name) { if (bmp == null) { //MessageBox.Show("请先加载待测图像!"); return; } var rawImage = RawImageShowUtils.BitmapToRawImage(bmp); _caseId = Guid.NewGuid().ToString(); _dataId = name; _readingVideo = false; var extendData = new Dictionary(); extendData.Add("CaseId", _caseId); extendData.Add("DataId", _dataId); extendData.Add("IsVideo", _readingVideo); extendData.Add("TimeStamp", (double)_frameIndex); _processId = _module.StartProcess(); var input = new ImageInputData(rawImage, extendData); IDetectedObject[] result = _module.PushOnePieceOfData(_processId, input); _module.EndProcess(_processId); Bitmap dstimage = (Bitmap)_currentimg.Clone(); Bitmap oriimage = (Bitmap)_currentimg.Clone(); int lesionNum = 0; string strDescriptionEcho = string.Empty; string strDescriptionShape = string.Empty; string strDescriptionMargin = string.Empty; string strDescriptionEchogenicFoci = string.Empty; System.Drawing.PointF[] axisH = new PointF[2]; System.Drawing.PointF[] axisV = new PointF[2]; foreach (var moduleResult in result) { var label = moduleResult.Label; var nameOrgan = label.GroupName; if(nameOrgan != "AI.Vaid.Breast.Lesion") { continue; } if (moduleResult.Contour == null || moduleResult.Measurements == null || moduleResult.Description == null) { continue; } var resultConversion = AIModuleResultShowUtils.GetObjectStr(moduleResult); if (moduleResult.Contour?.Contours.Length > 0) { //ShowContour(moduleResult.Contour, brush, null, transform); int count = moduleResult.Contour.Contours.Length; for (int i = 0; i < count; i++) { var contourPoints = moduleResult.Contour.Contours[i]; int pointCount = contourPoints.Points.Length; var points = new List(); System.Drawing.PointF[] lesionContour = new PointF[pointCount]; for (int j = 0; j < pointCount; j++) { var point = new System.Windows.Point(contourPoints.Points[j].X, contourPoints.Points[j].Y); lesionContour[j].X = contourPoints.Points[j].X; lesionContour[j].Y = contourPoints.Points[j].Y; } var desResult = moduleResult.Description; var type = desResult.GetType(); string strDescription = string.Empty; //if (type == typeof(BreastLesionDescription)) { foreach (var key in desResult.Descriptions.Keys) { if (key == "Shape") { string des = string.Empty; switch (desResult.Descriptions[key]) { case "Oval": des = "椭圆形"; break; case "Round": des = "类圆形"; break; case "Irregular": des = "不规则形"; break; } strDescription += "形状:" + des + Environment.NewLine; } if (key == "Orientation") { string des = string.Empty; switch (desResult.Descriptions[key]) { case "Parallel": des = "平行"; break; case "NonParallel": des = "非平行"; break; } strDescription += "生长方向:" + des + Environment.NewLine; } if (key == "EchoPattern") { string des = string.Empty; switch (desResult.Descriptions[key]) { case "Anechoic": des = "无回声"; break; case "Hypoechoic": des = "低回声"; break; case "Isoechoic": des = "等回声"; break; case "Hyperechoic": des = "高回声"; break; case "Complex": des = "混合回声"; break; } strDescription += "回声类型:" + des + Environment.NewLine; } if (key == "Boundary") { string des = string.Empty; switch (desResult.Descriptions[key]) { case "AbruptInterface": des = "清晰"; break; case "EchogenicHalo": des = "模糊"; break; } strDescription += "边界:" + des + Environment.NewLine; } if (key == "Margin") { string des = string.Empty; switch (desResult.Descriptions[key]) { case "Circumscribed": des = "光整"; break; case "NonCircumscribed": des = "不光整"; break; } strDescription += "边缘:" + des + Environment.NewLine; } if (key == "Calcification") { string des = string.Empty; switch (desResult.Descriptions[key]) { case "NoCalcifications": des = "无钙化"; break; case "Macrocalcifications": des = "粗钙化"; break; case "Microcalcifications": des = "微钙化"; break; } strDescription += "钙化:" + des + Environment.NewLine; } if(key == "PosteriorAcousticFeature") { string des = string.Empty; switch (desResult.Descriptions[key]) { case "Shadowing": des = "衰减"; _Shadowing++; break; case "Enhancement": des = "增强"; _Enhancement++; break; case "Absent": des = "无改变"; _Absent++; break; case "Combined": des = "混合"; _Combined++; break; } strDescription += "后部声学特征:" + des + Environment.NewLine; } } } var rect = moduleResult.BoundingBox.Contour.BoundingBox(); var roiBox = moduleResult.BoundingBox; var ss = roiBox.Contour.Points; var lesionSize = Array.Find(moduleResult.Measurements, x => x.GetType() == typeof(TransverseLongitudinalDiameterMeasurement)); var size = (TransverseLongitudinalDiameterMeasurement)lesionSize; var pointLineH1 = new System.Windows.Point(size.TransverseDiameterMarkPosition.LineStart.X, size.TransverseDiameterMarkPosition.LineStart.Y); var pointLineH2 = new System.Windows.Point(size.TransverseDiameterMarkPosition.LineEnd.X, size.TransverseDiameterMarkPosition.LineEnd.Y); var pointLineV1 = new System.Windows.Point(size.LongitudinalDiameterMarkPosition.LineStart.X, size.LongitudinalDiameterMarkPosition.LineStart.Y); var pointLineV2 = new System.Windows.Point(size.LongitudinalDiameterMarkPosition.LineEnd.X, size.LongitudinalDiameterMarkPosition.LineEnd.Y); axisH[0].X = (int)pointLineH1.X; axisH[0].Y = (int)pointLineH1.Y; axisH[1].X = (int)pointLineH2.X; axisH[1].Y = (int)pointLineH2.Y; axisV[0].X = (int)pointLineV1.X; axisV[0].Y = (int)pointLineV1.Y; axisV[1].X = (int)pointLineV2.X; axisV[1].Y = (int)pointLineV2.Y; using (var g = Graphics.FromImage(dstimage)) { System.Drawing.Pen pen3 = new System.Drawing.Pen(System.Drawing.Brushes.Navy, 2); System.Drawing.Rectangle lesionBox = new System.Drawing.Rectangle(rect.Left, rect.Top, rect.Right - rect.Left, rect.Bottom - rect.Top); g.DrawRectangle(pen3, lesionBox); //画病灶矩形框 if (lesionContour.Length > 1)//画直线要超过一个点 { System.Drawing.Pen pen = new System.Drawing.Pen(System.Drawing.Brushes.Orange, 2); g.DrawLines(pen, lesionContour); //画病灶轮廓 pen.Dispose(); } //画轮廓的长短轴 System.Drawing.Pen pen_h = new System.Drawing.Pen(System.Drawing.Brushes.PaleGreen, 2); g.DrawLines(pen_h, axisH); //横轴,浅绿色 System.Drawing.Pen pen_v = new System.Drawing.Pen(System.Drawing.Brushes.Red, 1); g.DrawLines(pen_v, axisV); //纵轴,红色 SolidBrush drawBrush = new SolidBrush(System.Drawing.Color.GreenYellow); g.DrawString(lesionNum.ToString(), new Font("Arial", 20), drawBrush, lesionBox.Left, lesionBox.Top); g.DrawString(strDescription, new Font("Arial", 20), drawBrush, rect.Top + 10, rect.Top + 10); g.Dispose(); } } } } EchoPatternDescri.Text = strDescriptionEcho; //ShapeDescri.Text = strDescriptionShape; //MarginDescri.Text = strDescriptionMargin; //EchogenicFociDescri.Text = strDescriptionEchogenicFoci; _dstimg = ImageUtility.BitmapToBitmapImage(dstimage); Dispatcher.BeginInvoke(DispatcherPriority.Normal, new Action(() => { DstImage.Source = _dstimg; })); dstimage.Dispose(); _origimg = ImageUtility.BitmapToBitmapImage(oriimage); Dispatcher.BeginInvoke(DispatcherPriority.Normal, new Action(() => { //OrigImage.Source = _origimg; ImageUpdated(); })); oriimage.Dispose(); //return result; } private void OnModelsProcessAllClick(object sender, RoutedEventArgs e) { OpenFileDialog openFileDialog = new OpenFileDialog(); openFileDialog.Filter = "图片文件|*.png;*.bmp;*.jpg;*.jpeg"; openFileDialog.Multiselect = true; openFileDialog.Title = "选择一幅或多幅图像"; if (openFileDialog.ShowDialog() ?? false) { foreach (string filename in openFileDialog.FileNames) { Bitmap img = new Bitmap(filename); _currentimg = img; string temp; int idx = filename.LastIndexOf("\\"); temp = filename.Substring(idx); string[] strs1 = temp.Split('\\'); temp = strs1[1]; //string[] strs2 = temp.Split(new char[4] { '.', 'j', 'p', 'g' }, 2); //string ImgId = strs2[0]; string[] sArray = null; sArray = System.Text.RegularExpressions.Regex.Split(temp, ".jpg", System.Text.RegularExpressions.RegexOptions.IgnoreCase); string ImgId = sArray[0]; //WriteTxtToFile("E:\\image\\", "name.txt", ImgId, false); _currentImgId = ImgId; int imgIdx = _allImages.FindIndex(x => x.ImageId == _currentImgId); //if (imgIdx < 0) //{ // //return; // //continue; //} //else { _currentImgIdex = imgIdx; //DoDescriAlgorithm(ImgId); DescriAlgorithmModelAll(img, openFileDialog.FileName); } } } Console.WriteLine("衰减: " + _Shadowing); Console.WriteLine("增强: " + _Enhancement); Console.WriteLine("无改变: " + _Absent); Console.WriteLine("混合: " + _Combined); Console.WriteLine(); } private void OnDrawImageDBClick(object sender, RoutedEventArgs e) { OpenFileDialog openFileDialog = new OpenFileDialog(); openFileDialog.Filter = "图片文件|*.png;*.bmp;*.jpg;*.jpeg"; openFileDialog.Multiselect = true; openFileDialog.Title = "选择一幅或多幅图像"; if (openFileDialog.ShowDialog() ?? false) { foreach (string filename in openFileDialog.FileNames) { Bitmap img = new Bitmap(filename); _currentimg = img; string temp; int idx = filename.LastIndexOf("\\"); temp = filename.Substring(idx); string[] strs1 = temp.Split('\\'); temp = strs1[1]; //string[] strs2 = temp.Split(new char[4] { '.', 'j', 'p', 'g' }, 2); //string ImgId = strs2[0]; string[] sArray = null; sArray = System.Text.RegularExpressions.Regex.Split(temp, ".jpg", System.Text.RegularExpressions.RegexOptions.IgnoreCase); string ImgId = sArray[0]; //WriteTxtToFile("E:\\image\\", "name.txt", ImgId, false); _currentImgId = ImgId; int imgIdx = _allImages.FindIndex(x => x.ImageId == _currentImgId); if (imgIdx < 0) { //return; continue; } else { _currentImgIdex = imgIdx; //DoDescriAlgorithm(ImgId); if (_currentimg == null) { MessageBox.Show("请先加载待测图像!"); return; } Bitmap bmp = _currentimg; //RawImage rawImg = BitmapToRawImage(bmp); roiCoor roi; roi.x = 0; roi.y = 0; roi.width = _currentimg.Width; roi.height = _currentimg.Height; int LesionsNum = _allImages[_currentImgIdex].Lesions.Count; //确定存在病灶 if (LesionsNum > 0) { Bitmap dstimage = (Bitmap)_currentimg.Clone(); //Bitmap oriimage = (Bitmap)_currentimg.Clone(); int lesionsNum = _allImages[_currentImgIdex].Lesions.Count; for (int ii = 0; ii < lesionsNum; ii++) { //获取病灶轮廓 int num2 = _allImages[_currentImgIdex].Lesions[ii].Contour.Count; MyPoint[] lesionPts = new MyPoint[num2]; System.Drawing.PointF[] lesionContour = new PointF[num2]; for (int i = 0; i < num2; i++) { lesionPts[i].x = _allImages[_currentImgIdex].Lesions[ii].Contour[i].x; lesionPts[i].y = _allImages[_currentImgIdex].Lesions[ii].Contour[i].y; lesionContour[i].X = _allImages[_currentImgIdex].Lesions[ii].Contour[i].x; lesionContour[i].Y = _allImages[_currentImgIdex].Lesions[ii].Contour[i].y; } EchoPattern echoGT = (EchoPattern)(_allImages[_currentImgIdex].Lesions[ii].EchoPattern) + 1; Boundary boundaryGT = (Boundary)(_allImages[_currentImgIdex].Lesions[ii].Boundary) + 1; MarginEnum marginGT = (MarginEnum)(_allImages[_currentImgIdex].Lesions[ii].Margin) + 1; ContourShape shapeCppGT = (ContourShape)(_allImages[_currentImgIdex].Lesions[ii].Shape) + 1; Orientation orientationGT = (Orientation)(_allImages[_currentImgIdex].Lesions[ii].Orientation) + 1; int resMar = -1; int resShape = -1; string strDescription = string.Empty; //Dispatcher.BeginInvoke(DispatcherPriority.Normal, new Action(() => { string strName = string.Empty; if (shapeCppGT == ContourShape.Oval) { ContourShapeDescriPr.Text = "椭圆形"; strName = "椭圆形"; resShape = 1; } else if (shapeCppGT == ContourShape.Round) { strName = "类圆形"; ContourShapeDescriPr.Text = strName; resShape = 2; } else if (shapeCppGT == ContourShape.Irregular) { strName = "不规则形"; ContourShapeDescriPr.Text = strName; resShape = 3; } else if (shapeCppGT == ContourShape.NoneShape) { strName = "未标注"; ContourShapeDescriPr.Text = "未标注"; } strDescription += " 形状:" + strName + "\r\n"; strName = string.Empty; if (orientationGT == Orientation.NonParallel) { strName = "非平行"; GrowDirectionDescriPr.Text = "非平行"; } else if (orientationGT == Orientation.Parallel) { strName = "平行"; GrowDirectionDescriPr.Text = "平行"; } else if (orientationGT == Orientation.NoneOrientation) { strName = "未标注"; GrowDirectionDescriPr.Text = "未标注"; } strDescription += " 方向:" + strName + "\r\n"; strName = string.Empty; if (echoGT == EchoPattern.Anechoic) // 1无回声 { strName = "无回声"; EchoPatternDescriPr.Text = "无回声"; } else if (echoGT == EchoPattern.Hypoechoic) // 2低回声 { strName = "低回声"; EchoPatternDescriPr.Text = "低回声"; } else if (echoGT == EchoPattern.Complex) // 5混合回声 { strName = "混合回声"; EchoPatternDescriPr.Text = "混合回声"; } else if (echoGT == EchoPattern.NoneEcho) { strName = "未标注"; EchoPatternDescriPr.Text = "未标注"; } strDescription += " 回声:" + strName + "\r\n"; strName = string.Empty; // 边界清晰度 if (boundaryGT == Boundary.AbruptInterface) { strName = "清晰"; BoundaryBoundaryDescriPr.Text = "清晰"; } else if (boundaryGT == Boundary.EchogenicHalo) { strName = "不清晰"; BoundaryBoundaryDescriPr.Text = "不清晰"; } else if (boundaryGT == Boundary.NoneBoundary) { strName = "未标注"; BoundaryBoundaryDescriPr.Text = "未标注"; } strDescription += " 边界:" + strName + "\r\n"; strName = string.Empty; // 边缘光整度 if (marginGT == SegmentDescribDemo.MarginEnum.Circumscribed) { strName = "光整"; EdgeMarginDescriPr.Text = "光整"; resMar = 1; } else if (marginGT == SegmentDescribDemo.MarginEnum.NonCircumscribed) { strName = "不光整"; EdgeMarginDescriPr.Text = "不光整"; resMar = 2; } else if (marginGT == SegmentDescribDemo.MarginEnum.NoneMargin) { strName = "未标注"; EdgeMarginDescriPr.Text = "未标注"; } strDescription += " 边缘:" + strName + "\r\n"; strName = string.Empty; /////////////////////////////////////////////////////////// } ////)); using (var g = Graphics.FromImage(dstimage)) { System.Drawing.Pen pen3 = new System.Drawing.Pen(System.Drawing.Brushes.Navy, 2); System.Drawing.Rectangle lesionBox = new System.Drawing.Rectangle(roi.x, roi.y, roi.width, roi.height); g.DrawRectangle(pen3, lesionBox); //画病灶矩形框 if (lesionContour.Length > 5) { System.Drawing.Pen pen = new System.Drawing.Pen(System.Drawing.Brushes.Orange, 2); g.DrawLines(pen, lesionContour); //画病灶轮廓 System.Drawing.Pen pen2 = new System.Drawing.Pen(System.Drawing.Brushes.SeaGreen, 2); if (lesionPts.Length > 0) { //g.DrawLines(pen2, lesionPts); //画肝脏轮廓 } pen.Dispose(); } //画轮廓的长短轴 //System.Drawing.Pen pen_h = new System.Drawing.Pen(System.Drawing.Brushes.PaleGreen, 2); //g.DrawLines(pen_h, axisH); //横轴,浅绿色 //System.Drawing.Pen pen_v = new System.Drawing.Pen(System.Drawing.Brushes.Red, 1); //g.DrawLines(pen_v, axisV); //纵轴,红色 SolidBrush drawBrush = new SolidBrush(System.Drawing.Color.GreenYellow); g.DrawString(strDescription, new Font("Arial", 20),drawBrush, roi.x + 10, roi.y + 10); g.Dispose(); } string newPath = System.IO.Path.Combine(_currentPath, "result"); if (resMar == 1) { string nameSave = newPath + "\\01\\" + _currentImgId + ".jpg"; //if (shapeCppGT == ShapeEnum.WiderThanTall) { dstimage.Save(nameSave, System.Drawing.Imaging.ImageFormat.Jpeg); } } else if (resMar == 2) { string nameSave = newPath + "\\02\\" + _currentImgId + ".jpg"; //if (shapeCppGT == ShapeEnum.WiderThanTall) { dstimage.Save(nameSave, System.Drawing.Imaging.ImageFormat.Jpeg); } //_currentImg.Save(nameSave, System.Drawing.Imaging.ImageFormat.Jpeg); } //if (resShape == 1) //{ // string nameSave = newPath + "\\01\\" + _currentImgId + ".jpg"; // //if (shapeCppGT == ShapeEnum.WiderThanTall) // { // dstimage.Save(nameSave, System.Drawing.Imaging.ImageFormat.Jpeg); // } //} //else if (resShape == 2) //{ // string nameSave = newPath + "\\02\\" + _currentImgId + ".jpg"; // //if (shapeCppGT == ShapeEnum.WiderThanTall) // { // dstimage.Save(nameSave, System.Drawing.Imaging.ImageFormat.Jpeg); // } // //_currentImg.Save(nameSave, System.Drawing.Imaging.ImageFormat.Jpeg); //} //else if (resShape == 3) //{ // string nameSave = newPath + "\\03\\" + _currentImgId + ".jpg"; // dstimage.Save(nameSave, System.Drawing.Imaging.ImageFormat.Jpeg); //} } } } } } } } }