123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482 |
- using System;
- using System.Collections.Generic;
- using System.Windows.Media.Imaging;
- using System.Windows.Threading;
- using System.Drawing;
- using System.Drawing.Imaging;
- using System.Windows.Controls;
- using AI.Common;
- using Rectangle = System.Drawing.Rectangle;
- using RUSInferNet;
- using HumanOrganSegDemo;
- using RUSInferNet.PostProcess;
- using System.Xml.Linq;
- using System.Windows.Media;
- using System.Linq;
- namespace HumanOrganSegmentDemo
- {
- public class TestResults
- {
- /// <summary>
- /// 人体/人脸
- /// </summary>
- public Dictionary<EnumHumanParts, Rect[]> BodyPartBoundBoxes;
- /// <summary>
- /// 一张图里目标对象的关键点
- /// </summary>
- public BodyKeyPoints BodyKeyPoints { get; set; }
- /// <summary>
- /// 目标脏器的轮廓信息
- /// </summary>
- public ContourPoints OrganContours;
- /// <summary>
- /// 像素坐标系下人体朝向的方向向量
- /// </summary>
- public Point2D HumanOrientationInPCS { get; set; }
- public TestResults(Dictionary<EnumHumanParts, Rect[]> bodyBoundBoxes, BodyKeyPoints bodyKeyPoints, ContourPoints organContours, Point2D humanOrientationInPCS)
- {
- BodyPartBoundBoxes = bodyBoundBoxes;
- BodyKeyPoints = bodyKeyPoints;
- OrganContours = organContours;
- HumanOrientationInPCS = humanOrientationInPCS;
- }
- }
- 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>
- /// ImageInfo.xaml 的交互逻辑
- /// </summary>
- public partial class ImageCanvas : UserControl
- {
- #region private
- private Bitmap _image;
- //private volatile bool _enableAI;
- private volatile bool _showContour;
- private volatile bool _showSize;
- private MyTransform _transform;
- private TestResults _testResult;
- #endregion
- #region properties
- public Bitmap Image { get => _image; }
- #endregion
- #region 用户界面响应
- private void OcardialSizeChanged(object sender, System.Windows.SizeChangedEventArgs e)
- {
- UpdateTransforms();
- }
- #endregion
- #region public
- public ImageCanvas()
- {
- InitializeComponent();
- }
- public void UpdateImage(Bitmap image)
- {
- if (_image != null)
- {
- _image.Dispose();
- }
- _image = image.Clone(new 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 UpdateHumanDetectResults(HumanDetectResultPerImage result)
- {
- _testResult = new TestResults(result.BodyPartBoundBoxesAll, result.ObjectKeyPoints, result.ObjectOrganContours, result.ObjectOrientationInPCS);
- UpdateTestResultShow();
- }
- public void UpdateRoughPathResults(Point2D[] pathPts)
- {
- Dispatcher.BeginInvoke(DispatcherPriority.Normal, new Action(() =>
- {
- DrawContoursInCanvas(pathPts, "path", System.Windows.Media.Brushes.Cyan);
- }));
- }
- public void Clear()
- {
- // 清空画布上的所有内容
- TestResultCanvas.Children.Clear();
- }
- #endregion
- #region private
- 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;
- }
- private void UpdateTransforms()
- {
- if (_image != null)
- {
- // 使图片保持长宽比例,居中显示,需要平移和缩放
- var imgWidth = _image.Width;
- var imgHeight = _image.Height;
- var ocardialWidth = TestResultCanvas.ActualWidth;
- var ocardialHeight = TestResultCanvas.ActualHeight;
- var scaleX = ocardialWidth / imgWidth;
- var scaleY = ocardialHeight / 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 UpdateTestResultShow()
- {
- Dispatcher.BeginInvoke(DispatcherPriority.Normal, new Action(() =>
- {
- // 清空画布上的所有内容
- TestResultCanvas.Children.Clear();
- // 没有结果就直接返回
- if (_testResult == null)
- {
- return;
- }
- if(_testResult.BodyPartBoundBoxes.Count==0)
- {
- return;
- }
- if (_testResult.BodyPartBoundBoxes.Count > 0)
- {
- // 更新所有框
- foreach (var rcs in _testResult.BodyPartBoundBoxes.ToArray())
- {
- if (rcs.Key == EnumHumanParts.Head)
- {
- DrawRectsInCanvas(rcs.Value, "head");
- }
- if (rcs.Key == EnumHumanParts.Body)
- {
- DrawRectsInCanvas(rcs.Value, "body");
- }
- }
- }
- // 更新人体关键点
- DrawHumanInCanvas(_testResult.BodyKeyPoints, "keyPts");
- // 更新轮廓
- DrawContoursInCanvas(_testResult.OrganContours.Points, "contours", System.Windows.Media.Brushes.OrangeRed);
- // 更新人体朝向
- //if (_testResult.HumanOrientationInPCS.X * _testResult.HumanOrientationInPCS.Y != 0)
- //{
- // Point2D[] pts = new Point2D[2];
- // pts[0] = new Point2D(_image.Width / 2, _image.Height / 2);
- // pts[1] = new Point2D(pts[0].X + _testResult.HumanOrientationInPCS.X, pts[0].Y + _testResult.HumanOrientationInPCS.Y);
- // DrawContoursInCanvas(pts, "Orientation", System.Windows.Media.Brushes.BlueViolet);
- //}
- }));
- }
- /// <summary>
- /// 从画布上移除矩形框
- /// </summary>
- /// <param name="roiName"></param>
- private void RemoveRectsCanvas(string roiName)
- {
- // 框
- string textName = roiName;
- List<System.Windows.Shapes.Rectangle> rcsExist = TestResultCanvas.FindName(textName) as List<System.Windows.Shapes.Rectangle>;
- if (rcsExist != null)
- {
- foreach (var rcExist in rcsExist)
- {
- TestResultCanvas.Children.Remove(rcExist);
- }
- TestResultCanvas.UnregisterName(textName);
- }
- }
- /// <summary>
- /// 在画布上画出矩形框
- /// </summary>
- /// <param name="rcs"></param>
- /// <param name="rcName"></param>
- private void DrawRectsInCanvas(Rect[] rcs, string rcName)
- {
- if (_transform == null)
- {
- return;
- }
- // 已有则删除
- RemoveRectsCanvas(rcName);
- List<System.Windows.Shapes.Rectangle> rcRenders = new List<System.Windows.Shapes.Rectangle> { };
- foreach (var rc in rcs)
- {
- System.Windows.Shapes.Rectangle rcRender = new System.Windows.Shapes.Rectangle();
- rcRender.StrokeThickness = 3;
- rcRender.Stroke = System.Windows.Media.Brushes.AliceBlue;
- var transPtLeftTop = _transform.Transform(new System.Windows.Point(rc.Left, rc.Top));
- var transPtRightDown = _transform.Transform(new System.Windows.Point(rc.Left + rc.Width, rc.Top + rc.Height));
- Canvas.SetLeft(rcRender, transPtLeftTop.X);
- Canvas.SetTop(rcRender, transPtLeftTop.Y);
- rcRender.Width = transPtRightDown.X - transPtLeftTop.X;
- rcRender.Height = transPtRightDown.Y - transPtLeftTop.Y;
- TestResultCanvas.Children.Add(rcRender);
- //TestResultCanvas.RegisterName(rcName, rcRender);
- rcRenders.Add(rcRender);
- }
- TestResultCanvas.RegisterName(rcName, rcRenders);
- }
- /// <summary>
- /// 在画布上画出轮廓
- /// </summary>
- /// <param name="pts"></param>
- /// <param name="registerName"></param>
- private void DrawContoursInCanvas(Point2D[] pts, string registerName, System.Windows.Media.Brush color)
- {
- if (_transform == null)
- {
- return;
- }
- // 已有则删除
- RemoveContoursInCanvas(registerName);
- if(pts== null)
- {
- return;
- }
- PointCollection contourPoints = new PointCollection();
- foreach (var pt in pts)
- {
- var point = new System.Windows.Point(pt.X, pt.Y);
- var transPoint = _transform.Transform(point);
- contourPoints.Add(transPoint);
- }
- System.Windows.Shapes.Polyline contourDraw = new System.Windows.Shapes.Polyline();
- contourDraw.Points = contourPoints;
- contourDraw.StrokeThickness = 3;
- contourDraw.Stroke = color;
- TestResultCanvas.Children.Add(contourDraw);
- TestResultCanvas.RegisterName(registerName, contourDraw);
- }
- /// <summary>
- /// 从画布上将轮廓移除
- /// </summary>
- /// <param name="registerName"></param>
- private void RemoveContoursInCanvas(string registerName)
- {
- System.Windows.Shapes.Polyline contourExist = TestResultCanvas.FindName(registerName) as System.Windows.Shapes.Polyline;
- if (contourExist != null)
- {
- TestResultCanvas.Children.Remove(contourExist);
- TestResultCanvas.UnregisterName(registerName);
- }
- }
- private void DrawHumanInCanvas(BodyKeyPoints humanKeyPts, string name)
- {
- if (_transform == null)
- {
- return;
- }
- // 已有则删除
- RemoveHumanInCanvas(name);
- var neckPosition = _transform.Transform(new System.Windows.Point(humanKeyPts.Neck.X, humanKeyPts.Neck.Y));
- var leftShoulderPosition = _transform.Transform(new System.Windows.Point(humanKeyPts.LeftShoulder.X, humanKeyPts.LeftShoulder.Y));
- var rightShoulderPosition = _transform.Transform(new System.Windows.Point(humanKeyPts.RightShoulder.X, humanKeyPts.RightShoulder.Y));
- // 脖子
- if (humanKeyPts.Neck.X * humanKeyPts.Neck.Y > 0)
- {
- System.Windows.Shapes.Ellipse neck = new System.Windows.Shapes.Ellipse();
- neck.StrokeThickness = 4;
- neck.Stroke = System.Windows.Media.Brushes.Orange;
- neck.Width = 6;
- Canvas.SetLeft(neck, neckPosition.X);
- Canvas.SetTop(neck, neckPosition.Y);
- TestResultCanvas.Children.Add(neck);
- string neckName = "Human_" + name + "_point_head";
- TestResultCanvas.RegisterName(neckName, neck);
- }
- // 左肩
- if (humanKeyPts.LeftShoulder.X * humanKeyPts.LeftShoulder.Y > 0)
- {
- System.Windows.Shapes.Ellipse leftShoulder = new System.Windows.Shapes.Ellipse();
- leftShoulder.StrokeThickness = 3;
- leftShoulder.Stroke = System.Windows.Media.Brushes.AliceBlue;
- leftShoulder.Width = 6;
- Canvas.SetLeft(leftShoulder, leftShoulderPosition.X);
- Canvas.SetTop(leftShoulder, leftShoulderPosition.Y);
- TestResultCanvas.Children.Add(leftShoulder);
- string leftShoulderName = "Human_" + name + "_point_leftShoulder";
- TestResultCanvas.RegisterName(leftShoulderName, leftShoulder);
- }
- // 右肩
- if (humanKeyPts.RightShoulder.X * humanKeyPts.RightShoulder.Y > 0)
- {
- System.Windows.Shapes.Ellipse rightShoulder = new System.Windows.Shapes.Ellipse();
- rightShoulder.StrokeThickness = 3;
- rightShoulder.Stroke = System.Windows.Media.Brushes.AliceBlue;
- rightShoulder.Width = 6;
- Canvas.SetLeft(rightShoulder, rightShoulderPosition.X);
- Canvas.SetTop(rightShoulder, rightShoulderPosition.Y);
- TestResultCanvas.Children.Add(rightShoulder);
- string rightShoulderName = "Human_" + name + "_point_rightShoulder";
- TestResultCanvas.RegisterName(rightShoulderName, rightShoulder);
- }
- // 从脖子到左肩的线
- if (humanKeyPts.Neck.X * humanKeyPts.Neck.Y > 0 && humanKeyPts.LeftShoulder.X * humanKeyPts.LeftShoulder.Y > 0)
- {
- System.Windows.Shapes.Line lineLeft = new System.Windows.Shapes.Line();
- lineLeft.StrokeThickness = 2;
- lineLeft.Stroke = System.Windows.Media.Brushes.RosyBrown;
- lineLeft.X1 = neckPosition.X;
- lineLeft.Y1 = neckPosition.Y;
- lineLeft.X2 = leftShoulderPosition.X;
- lineLeft.Y2 = leftShoulderPosition.Y;
- TestResultCanvas.Children.Add(lineLeft);
- string lineLeftName = "Human_" + name + "_lineLeft";
- TestResultCanvas.RegisterName(lineLeftName, lineLeft);
- }
- // 从脖子到右肩的线
- if (humanKeyPts.Neck.X * humanKeyPts.Neck.Y > 0 && humanKeyPts.RightShoulder.X * humanKeyPts.RightShoulder.Y > 0)
- {
- System.Windows.Shapes.Line lineRight = new System.Windows.Shapes.Line();
- lineRight.StrokeThickness = 2;
- lineRight.Stroke = System.Windows.Media.Brushes.DarkGray;
- lineRight.X1 = neckPosition.X;
- lineRight.Y1 = neckPosition.Y;
- lineRight.X2 = rightShoulderPosition.X;
- lineRight.Y2 = rightShoulderPosition.Y;
- TestResultCanvas.Children.Add(lineRight);
- string lineRightName = "Human_" + name + "_lineRight";
- TestResultCanvas.RegisterName(lineRightName, lineRight);
- }
- }
- private void RemoveHumanInCanvas(string name)
- {
- // 脖子
- string neckName = "Human_" + name + "_point_head";
- System.Windows.Shapes.Ellipse neck = TestResultCanvas.FindName(neckName) as System.Windows.Shapes.Ellipse;
- if (neck != null)
- {
- TestResultCanvas.Children.Remove(neck);
- TestResultCanvas.UnregisterName(neckName);
- }
- // 左肩
- string leftShoulderName = "Human_" + name + "_point_leftShoulder";
- System.Windows.Shapes.Ellipse leftShoulder = TestResultCanvas.FindName(leftShoulderName) as System.Windows.Shapes.Ellipse;
- if (leftShoulder != null)
- {
- TestResultCanvas.Children.Remove(leftShoulder);
- TestResultCanvas.UnregisterName(leftShoulderName);
- }
- // 右肩
- string rightShoulderName = "Human_" + name + "_point_rightShoulder";
- System.Windows.Shapes.Ellipse rightShoulder = TestResultCanvas.FindName(rightShoulderName) as System.Windows.Shapes.Ellipse;
- if (rightShoulder != null)
- {
- TestResultCanvas.Children.Remove(rightShoulder);
- TestResultCanvas.UnregisterName(rightShoulderName);
- }
- // 从脖子到左肩的线
- string lineLeftName = "Human_" + name + "_lineLeft";
- System.Windows.Shapes.Line lineLeft = TestResultCanvas.FindName(lineLeftName) as System.Windows.Shapes.Line;
- if (lineLeft != null)
- {
- TestResultCanvas.Children.Remove(lineLeft);
- TestResultCanvas.UnregisterName(lineLeftName);
- }
- // 从脖子到右肩的线
- string lineRightName = "Human_" + name + "_lineRight";
- System.Windows.Shapes.Line lineRight = TestResultCanvas.FindName(lineRightName) as System.Windows.Shapes.Line;
- if (lineRight != null)
- {
- TestResultCanvas.Children.Remove(lineRight);
- TestResultCanvas.UnregisterName(lineRightName);
- }
- }
- #endregion
- }
- }
|