当前位置: 首页 > news >正文

VTK知识学习(53)- 交互与Widget(四)

1、测量类Widget

1)概述

与测量相关的主要 Widget如下:

  • vtkDistanceWidget:用于在二维平面上测量两点之间的距离。
  • vtkAngleWidget:用于二维平面的角度测量。
  • vtkBiDimensionalWidget:用于测量二维平面上任意两个正交方向的轴长。

按照前面提到的步骤创建一个用于测量距离的 Widget,示例MeasurementWidget 演示了这个过程。

2)代码
 private void TestMeasureDemo(){vtkBMPReader read = vtkBMPReader.New();read.SetFileName("F:\\code\\VTK\\TestActiViz\\data\\lena.bmp");read.Update();vtkImageActor imageActor = vtkImageActor.New();imageActor.SetInputData(read.GetOutput());vtkRenderer renderer = vtkRenderer.New();renderer.SetBackground(1, 1, 1);vtkRenderWindow renderWindow = vtkRenderWindow.New();// renderWindowControl.RenderWindow;renderWindow.AddRenderer(renderer);renderer.AddActor(imageActor);renderWindow.Render();renderWindow.SetSize(400, 400);vtkRenderWindowInteractor renderWindowInteractor = vtkRenderWindowInteractor.New();renderWindowInteractor.SetRenderWindow(renderWindow);vtkInteractorStyleImage style = vtkInteractorStyleImage.New();renderWindowInteractor.SetInteractorStyle(style);int widgetType = 2;if (widgetType == 0)//vtkDistanceWidget{// 两个点之间的距离// 用户只要用鼠标左键点击屏幕,然后松开鼠标并移至另外一个点,即会在两点之间生成一条线段,并有距离的测量值 。vtkDistanceWidget distanceWidget = vtkDistanceWidget.New(); //实例化distanceWidget.SetInteractor(renderWindowInteractor);       //设置渲染容器交互器distanceWidget.CreateDefaultRepresentation();                //创建默认的几何表达实体//设置两点之间所测距离 的文本表示格式((vtkDistanceRepresentation)distanceWidget.GetRepresentation()).SetLabelFormat("%-#6.3g px");renderWindowInteractor.Initialize();renderWindow.Render();distanceWidget.On();       //激活实例renderWindowInteractor.Start();}else if (widgetType == 1) //vtkAngleWidget{//角度测量vtkAngleWidget angleWidget = vtkAngleWidget.New();angleWidget.SetInteractor(renderWindowInteractor);vtkAngleRepresentation2D angleRep = vtkAngleRepresentation2D.New();angleRep.GetRay1().GetProperty().SetColor(1, 0, 0);angleRep.GetRay2().GetProperty().SetColor(0, 1, 0);angleRep.GetArc().GetProperty().SetColor(0, 0, 1);angleWidget.SetRepresentation(angleRep);renderWindowInteractor.Initialize();renderWindow.Render();angleWidget.On();renderWindowInteractor.Start();}else if (widgetType == 2) //vtkBiDimensionalWidget{//测量二维平面上任意两个正交方向的轴长vtkBiDimensionalWidget biDimensionalWidget = vtkBiDimensionalWidget.New();biDimensionalWidget.SetInteractor(renderWindowInteractor);biDimensionalWidget.CreateDefaultRepresentation();//vtkBiDimensionalCallback vtkBiDimensionalCallback = (vtkBiDimensionalCallback)vtkBiDimensionalCallback.New();biDimensionalWidget.InteractionEvt += BiDimensionalWidget_RenderEvt;//biDimensionalWidget.AddObserver((uint)vtkCommand.EventIds.InteractionEvent, vtkBiDimensionalCallback, 0f);// vtkCommand.CreaterenderWindowInteractor.Initialize();renderWindow.Render();biDimensionalWidget.On();renderWindowInteractor.Start();}}
private void BiDimensionalWidget_RenderEvt(vtkObject sender, vtkObjectEventArgs e){if (sender is vtkBiDimensionalWidget biDimensionalWidget){if (biDimensionalWidget.GetRepresentation() is vtkBiDimensionalRepresentation2D representation2D){IntPtr data = Marshal.AllocHGlobal(sizeof(double) * 3);representation2D.GetPoint1DisplayPosition(data);double[] p1 = new double[3];Marshal.Copy(data, p1, 0, 3);representation2D.GetPoint2DisplayPosition(data);double[] p2 = new double[3];Marshal.Copy(data, p2, 0, 3);representation2D.GetPoint3DisplayPosition(data);double[] p3 = new double[3];Marshal.Copy(data, p3, 0, 3);representation2D.GetPoint4DisplayPosition(data);double[] p4 = new double[3];Marshal.Copy(data, p4, 0, 3);Console.WriteLine($"p1:{p1[0]} {p1[1]} {p1[2]}  " +$"p2:{p2[0]} {p2[1]} {p2[2]}  " +$"p3:{p3[0]} {p3[1]} {p3[2]}  " +$"p4:{p4[0]} {p4[1]} {p4[2]}  ");}}}
3)效果

4)说明

        以上示例中,使用了 vtkDistanceWidget 类来做二维空间的距离测量。先是实例化一个vtkDistanceWidget 实例;然后调用该类的 SetInteractor()函数来设置渲染窗口交互器;接着调用 CreateDefaultRepresentation()函数来创建默认的几何表达实体,即用十字形表示两个端点,端点之间使用带有刻度的直线连接。需要注意的是,在程序中调用SetLabelFormat()函数来设置两点之间所测距离的文本表示格式;最后调用0n()函数来激活vtkDistanceWidget实例。

        程序运行后,用户只要用鼠标左键点击屏幕,然后松开鼠标并移至另外一个点,即会在两点之间生成一条线段,并有距离的测量值,程序运行结果如图所示。

        角度测量的 vtkAngleWidget 以及二维正交方向长度测量的 vtkBiDimensionalWidget 的使用方法与 vtkDistanceWidget 类似,它们的二维几何表达形式分别为 vtkAngleRepresentation2D和 vtkBiDimensionalRepresentation2D。

2、标注类Widget

1)概述

        在可视化应用程序中,经常会对某个对象做一些标注说明,比如在医学图像诊断中,常常会手动标注出被诊断为肿瘤的区域或者其他病变区域,并用文字等进行标注。又如,在气象领域中,会用一些颜色图标表示各个地理区域在某个时间段温度高低的分布情况等。VTK中,与标注相关的主要 Widget如下:

  • vtkTextWidget:在渲染场景中生成一串标识文本,可以随意调整该文本在渲染场景中的位置,缩放其大小等。
  • vtkScalarBarWidget:根据输入的数据在渲染场景中生成一个标量条,通过设置颜色查找表,可以用标量条上的颜色来指示输入的数据。渲染场景中的标量条可以随意移动、改变大小、设置不同的方向等。
  • vtkCaptionWidget:用一个带线框及箭头的文本信息来标注某一对象。
  • vtkOrientationMarkerWidget:渲染场景中所渲染数据的方向指示标志。在医学图像应用程序中有广泛的应用,比如,通过CT、MR 等扫描的数据,当将其导入可视化应用程序时,需要标识其上、下、左、右、前、后等方位。
  • vtkBalloonWidget:当鼠标停留在渲染场景中的某个 Actor 一段时间后,会弹出提示信息。所提示的信息除了可以用文本表示,也可以用图像表示。

示例  AnnotationWidget 演示了以上几个 Widget 的用法。

2)代码
private void TestAnnotation(){vtkUnstructuredGridReader reader = vtkUnstructuredGridReader.New();reader.SetFileName("F:\\code\\VTK\\TestActiViz\\data\\scalarBarWidgetTestData.vtk");reader.Update();vtkLookupTable lut = vtkLookupTable.New();lut.Build();vtkDataSetMapper mapper = vtkDataSetMapper.New();mapper.SetInputData(reader.GetOutput());double[] scalar = reader.GetOutput().GetScalarRange();mapper.SetScalarRange(scalar[0], scalar[1]);mapper.SetLookupTable(lut);vtkActor actor = vtkActor.New();actor.SetMapper(mapper);vtkRenderer renderer = vtkRenderer.New();renderer.AddActor(actor);renderer.SetBackground(1, 1, 1);vtkRenderWindow renderWindow = vtkRenderWindow.New();renderWindow.AddRenderer(renderer);renderWindow.SetWindowName("AnnotationWidget");renderWindow.SetSize(400, 400);renderWindow.Render();vtkRenderWindowInteractor interactor = vtkRenderWindowInteractor.New();interactor.SetRenderWindow(renderWindow);vtkScalarBarActor scalarBarActor = vtkScalarBarActor.New();scalarBarActor.SetOrientationToHorizontal();scalarBarActor.SetLookupTable(lut);// vtkScalarBarWidgetvtkScalarBarWidget scalarBarWidget = vtkScalarBarWidget.New();scalarBarWidget.SetInteractor(interactor);scalarBarWidget.SetScalarBarActor(scalarBarActor);scalarBarWidget.On();// vtkTextWidgetvtkTextActor textActor = vtkTextActor.New();textActor.SetInput("VTK Widgets");textActor.GetTextProperty().SetColor(0, 1, 0);vtkTextWidget textWidget = vtkTextWidget.New();vtkTextRepresentation textRepresentation = vtkTextRepresentation.New();textRepresentation.GetPositionCoordinate().SetValue(0.15, 0.15);textRepresentation.GetPosition2Coordinate().SetValue(0.7, 0.2);textWidget.SetRepresentation(textRepresentation);textWidget.SetInteractor(interactor);textWidget.SetTextActor(textActor);textWidget.On();// vtkBalloonWidgetvtkBalloonRepresentation balloonrep = vtkBalloonRepresentation.New();balloonrep.SetBalloonLayoutToImageRight();vtkBalloonWidget balloonWidget = vtkBalloonWidget.New();balloonWidget.SetInteractor(interactor);balloonWidget.SetRepresentation(balloonrep);balloonWidget.AddBalloon(actor, "This is a widget example");balloonWidget.On();//vtkOrientationMarkerWidgetvtkAxesActor iconActor = vtkAxesActor.New();vtkOrientationMarkerWidget orientation = vtkOrientationMarkerWidget.New();orientation.SetOutlineColor(0.93, 0.57, 0.13);orientation.SetOrientationMarker(iconActor);orientation.SetInteractor(interactor);orientation.SetViewport(0, 0, 0.2, 0.2);orientation.SetEnabled(1);orientation.InteractiveOn();vtkCaptionWidget//vtkCaptionRepresentation captionRepresentation = vtkCaptionRepresentation.New();//captionRepresentation.GetCaptionActor2D().SetCaption("Caption Widget");//captionRepresentation.GetCaptionActor2D().GetTextActor().GetTextProperty().SetFontSize(20);//double[] pos = new double[] { 0.5, 0, 0 };//IntPtr dataPtr = Marshal.AllocHGlobal(sizeof(double) * 3);//Marshal.Copy(pos, 0, dataPtr, 3);//captionRepresentation.SetAnchorPosition(dataPtr);//vtkCaptionWidget captionWidget = vtkCaptionWidget.New();//captionWidget.SetInteractor(interactor);//captionWidget.SetRepresentation(captionRepresentation);//captionWidget.On();renderWindow.Render();interactor.Initialize();interactor.Start();}
3)效果

4)说明

        以上 Widget 在使用时需要注意的地方是,除了指定Widget 的表达实体以外,某些Widget 还需要与其他 Actor 协同使用,比如 vkScalarBarWidget要与 vtkScalarBarActor 协同工作vtkTextWidget 要与 vtkTextActor 协同工作等。

3、分割/配准灯Widget

         图像分割与配准是数字图像处理技术两大主要的应用领域,特别是在医学图像处理中,其应用更加广泛。著名的医学图像分割与配准工具包ITK(Insight Segmentation and RegistrationToolkit)的重要应用领域就是图像分割与配准。ITK 实现了许多经典的分割、配准算法,但不提供可视化的功能,因此,在应用中一般都会和 VTK 一起使用。由ITK负责分割、配准等数据处理,其处理结果由 VTK进行显示,必要时可以使用VTK的交互 Widget,从用户的交互过程中获取所需的数据,并向ITK的处理算法传递用户的参数设置。比如,对于区域增长算法,需要设置初始的种子点,而种子点的设置则可以使用VTK的vtkSeedWidget。与图像分割、配准应用相关的主要 Widget 如下。

  • vtkContourWidget:绘制轮廓线。所绘制的轮可以是闭合的,也可以是不闭合的,取决于最后一个点的位置。
  • vtkImageTracerWidget:绘制轨迹线。该类在手动分割图像中应用得较多。
  • vtkSeedWidget:放置种子点。在基于种子点的分割算法中应用得较多。
  • vtkCheckerboardWidget:在二维图像上生成棋盘格,而且可以控制棋盘格的数目。使用该类可以查看两幅图像配准后的重叠效果。
  • vtkRectilinearWipeWidget:在二维图像上生成棋盘格,与 vtkCheckboardWidget 不同的是,该类不可以控制棋盘格的数目,所生成的棋盘格是固定的2X2,但是该2x2的棋盘格可以调节大小,主要也是应用于图像配准中。

4、其他Widget

        除了以上介绍的 Widget 以外,VTK 还提供与绘图相关的 Widget,如 vtkXYPlotWidget;与动画、视频相关的 Widget,如 vkCameraWidget、vtkPlaybackWidget;与参数控制等相关的Widget,如 vtkCompassWidget、vtkSliderWidget、vtkCenteredSliderWidget 等;与数据探测提取等相关的 Widget,如vtkPlaneWidget、vtklmagePlaneWidget、vtkImplicitPlaneWidget2、vtkTensorProbeWidget;还有与空间变换相关的 Widget,如 vtkAffneWidget 等。

        虽然每个 Widget 都有不同的功能及应用范围,但是它们的使用方法大同小异,基本都是遵循 前面所述的操作步骤。每个 Widget内部都会绑定不同的事件,在使用这些 Widget 类时,只要知道应该捕获哪些消息,然后根据具体的需求实现相应的回调函数即可,而 Widget的样式则由相应的 Represention 类进行表达。用户可以使用默认的表达实体或者指定其他的表达实体,这就是 vtkAbstractWidget里“交互/表达实体”分离的好处。

相关文章:

  • Kubernetes 创建 Jenkins 实现 CICD 配置指南
  • 5.2.1 CallerMemberName的使用
  • 02-HTML结构
  • 在线查看【免费】vsd, vsdx/wmf, emf /psd, eps/pdf ,ofd, rtf/xmind/bpmn/eml/epub文件格式网
  • 驱动开发硬核特训 · Day 16:字符设备驱动模型与实战注册流程
  • 基于STC89C52RC和8X8点阵屏、独立按键的匹配消除类小游戏
  • unity3d实现物体闪烁
  • Discuz论坛网站忘记管理员密码进不去管理中心怎么办?怎么改管理员密码?
  • 45.[前端开发-JavaScript高级]Day10-迭代器-生成器
  • Git创建空分支并推送到远程仓库
  • 市场分析 3 mysql (槽)
  • YOLO11改进,尺度动态损失函数Scale-based Dynamic Loss,减少标签不准确对损失函数稳定性的影响
  • 【网络安全】OWASP 十大漏洞
  • 蓝桥杯2024省A.成绩统计
  • 组件是怎样写的(1):虚拟列表-VirtualList
  • Activity之间交互
  • spark与hadoop的区别
  • Flutter 状态管理 Riverpod
  • 【Linux】多线程任务模块
  • 【Linux篇】轻松搭建命名管道通信:客户端与服务器的互动无缝连接
  • 商务部:支持“来数加工”等新业态新模式,发展游戏出海业务
  • “6+2”小复式追加票!松江购彩者擒大乐透1672万头奖
  • 中国房地产报:以改促治实现楼市多难并解
  • 金融监管总局:建立保险销售人员违法违规导致经济损失的佣金薪酬追索扣回机制
  • 左眼失明左耳失聪,办理残疾人证被拒?县残联:双眼残疾才能办
  • 俄外交部谴责日本计划在近俄边境军事演习