123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577 |
- using AI.Common;
- using UsHepatoRenalRatioDetectLib;
- using UsHepatoRenalRatioDetectLib.OrganSegProcessModule;
- using System;
- using System.Collections.Generic;
- using System.Drawing;
- using System.Drawing.Imaging;
- using System.Windows;
- using System.Windows.Controls;
- using System.Windows.Media;
- using System.Windows.Media.Imaging;
- using System.Windows.Threading;
- using static System.Net.Mime.MediaTypeNames;
- using Rect = AI.Common.Rect;
- namespace HepatoRenalEchoContrastDemo
- {
- //public class TestResults
- //{
- // public Point2D[][] Countours { get; set; }
- // public Rect[] Rois { get; set; }
- // public double EchoContastValue { get; set; }
- // public TestResults(Point2D[][] countours, Rect[] rois, double echoContastValue)
- // {
- // Countours = countours;
- // Rois = rois;
- // EchoContastValue = echoContastValue;
- // }
- //}
- public class RoiInfo
- {
- public Rect RoiRect { get; set; }
- public System.Windows.Media.Brush Color { get; set; }
- public RoiInfo(Rect roi, System.Windows.Media.Brush color)
- {
- RoiRect = roi;
- Color = color;
- }
- }
- public class OrganInfo
- {
- public string OrganName { get; set; }
- public Rect BoundingBox { get; set; }
- public Point2D[][] Contours { get; set; }
- public System.Windows.Media.Brush Color => System.Windows.Media.Brushes.Green;
- public OrganInfo(string organName, Rect boundingBox, Point2D[][] contours)
- {
- OrganName = organName;
- BoundingBox = boundingBox;
- Contours = contours;
- }
- }
- public class MyTransform
- {
- public double Scale { get; set; }
- public double OffsetX { get; set; }
- public double OffsetY { get; set; }
- public MyTransform(double scale, double offsetX, double offsetY)
- {
- Scale = scale;
- OffsetX = offsetX;
- OffsetY = offsetY;
- }
- public System.Windows.Point Transform(System.Windows.Point point)
- {
- double x = OffsetX + Scale * point.X;
- double y = OffsetY + Scale * point.Y;
- return new System.Windows.Point(x, y);
- }
- public System.Windows.Rect Transform(System.Windows.Rect rect)
- {
- double left = OffsetX + Scale * rect.Left;
- double top = OffsetY + Scale * rect.Top;
- double width = Scale * rect.Width;
- double height = Scale * rect.Height;
- return new System.Windows.Rect(left, top, width, height);
- }
- }
- /// <summary>
- /// ImageCanvas.xaml 的交互逻辑
- /// </summary>
- public partial class ImageCanvas : UserControl
- {
- #region private variables
- private Bitmap _image;
- private List<RoiInfo> _rois;
- private List<OrganInfo> _organs;
- private volatile bool _showOrgan;
- private volatile bool _showRois;
- private volatile bool _showEchoContastValue;
- private MyTransform _transform;
- private double _echoContrastRatio;
- #endregion
- #region 用户界面响应
- private void CanvasSizeChanged(object sender, System.Windows.SizeChangedEventArgs e)
- {
- UpdateTransforms();
- }
- #endregion
- #region public funcs
- public ImageCanvas()
- {
- InitializeComponent();
- }
- /// <summary>
- /// 设置显示参数
- /// </summary>
- /// <param name="showCountours"></param>
- /// <param name="showRois"></param>
- /// <param name="showeEchoContastValue"></param>
- public void SetShowParams(bool showCountours, bool showRois, bool showeEchoContastValue)
- {
- _showOrgan = showCountours;
- _showRois = showRois;
- _showEchoContastValue = showeEchoContastValue;
- if (_rois != null)
- {
- UpdateRois();
- }
- if (_organs != null)
- {
- UpdateOrgans();
- }
- }
- public void UpdateImage(Bitmap image)
- {
- if (_image != null)
- {
- _image.Dispose();
- }
- _image = image.Clone(new System.Drawing.Rectangle(0, 0, image.Width, image.Height), image.PixelFormat);
- // 更新缩放比例
- UpdateTransforms();
- // 更新图像显示
- var bitmapImage = BitmapToBitmapImage(image);
- Dispatcher.BeginInvoke(DispatcherPriority.Normal, new Action(() =>
- {
- ImageShow.Source = bitmapImage;
- }));
- }
- public void UpdateTestResults(HRRDetectResultPerImg detectedResult)
- {
- List<OrganInfo> organs = new List<OrganInfo>();
- List<RoiInfo> rois = new List<RoiInfo>();
- foreach (var organ in detectedResult.SegResults)
- {
- organs.Add(new OrganInfo(organ.Organ.ToString(), organ.BoundingBox, organ.Contours));
- }
- foreach (var roiDict in detectedResult.Rois)
- {
- rois.Add(new RoiInfo(roiDict.Value, System.Windows.Media.Brushes.Yellow));
- }
- // 删掉旧的Roi和Organ
- RemoveRois();
- RemoveOrgans();
- RemoveText();
- _organs = organs;
- _rois = rois;
- _echoContrastRatio = detectedResult.HepatoRenalRatio;
- // 更新画布上显示的Roi和Organ
- ////////////////////////////////
- double ratio = Math.Round(_echoContrastRatio, 4);
- if (ratio > 0)
- {
- UpdateRois();
- }
- ///////////////////////////////
-
- UpdateOrgans();
- UpdateText();
- }
- public void ClearTestResult()
- {
- // 删掉旧的Roi和Organ
- RemoveRois();
- RemoveOrgans();
- RemoveText();
- // 设置
- _rois = null;
- _organs = null;
- }
- /// <summary>
- /// 将画布上的点转到图像坐标系下
- /// </summary>
- /// <param name="point"></param>
- /// <returns></returns>
- public Point2D TransBack(System.Windows.Point point)
- {
- int x = Convert.ToInt32((point.X - _transform.OffsetX) / _transform.Scale);
- int y = Convert.ToInt32((point.Y - _transform.OffsetY) / _transform.Scale);
- return new Point2D(x, y);
- }
- #endregion
- #region private funcs
- private BitmapImage BitmapToBitmapImage(Bitmap img)
- {
- BitmapImage bmpimg = new BitmapImage();
- using (System.IO.MemoryStream ms = new System.IO.MemoryStream())
- {
- img.Save(ms, ImageFormat.Png);
- bmpimg.BeginInit();
- bmpimg.StreamSource = ms;
- bmpimg.CacheOption = BitmapCacheOption.OnLoad;
- bmpimg.EndInit();
- bmpimg.Freeze();
- ms.Dispose();
- }
- return bmpimg;
- }
- public void RemoveRoiInCanvas(string roiName)
- {
- // 框
- string rectName = "ROI_Rect_" + roiName;
- System.Windows.Shapes.Rectangle rectExist = TestResultCanvas.FindName(rectName) as System.Windows.Shapes.Rectangle;
- if (rectExist != null)
- {
- TestResultCanvas.Children.Remove(rectExist);
- TestResultCanvas.UnregisterName(rectName);
- }
- // 文字
- string textName = "ROI_Text_" + roiName;
- System.Windows.Controls.TextBlock textExist = TestResultCanvas.FindName(textName) as System.Windows.Controls.TextBlock;
- if (textExist != null)
- {
- TestResultCanvas.Children.Remove(textExist);
- TestResultCanvas.UnregisterName(textName);
- }
- }
- private void RemoveOrganInCanvas(OrganInfo organ)
- {
- string organName = organ.OrganName;
- // 框
- string rectName = "Organ_Rect_" + organName;
- System.Windows.Shapes.Rectangle rectExist = TestResultCanvas.FindName(rectName) as System.Windows.Shapes.Rectangle;
- if (rectExist != null)
- {
- TestResultCanvas.Children.Remove(rectExist);
- TestResultCanvas.UnregisterName(rectName);
- }
- // 轮廓
- int count = organ.Contours.Length;
- for (int ni = 0; ni < count; ni++)
- {
- string contourName = "Organ_Contour_" + organName + "_" + ni;
- System.Windows.Shapes.Polygon contourExist = TestResultCanvas.FindName(contourName) as System.Windows.Shapes.Polygon;
- if (contourExist != null)
- {
- TestResultCanvas.Children.Remove(contourExist);
- TestResultCanvas.UnregisterName(contourName);
- }
- }
- // 文字
- string textName = "Organ_Text_" + organName;
- System.Windows.Controls.TextBlock textExist = TestResultCanvas.FindName(textName) as System.Windows.Controls.TextBlock;
- if (textExist != null)
- {
- TestResultCanvas.Children.Remove(textExist);
- TestResultCanvas.UnregisterName(textName);
- }
- }
- public void DrawRoiInCanvas(RoiInfo roi, string roiName)
- {
- if (_transform == null)
- {
- return;
- }
- // 已有则删除
- RemoveRoiInCanvas(roiName);
- // 不显示ROI,则直接退出
- if (!_showRois)
- {
- return;
- }
- // 画框
- var rect = new System.Windows.Rect(roi.RoiRect.Left, roi.RoiRect.Top, roi.RoiRect.Width, roi.RoiRect.Height);
- var transRect = _transform.Transform(rect);
- System.Windows.Shapes.Rectangle rectDraw = new System.Windows.Shapes.Rectangle();
- rectDraw.StrokeThickness = 3;
- rectDraw.Stroke = roi.Color;
- rectDraw.Width = transRect.Width;
- rectDraw.Height = transRect.Height;
- Canvas.SetLeft(rectDraw, transRect.Left);
- Canvas.SetTop(rectDraw, transRect.Top);
- TestResultCanvas.Children.Add(rectDraw);
- string rectName = "ROI_Rect_" + roiName;
- TestResultCanvas.RegisterName(rectName, rectDraw);
- // 将Roi的序号写在左上角
- var pointLT = new System.Windows.Point(roi.RoiRect.Left, roi.RoiRect.Top);
- var transPointLT = _transform.Transform(pointLT);
- var textLeft = transPointLT.X - 16;
- var textTop = transPointLT.Y;
- TextBlock text = new TextBlock();
- text.Text = roiName;
- text.FontSize = 16;
- text.FontWeight = System.Windows.FontWeights.Bold;
- text.Foreground = roi.Color;
- text.VerticalAlignment = System.Windows.VerticalAlignment.Top;
- Canvas.SetLeft(text, textLeft);
- Canvas.SetTop(text, textTop);
- TestResultCanvas.Children.Add(text);
- string textName = "ROI_Text_" + roiName;
- TestResultCanvas.RegisterName(textName, text);
- }
- private void DrawOrganInCanvas(OrganInfo organ)
- {
- if (_transform == null)
- {
- return;
- }
- // 已有则删除
- RemoveOrganInCanvas(organ);
- // 是否显示Organ
- if (!_showOrgan)
- {
- return;
- }
- // 有轮廓就显示轮廓,没有轮廓就显示方框
- string organName = organ.OrganName;
- if (organ.Contours.Length > 0)
- {
- int count = organ.Contours.Length;
- for (int ni = 0; ni < count; ni++)
- {
- Point2D[] contour = organ.Contours[ni];
- PointCollection contourPoints = new PointCollection();
- for (int nj = 0; nj < contour.Length; nj++)
- {
- var point = new System.Windows.Point(contour[nj].X, contour[nj].Y);
- var transPoint = _transform.Transform(point);
- contourPoints.Add(transPoint);
- }
- System.Windows.Shapes.Polygon contourDraw = new System.Windows.Shapes.Polygon();
- contourDraw.Points = contourPoints;
- contourDraw.StrokeThickness = 3;
- contourDraw.Stroke = organ.Color;
- TestResultCanvas.Children.Add(contourDraw);
- string contourName = "Organ_Contour_" + organName + "_" + ni;
- TestResultCanvas.RegisterName(contourName, contourDraw);
- }
- }
- else
- {
- var rect = new System.Windows.Rect(organ.BoundingBox.Left, organ.BoundingBox.Top, organ.BoundingBox.Width, organ.BoundingBox.Height);
- var transRect = _transform.Transform(rect);
- System.Windows.Shapes.Rectangle rectDraw = new System.Windows.Shapes.Rectangle();
- rectDraw.StrokeThickness = 3;
- rectDraw.Stroke = organ.Color;
- rectDraw.Width = transRect.Width;
- rectDraw.Height = transRect.Height;
- Canvas.SetLeft(rectDraw, transRect.Left);
- Canvas.SetTop(rectDraw, transRect.Top);
- TestResultCanvas.Children.Add(rectDraw);
- string rectName = "Organ_Rect_" + organName;
- TestResultCanvas.RegisterName(rectName, rectDraw);
- }
- // 将Organ的序号写在左上角
- var pointLT = new System.Windows.Point(organ.BoundingBox.Left, organ.BoundingBox.Top);
- var transPointLT = _transform.Transform(pointLT);
- var textLeft = transPointLT.X + 16;
- var textTop = transPointLT.Y;
- TextBlock text = new TextBlock();
- text.Text = organName;
- text.FontSize = 16;
- text.FontWeight = System.Windows.FontWeights.Bold;
- text.Foreground = organ.Color;
- text.VerticalAlignment = System.Windows.VerticalAlignment.Top;
- Canvas.SetLeft(text, textLeft);
- Canvas.SetTop(text, textTop);
- TestResultCanvas.Children.Add(text);
- string textName = "Organ_Text_" + organName;
- TestResultCanvas.RegisterName(textName, text);
- }
- private void UpdateTransforms()
- {
- if (_image != null)
- {
- // 使图片保持长宽比例,居中显示,需要平移和缩放
- var imgWidth = _image.Width;
- var imgHeight = _image.Height;
- var canvasWidth = TestResultCanvas.ActualWidth;
- var canvasHeight = TestResultCanvas.ActualHeight;
- var scaleX = canvasWidth / imgWidth;
- var scaleY = canvasHeight / imgHeight;
- var scale = scaleX < scaleY ? scaleX : scaleY;
- double offsetX, offsetY;
- if (Math.Abs(scale - scaleX) < 0.0001)
- {
- offsetY = 0.5 * (scaleY - scale) * imgHeight;
- offsetX = 0;
- }
- else
- {
- offsetX = 0.5 * (scaleX - scale) * imgWidth;
- offsetY = 0;
- }
- _transform = new MyTransform(scale, offsetX, offsetY);
- }
- }
- private void RemoveRois()
- {
- Dispatcher.Invoke(DispatcherPriority.Normal, new Action(() =>
- {
- // 移除所有旧的ROI
- if (_rois != null)
- {
- for (int ni = 0; ni < _rois.Count; ni++)
- {
- RemoveRoiInCanvas(ni.ToString());
- }
- }
- }));
- }
- private void RemoveOrgans()
- {
- Dispatcher.Invoke(DispatcherPriority.Normal, new Action(() =>
- {
- // 移除所有旧的Organ
- if (_organs != null)
- {
- for (int ni = 0; ni < _organs.Count; ni++)
- {
- RemoveOrganInCanvas(_organs[ni]);
- }
- }
- }));
- }
- private void RemoveText()
- {
- Dispatcher.Invoke(DispatcherPriority.Normal, new Action(() =>
- {
- // 文字
- string textName = "Ratio";
- System.Windows.Controls.TextBlock textExist = TestResultCanvas.FindName(textName) as System.Windows.Controls.TextBlock;
- if (textExist != null)
- {
- TestResultCanvas.Children.Remove(textExist);
- TestResultCanvas.UnregisterName(textName);
- }
- }));
- }
- private void UpdateRois()
- {
- Dispatcher.Invoke(DispatcherPriority.Normal, new Action(() =>
- {
- if (_rois != null)
- {
- for (int ni = 0; ni < _rois.Count; ni++)
- {
- DrawRoiInCanvas(_rois[ni], ni.ToString());
- }
- }
- }));
- }
- private void UpdateOrgans()
- {
- Dispatcher.Invoke(DispatcherPriority.Normal, new Action(() =>
- {
- if (_organs != null)
- {
- for (int ni = 0; ni < _organs.Count; ni++)
- {
- DrawOrganInCanvas(_organs[ni]);
- }
- }
- }));
- }
- private void UpdateText()
- {
- Dispatcher.Invoke(DispatcherPriority.Normal, new Action(() =>
- {
- if (_transform == null)
- {
- return;
- }
- // 已有则删除
- RemoveText();
- // 不显示ROI,则直接退出
- if (!_showRois)
- {
- return;
- }
- var pointLT = new System.Windows.Point(50, 50);
- var transPointLT = _transform.Transform(pointLT);
- var textLeft = transPointLT.X - 16;
- var textTop = transPointLT.Y;
- TextBlock text = new TextBlock();
- double ratio = Math.Round(_echoContrastRatio, 4);
- text.Text = ratio.ToString();
- if (ratio<=0)
- {
- text.Text = "Invalid !";
- }
- text.FontSize = 30;
- text.FontWeight = System.Windows.FontWeights.Bold;
- text.Foreground = System.Windows.Media.Brushes.Yellow;
- text.VerticalAlignment = System.Windows.VerticalAlignment.Top;
- Canvas.SetLeft(text, textLeft);
- Canvas.SetTop(text, textTop);
- TestResultCanvas.Children.Add(text);
- string textName = "Ratio";
- TestResultCanvas.RegisterName(textName, text);
- }));
- }
- #endregion
- }
- }
|