123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221 |
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Text;
- using System.Threading.Tasks;
- using System.Windows.Controls;
- using System.Windows.Threading;
- using System.Windows.Media.Imaging;
- using System.Drawing;
- using System.Drawing.Imaging;
- using YOLODetectProcessLib;
- namespace YOLODetectDemo
- {
- public class Roi
- {
- public Rect BoundBox { get; set; }
- public System.Windows.Media.Brush Color { get; set; }
- public string LabelName { get; set; }
- }
- 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
- private Bitmap _image;
- private List<Roi> _rois;
- private volatile bool _enableAI;
- private volatile bool _showContour;
- private volatile bool _showSize;
- private MyTransform _transform;
- #endregion
- #region properties
- public Bitmap Image { get => _image; }
- #endregion
- #region 用户界面响应
- private void CanvasSizeChanged(object sender, System.Windows.SizeChangedEventArgs e)
- {
- UpdateTransforms();
- }
- #endregion
- #region public
- public ImageCanvas()
- {
- InitializeComponent();
- }
- public void SetShowParams(bool enableAI)
- {
- _enableAI = enableAI;
- if (_rois != null)
- {
- for (int ni = 0; ni < _rois.Count; ni++)
- {
- DrawRoiInCanvas(_rois[ni], ni.ToString());
- }
- }
- }
- public void UpdateImage(Bitmap image)
- {
- _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;
- }));
- }
- #endregion
- #region private
- private void RemoveRoiInCanvas(string roiName)
- {
- // 文字
- string textName = "Text_" + roiName;
- System.Windows.Controls.TextBlock textExist = RoiCanvas.FindName(textName) as System.Windows.Controls.TextBlock;
- if (textExist != null)
- {
- RoiCanvas.Children.Remove(textExist);
- RoiCanvas.UnregisterName(textName);
- }
- }
- private void DrawRoiInCanvas(Roi roi, string roiName)
- {
- if (_transform == null)
- {
- return;
- }
- // 已有则删除
- RemoveRoiInCanvas(roiName);
- // 不启用AI,则直接退出
- if (!_enableAI)
- {
- return;
- }
- // 将Roi的序号写在左上角
- var pointLT = new System.Windows.Point(roi.BoundBox.Left, roi.BoundBox.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);
- RoiCanvas.Children.Add(text);
- string textName = "Text_" + roiName;
- RoiCanvas.RegisterName(textName, text);
- }
- 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 canvasWidth = RoiCanvas.ActualWidth;
- var canvasHeight = RoiCanvas.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);
- }
- }
- #endregion
- }
- }
|