草庐IT

WPF HALCON HSmartWindowControlWPF 鼠标绘制ROI

knok 2024-07-06 原文

0. 需求

在HSmartWindowsControlWPF上用鼠标绘制ROI,且显示绘制时的鼠标交互过程,最终效果如下:

1. 基本思路

  • 在HSmartWindowControl上布置一层透明的Canvas,用于实时显示鼠标绘制ROI的过程

  • 鼠标移动时,在Canvas上用鼠标实时绘制Rectangle等ROI形状,

  • 鼠标在Canvas坐标系中的Position信息(x,y)坐标转换到HALCON图像坐标系,变换为Row、Column等信息

  • 根据Row、Column信息调用HDrawingObject.CreateDrawingObject()方法生成Halcon原生ROI

  • 鼠标左键释放时,隐藏Canvas,将原生ROI附加到窗口中

UI布局如下:

  <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="100"></ColumnDefinition>
            <ColumnDefinition></ColumnDefinition>
        </Grid.ColumnDefinitions>
        <StackPanel Grid.Column="0" Orientation="Vertical">
            <Button Width="75" Height="25" Content="LoadImg" Margin="2.5" Click="Button_Click"></Button>
            <CheckBox Content="Rect" Margin="2.5" x:Name="rect_roi" Checked="rect_roi_Checked" Unchecked="rect_roi_Unchecked"></CheckBox>
            <CheckBox Content="Ellipse" Margin="2.5" x:Name="ellipse_roi" Checked="ellipse_roi_Checked" Unchecked="ellipse_roi_Unchecked"></CheckBox>
        </StackPanel>
        <halcon:HSmartWindowControlWPF HKeepAspectRatio="True" Grid.Column="1" x:Name="HalconWindowControl" HInitWindow="HWind_HInitWindow"></halcon:HSmartWindowControlWPF>
        <Canvas x:Name="Canvas" Visibility="Collapsed" Grid.Column="1" Background="Transparent" MouseLeftButtonDown="Canvas_MouseLeftButtonDown" MouseUp="Canvas_MouseUp" MouseMove="Canvas_MouseMove"></Canvas>
    </Grid>

2. 鼠标事件处理

  1. 初始化时,在Canvas中添加Rectangle等对象,并将其设置为不可见

	   private void Init()
        {
            Canvas.Children.Add(_canvasRect);
            Canvas.Children.Add(_canvasEllipse);
            Canvas.Children.Add(_cross);

            //矩形
            _canvasRect.Stroke = new SolidColorBrush(StokeColor);
            _canvasRect.StrokeThickness = StokeThickness;
            _canvasRect.Width = 0;
            _canvasRect.Height = 0;

            //圆形
            _canvasEllipse.Stroke = new SolidColorBrush(StokeColor);
            _canvasEllipse.StrokeThickness = StokeThickness;

            //十字
            _cross.Stroke = new SolidColorBrush(StokeColor);
            _cross.StrokeThickness = StokeThickness;
            _cross.Data = PathGeometry.Parse("M0,0 L8,8 M8,0 L0,8");
            _cross.Width = 0;
            _cross.Height = 0;

            // HImagePart随着窗口大小变化实时变动,注册事件用于实时更新坐标变换信息
            var dpd = DependencyPropertyDescriptor.FromProperty(HSmartWindowControlWPF.HImagePartProperty, typeof(HSmartWindowControlWPF));
            dpd.AddValueChanged(HalconWindowControl, (o, e) =>
            {
                var imgPart = HalconWindowControl.HImagePart;
                _k = imgPart.Height / HalconWindowControl.ActualHeight;
                _tx = imgPart.X;
                _ty = imgPart.Y;
            });
        }
  1. 鼠标左键单击,记录开始点startPoint

		private void Canvas_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            if (e.LeftButton == MouseButtonState.Pressed)
            {
                _startPoint = e.GetPosition(Canvas);
            }
        }
  1. 鼠标移动,在Canvas上实时绘制Rectangle

	    private void Canvas_MouseMove(object sender, MouseEventArgs e)
		{
            if (e.LeftButton == MouseButtonState.Pressed && rect_roi.IsChecked == true)
            {
                _endPoint = e.GetPosition(Canvas);

                _canvasRect.Height = Math.Abs(_endPoint.Y - _startPoint.Y);
                _canvasRect.Width = Math.Abs(_endPoint.X - _startPoint.X);
				
				// 左上往右下拖动
                if (_endPoint.X > _startPoint.X && _endPoint.Y > _startPoint.Y)
                {
                    Canvas.SetLeft(_canvasRect, _startPoint.X);
                    Canvas.SetTop(_canvasRect, _startPoint.Y);
                    
					//坐标转换,Canvas => HWindow
                    ConvertPoint(_startPoint.X, _startPoint.Y, _k, _tx, _ty, out double sx, out double sy);
                    ConvertPoint(_endPoint.X, _endPoint.Y, _k, _tx, _ty, out double ex, out double ey);
                    
                    _r1 = sy;
                    _c1 = sx;
                    _r2 = ey;
                    _c2 = ex;
                }

				// 右下往左上拖动
                if (_endPoint.X < _startPoint.X && _endPoint.Y < _startPoint.Y)
                {
                    Canvas.SetLeft(_canvasRect, _endPoint.X);
                    Canvas.SetTop(_canvasRect, _endPoint.Y);
                }
		}
  1. 鼠标释放时,添加ROI到HalconWindow中

		private void Canvas_MouseUp(object sender, MouseButtonEventArgs e)
        {
            if(rect_roi.IsChecked == true)
            {
                _roi = HDrawingObject.CreateDrawingObject(HDrawingObject.HDrawingObjectType.RECTANGLE1, _r1, _c1, _r2, _c2);
                _hwind.AttachDrawingObjectToWindow(_roi);
                rect_roi.IsChecked = false;
            }
            
            if(ellipse_roi.IsChecked == true)
            {
                _roi = HDrawingObject.CreateDrawingObject(HDrawingObject.HDrawingObjectType.CIRCLE, _cr, _cc, _cRadius);
                _hwind.AttachDrawingObjectToWindow(_roi);
                ellipse_roi.IsChecked = false;
            }
        }

4. 坐标转换

Canvas坐标系和HWindow坐标系之间仅存在缩放、平移这两种变换关系,和相机标定的原理一样,k为缩放系数,tx、ty为平移量

		private void ConvertPoint(double x, double y, double k, double tx, double ty, out double px, out double py)
        {
            px = k * x + tx;
            py = k * y + ty;
        }

有关WPF HALCON HSmartWindowControlWPF 鼠标绘制ROI的更多相关文章

  1. javascript - 使用鼠标绘制路径和调整大小 - 2

    我正在尝试用鼠标旋转SVG路径。Fiddle.但我对此没有什么问题,旋转原点错误当我停止旋转并再次旋转时,它是从不同的起始Angular开始的,而不是从之前的Angular开始的。不确定如何在旋转后更新circle的位置。代码在这里:varsvgns='http://www.w3.org/2000/svg';varpath=document.getElementById('path-element');varangle=0;functiongetRotationPoint(){varbRect=path.getBoundingClientRect();varrotationPoint=

  2. 视频目标检测paper(三)《Temporal ROI Align for Video Object Recognition》 - 2

            这篇文章作为2021年的AAAI视频目标检测类文章,可以说是现在视频目标检测的最新技术之一了,并且已经集成到了MMtracking框架之中,可以说是集合了计算机视觉,深度学习,目标检测,视频检测等知识综合性较强的文章,以小编现在的水平很难融汇贯通,所以说作为一个笔记总结吧,以后水平提高会重新总结这篇文章,希望看到的朋友们不要见怪哈。【Abstract】将来自同一视频的其他帧的时间信息聚合到当前帧是一种应对针对外观恶化的自然选择。ROI-Align仍是对目标从单帧特征图中提取特征,使得提取的特征缺少视频中的时间信息。1.考虑到视频中同一对象实例的特征在帧间高度相似,提出了一种新的

  3. WPF HALCON HSmartWindowControlWPF 鼠标绘制ROI - 2

    0.需求在HSmartWindowsControlWPF上用鼠标绘制ROI,且显示绘制时的鼠标交互过程,最终效果如下:1.基本思路在HSmartWindowControl上布置一层透明的Canvas,用于实时显示鼠标绘制ROI的过程鼠标移动时,在Canvas上用鼠标实时绘制Rectangle等ROI形状,鼠标在Canvas坐标系中的Position信息(x,y)坐标转换到HALCON图像坐标系,变换为Row、Column等信息根据Row、Column信息调用HDrawingObject.CreateDrawingObject()方法生成Halcon原生ROI鼠标左键释放时,隐藏Canvas,将

  4. c# - 单击鼠标绘制一个矩形 - 2

    我可以用鼠标点击画一个矩形吗?到目前为止,我的代码无法正常工作。你能帮帮我吗?privatevoidpanel1_MouseClick(objectsender,MouseEventArgse){Graphicsg=this.CreateGraphics();Penpen=newPen(Color.Black,2);g.DrawRectangle(pen,100,100,100,200);} 最佳答案 编辑版本:没有太多假设你想做什么:privatevoidpanel1_Click(objectsender,EventArgse){

  5. c++ - 丢失目标时如何重置或更新 KCF 跟踪器 ROI - 2

    我正在使用KCF跟踪算法,我的问题是当目标退出窗口时,跟踪器不会重置并错误地在窗口边缘显示它的矩形。在理想状态下,跟踪器应该在失去目标时删除矩形。这些是我的代码:intmain(intargc,char**argv){Rect2droi;Matframe;//createatrackerobjectPtrtracker=Tracker::create("KCF");VideoCapturecap("C2_0002.mp4");cap>>frame;resize(frame,frame,Size(frame.cols/2,frame.rows/2));roi=selectROI("tra

  6. c++ - 将图像拟合到 ROI - 2

    我有投资返回率和图像。我必须用我拥有的图像填充投资返回率。图像应根据ROI的形状和大小进行缩放,并且应填充整个ROI,而不重复图像。如何使用opencv实现此目的?opencv中有什么方法可以实现这个吗?假设这个白色部分是我的投资返回率这是我的输入图像有没有使用imageMagick的解决方案??? 最佳答案 找到一个形状在另一个形状内的最佳匹配并非易事,但如果您可以满足于次优结果,您可以执行以下操作:importcv2importnumpyasnpfrommatplotlibimportpyplotaspltbg_contours

  7. c++ - 在不复制的情况下从 Eigen::SparseMatrix 中提取 block /ROI - 2

    我想知道有没有什么好的方法可以从Eigen::SparseMatrix中提取block/ROI?更准确地说,我要提取的是内部vector。我想做的是这样的:typedefEigen::SparseMatrixSpMat;//PreparesomesparsematrixSpMatspmat;//ExtractlinesfromitconstSpMat&row_i=spmat.innerVector(i);constSpMat&row_j=spmat.innerVector(j);//Somecalculationwithrow_iandrow_j...根据我的测试,row_i和row_

  8. c++ - 在 OpenCV 中自动检测和裁剪 ROI - 2

    我有这些图像可以相互比较。但是,我认为我可以裁剪掉太多的黑色以使比较更有效。我想做的是裁剪火星。比较时,矩形或圆形可能会产生更好的结果。我担心如果裁剪会导致图像大小不同,比较结果不会像预期的那样好吗?如果可能的话,如何做的想法和示例代码?提前致谢更新:尝试使用cvHoughCircles()它不会检测到行星:/ 最佳答案 尝试使用颜色检测。你需要找到除黑色之外的所有颜色。Here和here是对这种方法的很好的解释。 关于c++-在OpenCV中自动检测和裁剪ROI,我们在StackOve

  9. c++ - 使用鼠标从视频上的矩形设置 ROI - 2

    我有视频,当程序运行时,视频的第一帧是图像,允许用户在图像上画一个矩形,画完矩形后,用户必须在图像上单击鼠标右键进行确认矩形。当鼠标右键单击时,图像消失,视频开始播放并在其上绘制矩形。我可以完美地绘制矩形,但无法将该矩形设置为ROI。我想要做的是将该矩形设置为感兴趣区域(ROI),以便对该ROI进行一些图像处理。我无法将我绘制的矩形设置为ROI。我在VisualStudio2010中使用OpenCV。稍后我会尝试将此程序集成到QTcreator中。如有任何帮助,我们将不胜感激。提前致谢。我的完整代码如下:#include#include#include#include#include#

  10. ios - 核心图 - 如何在标绘点上增加值(value) - 2

    我第一次使用CorePlot绘制图形一些我最终设法绘制点的方法,但我想以注释样式在图表上显示绘制点的精确值。我想显示与此附加图像(图形图像)中所示相同的精确点值http://i.stack.imgur.com/PpyRj.png请帮助我提前致谢 最佳答案 您必须显示数据标签(这就是它们在CorePlot中的名称),这里有一些有用的信息Core-PlotCPTScatterPlotdatalabels要显示数据标签,您需要从中返回相应的值-(CPTLayer*)dataLabelForPlot:(CPTPlot*)plotrecord

随机推荐