加载和显示DICOM图像切片作为一个3D对象- WinForms c#

本教程演示如何在LEADTOOLS中加载和显示2D DICOM图像切片堆栈作为3D对象MedicalViewerWinForms控制。

概述
总结 本教程介绍了如何在WinForms c#应用程序中加载和显示2D DICOM图像切片堆栈作为3D对象。
完成时间 30分钟
Visual Studio项目 下载教程项目(12kb)
平台 Windows WinForms c#应用程序
IDE Visual Studio 2019, 2022
开发许可 下载LEADTOOLS

所需的知识

步骤,熟悉创建项目和显示DICOM映像的基本步骤添加引用和设置License而且在医疗查看器中加载和显示DICOM图像教程,在工作之前加载和显示DICOM图像切片作为一个3D对象- WinForms c#教程。

Medical3DControl对象

Medical3DControl提供医疗3D对象,并与MedicalViewer类继承的MedicalViewerBaseCell类的基本对象,这意味着它与MedicalViewerMultiCell类用于正常显示二维医学图像。

要使用正确的测量和缩放正确地渲染3D体积,需要以下信息:

此外,对于给定的一组2D图像切片,截面平面必须平行且顺序正确。

为了说明问题,本教程使用image1.dcm样本:< INSTALL_DIR > \ LEADTOOLS22 \ \ \ DICOM图像资源

这是一个磁共振(MR)样本,其中包含了正确顺序的图像以及存储在数据集标签中的上述信息。

创建项目并添加LEADTOOLS引用

中创建的项目的副本开始在医疗查看器中加载和显示DICOM图像教程。如果项目不可用,请按照该教程中的步骤创建它。

所需要的参考资料取决于项目的目的。引用可以通过以下两种方法中的一种添加(但不能同时添加)。

如果使用NuGet引用,本教程需要以下NuGet包:

如果使用本地DLL引用,则需要以下DLL。

dll位于< INSTALL_DIR > \ LEADTOOLS22 \ Bin \ Dotnet4 \ x64

有关应用程序需要哪些DLL文件的完整列表,请参阅你的申请中包含的文件

设置License文件

许可证解锁项目所需的特性。它必须在调用任何工具箱函数之前设置。有关详细信息,包括针对不同平台的教程,请参阅设置运行时License

有两种类型的运行时许可证:

初始化Medical3DControl

现在已经将LEADTOOLS引用添加到项目中,并设置了许可证,可以开始编码了。

右键单击Form1.cs解决方案资源管理器并选择视图代码以显示表单后面的代码。

添加Leadtools。Medical3D使用块在文件顶部。

c#
使用系统;使用先;使用System.Windows.Forms;使用Leadtools;使用Leadtools.Dicom;使用Leadtools.Medical3D;使用Leadtools.MedicalViewer;

添加Medical3DControl对象添加到全局变量。

c#
私人MedicalViewer _medicalViewer;私人MedicalViewerMultiCell _cell;私人Medical3DControl _control3D;

修改loadDICOMToolStripMenuItem_Click事件处理程序来添加对Initialize3DControl函数之后_medicalViewer.Cells.Add (_cell)

c#
//添加初始化的单元格_medicalViewer.Cells.Add (_cell);//初始化3D控件如果(_cell.Image。PageCount >Initialize3DControl (_cell.Image。宽度,_cell.Image。高度,_cell.Image.PageCount);

确保将下面的代码添加到Initialize3DControl函数。

c#
私人无效Initialize3DControl (int宽度,int高度,inttotalFrames)//创建3D控件保龄球usesoftwarerender = !CanUse3DTexturing(宽度,高度,totalFrames);_control3D =Medical3DControl (useSoftwareRendering);_control3D.ObjectsContainer。RenderingType = Medical3DVolumeRenderingType.Auto;_control3D.ObjectsContainer.Objects.Add (Medical3DObject ());//初始化3D帧保龄球created = _control3D.ObjectsContainer.Objects[0].MemoryEfficientInit(totalFrames);如果创建(!)//删除对象_control3D.ObjectsContainer.Objects.RemoveAt (0);_control3D.Dispose ();_control3D =返回//添加3D控制动作_control3D.AddAction (MedicalViewerActionType.WindowLevel);_control3D.AddAction (MedicalViewerActionType.Rotate3DObject);_control3D.AddAction (MedicalViewerActionType.Scale3DObject);_control3D.SetAction (MedicalViewerActionType。Rotate3DObject MedicalViewerMouseButtons。对,MedicalViewerActionFlags.Active);_control3D.SetAction (MedicalViewerActionType。WindowLevel MedicalViewerMouseButtons。离开,MedicalViewerActionFlags.Active);_control3D.SetAction (MedicalViewerActionType。Scale3DObject MedicalViewerMouseButtons。中间,MedicalViewerActionFlags.Active);

在3D控件中设置图像帧

初始化3D控件后,修改控件中的代码loadDICOMToolStripMenuItem_Click事件处理程序获取数据集中每一帧的图像位置信息,并使用它将帧正确地加载到3D控件中。

c#
//初始化3D控件如果(_cell.Image。PageCount >Initialize3DControl (_cell.Image。宽度,_cell.Image。高度,_cell.Image.PageCount);如果(_control3D ! =//用DICOM文件中的图像位置信息填充单元格帧SetCellFramesImagePosition(数据集);//添加图像页到3D控制帧int指数= 0;index < _cell.Image.PageCount;指数+ +)_cell.Image。Page = index + 1;_control3D.ObjectsContainer.Objects[0].MemoryEfficientSetFrame(_cell.Image.Clone(), index, _cell.GetImagePosition(index),真正的);

添加一个名为SetCellFramesImagePosition (DicomDataSet数据集).方法中调用此方法loadDICOMToolStripMenuItem_Click事件处理程序,如上所示。添加下面的代码来从DICOM数据集加载图像位置信息,并在2D单元格中的每个帧的属性中设置它。

c#
私人无效SetCellFramesImagePosition (DicomDataSet数据集)int指数= 0;DicomElement元素= dataSet。FindFirstElement (, DicomTag。PerFrameFunctionalGroupsSequence,真正的);如果(元素! =element =数据集。GetChildElement(元素,真正的);DicomElement firsttem =数据集。FindFirstElement (element, DicomTag.Item,真正的);(firstItem ! =element =数据集。GetChildElement (firstItem真正的);element =数据集。FindFirstElement (element, DicomTag.PlanePositionSequence,真正的);element =数据集。GetChildElement(元素,真正的);element =数据集。FindFirstElement (element, DicomTag.Item,真正的);element =数据集。GetChildElement(元素,真正的);element =数据集。FindFirstElement (element, DicomTag.ImagePositionPatient,真正的);如果(元素! =[] doubleArray =数据集。GetDoubleValue(element, 0,3);_cell。SetImagePosition(指数,Point3D.FromDoubleArray (doubleArray),);指数+ +;firstItem =数据集。GetNextElement (firstItem真正的真正的);

在控件中设置3D帧

将所有帧加载到3D控件后,将下面的代码添加到loadDICOMToolStripMenuItem_Click事件处理程序来完成帧和标记的设置。

c#
如果(_control3D ! =//用DICOM文件中的图像位置信息填充单元格帧SetCellFramesImagePosition(数据集);//添加图像页到3D控制帧int指数= 0;index < _cell.Image.PageCount;指数+ +)_cell.Image。Page = index + 1;_control3D.ObjectsContainer.Objects[0].MemoryEfficientSetFrame(_cell.Image.Clone(), index, _cell.GetImagePosition(index),真正的);//从DICOM获取图像方向SetCellImageOrientation(数据集);//从DICOM获取像素间距SetCellPixelSpacing(数据集);/ /完成_control3D.ObjectsContainer.Objects [0] .MemoryEfficientEnd (_cell。ImageOrientation _cell.PixelSpacing);//设置标签Set3DTags ();

添加两个名为SetCellImageOrientation (DicomDataSet数据集)而且SetCellPixelSpacing (DicomDataSet数据集).方法中调用这两个方法loadDICOMToolStripMenuItem_Click事件处理程序,如上所示。将下面的代码添加到SetCellImageOrientation函数从数据集中获取图像方向。

c#
私人无效SetCellImageOrientation (DicomDataSet数据集)DicomElement元素= dataSet。FindFirstElement (, DicomTag。PerFrameFunctionalGroupsSequence,真正的);如果(元素! =element =数据集。GetChildElement(元素,真正的);element =数据集。FindFirstElement (element, DicomTag.Item,真正的);element =数据集。GetChildElement(元素,真正的);element =数据集。FindFirstElement (element, DicomTag.PlaneOrientationSequence,真正的);element =数据集。GetChildElement(元素,真正的);element =数据集。FindFirstElement (element, DicomTag.Item,真正的);element =数据集。GetChildElement(元素,真正的);element =数据集。FindFirstElement (element, DicomTag.ImageOrientationPatient,真正的);[] doubleArray =数据集。GetDoubleValue(element, 0,6);_cell。ImageOrientation =浮动[] {(浮动) doubleArray [0], (浮动) doubleArray [1], (浮动) doubleArray [2], (浮动) doubleArray [3], (浮动) doubleArray [4], (浮动) doubleArray [5]};

将下面的代码添加到SetCellPixelSpacing函数从数据集中获取像素间距信息。

c#
私人无效SetCellPixelSpacing (DicomDataSet数据集)DicomElement元素= dataSet。FindFirstElement (, DicomTag。SharedFunctionalGroupsSequence,真正的);如果(元素! =element =数据集。FindFirstElement (element, DicomTag.Item,);element =数据集。FindFirstElement (element, DicomTag.PixelMeasuresSequence,);element =数据集。FindFirstElement (element, DicomTag.Item,);element =数据集。FindFirstElement (element, DicomTag.PixelSpacing,);[] doubleArray =数据集。GetDoubleValue(element, 0,2);_cell。PixelSpacing =Point2D (doubleArray [0], doubleArray [1]);

添加Set3DTags函数码

在Program类中添加一个名为Set3DTags()的新函数。类的底部调用此函数loadDICOMToolStripMenuItem_Click事件处理程序,如前一步所示。

添加下面的代码,使用来自2D单元格的标签设置相关的3D控件标签。

c#
私人无效Set3DTags ()MedicalViewerTagInformation信息;//从多单元格中加载用户数据标签Information = _cell。MedicalViewerTagAlignment.TopRight GetTag (2);如果(信息! =) _control3D。MedicalViewerTagAlignment SetTag(1。TopRight,信息。类型,information.Text);Information = _cell。MedicalViewerTagAlignment.TopRight GetTag (3);如果(信息! =) _control3D。MedicalViewerTagAlignment SetTag(2。TopRight,信息。类型,information.Text);Information = _cell。MedicalViewerTagAlignment.TopRight GetTag(4日);如果(信息! =) _control3D。MedicalViewerTagAlignment SetTag(3。TopRight,信息。类型,information.Text);Information = _cell。MedicalViewerTagAlignment.TopRight GetTag(5日);如果(信息! =) _control3D。MedicalViewerTagAlignment SetTag(4。TopRight,信息。类型,information.Text);Information = _cell。MedicalViewerTagAlignment.TopRight GetTag(6日);如果(信息! =) _control3D。MedicalViewerTagAlignment SetTag(5。TopRight,信息。类型,information.Text);Information = _cell。MedicalViewerTagAlignment.TopRight GetTag(7日);如果(信息! =) _control3D。MedicalViewerTagAlignment SetTag(5。TopRight,信息。类型,information.Text);//其他标签_control3D。MedicalViewerTagAlignment SetTag(4。TopLeft MedicalViewerTagType.Frame);_control3D。MedicalViewerTagAlignment SetTag(6日。TopLeft MedicalViewerTagType.Scale);_control3D。MedicalViewerTagAlignment SetTag(2。BottomLeft MedicalViewerTagType.WindowLevelData);_control3D。MedicalViewerTagAlignment SetTag(1。BottomLeft MedicalViewerTagType.FieldOfView);_control3D。MedicalViewerTagAlignment SetTag(0。BottomLeft MedicalViewerTagType.RulerUnit);

添加表单控件从2D切换到3D

解决方案资源管理器,双击Form1.cs在设计器中显示。添加一个细胞类型菜单menuStrip1与一个&VRT和一个&2D细胞菜单项。右键单击每个项目并取消选中启用两者皆可选。使用_menuVolumeVRT而且_menu2DCell作为每个菜单项的Name属性。

细胞类型菜单对象,单击事件图标。属性窗口.然后,双击DropDownOpening事件来创建事件处理程序(如果不存在)。

控件中添加以下代码cellTypeToolStripMenuItem_DropDownOpening事件处理程序。

c#
私人无效cellTypeToolStripMenuItem_DropDownOpening (对象发送者,EventArgs保龄球Allow3D =保龄球Allow2D =如果(_cell ! =Allow2D =真正的如果(_control3D ! =Allow3D =真正的_menuVolumeVRT。启用= Allow3D;_menu2DCell。启用= Allow2D;

双击VRT菜单项编辑其事件处理程序。添加以下代码将3D控件加载到查看器中(如果可用的话)。

c#
私人无效_menuVolumeVRT_Click (对象发送者,EventArgsforeach(ToolStripMenuItem ToolStripMenuItemcellTypeToolStripMenuItem.DropDownItems)toolStripMenuItem。检查=_menuVolumeVRT。检查=真正的如果(_medicalViewer。Cells[0] != _control3D)_medicalViewer.Cells.Clear ();_medicalViewer.Cells.Add (_control3D);

接下来,双击2 d细胞菜单项编辑其事件处理程序。添加以下代码将2D单元格加载到查看器中。

c#
私人无效_menu2DCell_Click (对象发送者,EventArgsforeach(ToolStripMenuItem ToolStripMenuItemcellTypeToolStripMenuItem.DropDownItems)toolStripMenuItem。检查=_menu2DCell。检查=真正的如果(_medicalViewer。细胞[0]!= _cell)_medicalViewer.Cells.Clear ();_medicalViewer.Cells.Add (_cell);

最后,添加下面的代码,以便在加载新图像时从所选单元格类型菜单项中清除选中标记。

c#
私人无效loadDICOMToolStripMenuItem_Click (对象发送者,EventArgs试一试//清除现有单元格如果(_medicalViewer.Cells。计数> 0)_medicalViewer.Cells.Clear ();//清除单元格类型菜单中的对号foreach(ToolStripMenuItem ToolStripMenuItemcellTypeToolStripMenuItem.DropDownItems)toolStripMenuItem。检查=

运行项目

按下运行项目F5,或选择Debug ->开始调试

如果正确地执行了上述步骤,则应用程序将运行,并允许加载和显示选定的2D DICOM图像切片集MedicalViewer三维空间的控制。可以使用image1.dcm样本:< INSTALL_DIR > \ LEADTOOLS22 \ \ \ DICOM图像资源

加载示例文件,然后选择Cell Type -> VRT

显示输出

总结

方法中渲染3D DICOM图像所必需的引用MedicalViewerWinForms控制。

另请参阅

iOS
188金宝搏的网址客服|支持|联系我们|知识产权公告
©1991 - 2023领德科技有限公司版权所有。