LeadTools 使用基准线

发布时间:2015/11/17 00:11 发布者:iceman

返回博客中心

在本教程中,您将学习到如何在MedicalViewer 单元格中显示基准线。

1. 请您打开Visual Studio2005或一个更高的版本。

  1. 从“文件”菜单中选择“项目”。
  2. 然后会出现一个新建项目对话框。
  3. 从“项目类型”中展开“其他语言”节点,然后单击在“Visual C#” 节点上。
  4. 从该对话框左侧的模板列表中,选择“Windows窗体应用程序”。
  5. 在“项目名称”字段里输入该项目的名称“使用基准线”,然后选择“确定”。
  6. 选择“确定”来创建该项目。
  7. 从“视图”菜单中选择“解决方案资源管理器”。
  8. 在“解决方案资源管理器”的树型图中,右键单击“引用”节点,然后选择“添加引用”。
  9. 在“添加引用”对话框中选择“浏览”选项卡,然后添加以下这些DLL文件:
    • Leadtools.dll
    • Leadtools.Codecs.dll
    • Leadtools.MedicalViewer.dll
    • Leadtools.Medical3D.dll
    • Leadtools.Dicom.dll
    • Leadtools.Codecs.Cmp.dll

切换到Form1代码视图(在“解决方案资源管理器”上右键单击Form1,然后选择“查看代码”),并在文件的开头添加以下几行代码:

[Visual Basic]
            Imports Leadtools
            Imports Leadtools.Codecs
            Imports Leadtools.MedicalViewer
            Imports Leadtools.Medical3D
            Imports Leadtools.Dicom
            
[C#]
            using Leadtools;
            using Leadtools.Codecs;
            using Leadtools.MedicalViewer;
            using Leadtools.Medical3D;
            using Leadtools.Dicom;
  1. Form1中,创建一个新的方法InitClass() 。并将以下代码添加到该方法:
 [Visual Basic]
            Private Sub InitClass()
               Dim MY_LICENSE_FILE As String = "d:\temp\TestLic.lic"
                 
               ' 开启DICOM支持。
               Dim MY_DicomDEVELOPER_KEY As String = "xyz123abc"
               RasterSupport.SetLicense(MY_LICENSE_FILE, MY_DicomDEVELOPER_KEY);
                 
               ' 开启Medical支持。
               Dim MY_MedicalDEVELOPER_KEY As String = "abc123xyz"
               RasterSupport.SetLicense(MY_LICENSE_FILE, MY_MedicalDEVELOPER_KEY);
                 
               ' 开启Medical 3D支持。
               Dim MY_3DDEVELOPER_KEY As String = "123xyzabc"
               RasterSupport.SetLicense(MY_LICENSE_FILE, MY_3DDEVELOPER_KEY);
               
               ' 创建一个将被用于加载图像的编解码器类的新实例。
               Dim _codecs As RasterCodecs = New RasterCodecs()
               ' 创建一个MedicalViewer的新实例。该查看器布局将被划分为2X2。
               Dim viewer As MedicalViewer = New MedicalViewer(2, 2)
               ' 使该视图与整个窗体相匹配。
               viewer.Dock = DockStyle.Fill
               ' 将该查看器添加到窗体。
               Controls.Add(viewer)
            End Sub
            
[C#]
            void InitClass()
            {
               string MY_LICENSE_FILE = "d:\\temp\\TestLic.lic";
               
               // 开启DICOM支持。
               string MY_DicomDEVELOPER_KEY = "xyz123abc";
               RasterSupport.SetLicense(MY_LICENSE_FILE, MY_DicomDEVELOPER_KEY);
                 
               // 开启Medical支持。
               string MY_MedicalDEVELOPER_KEY = "abc123xyz";
               RasterSupport.SetLicense(MY_LICENSE_FILE, MY_MedicalDEVELOPER_KEY);
                 
               // 开启Medical 3D支持。
               string MY_3DDEVELOPER_KEY = "123xyzabc";
               RasterSupport.SetLicense(MY_LICENSE_FILE, MY_3DDEVELOPER_KEY);
               
               // 创建一个将被用于加载图像的编解码器类的新实例。
               RasterCodecs _codecs = new RasterCodecs();
               // 创建一个MedicalViewer的新实例。该查看器布局将被划分为2X2。
               MedicalViewer viewer = new MedicalViewer(2, 2);
               // 使该视图与整个窗体相匹配。
               viewer.Dock = DockStyle.Fill;
               // 将该查看器添加到窗体。
               Controls.Add(viewer);
            }
            

 

13.请从Form1的构造函数中调用该方法InitClass,并将该调用放置于InitializeComponent()之后。

14.运行该程序,您将会看到一个2x2布局。

15.注意:在接下来的步骤中,您将需要具备一个DICOMDIR文件。我们可以提供DICOMDIR示例文件,您可以点击这里进行下载。如果您想要了解有关如何在DICOMDIR中构建3D对象的更多相关详细信息,请参阅这一章“如何加载DICOMDIR来创建一个3D对象”。

注意:如果您遇到一个“无效的文件格式”或“功能不支持”的异常,请参阅如下主题“无效的文件格式/功能不支持

请下载示例DICOMDIR,并将其内容解压缩到此文件夹:C:\Leadtools_DICOMDIR。

16.请将如下代码添加到Form1类。该代码可用于从DICOMDIR中加载图像,将它们进行排序,并从中提取所有的有用信息:

[Visual Basic]
            Private _studyElement As DicomElement
            Private _seriesElement As DicomElement
            Private _seriesManager As MedicalViewerSeriesManager
            Private _imageDataList As List(Of MedicalViewerImageData)
            Private doubleArray As Double()
            Private patientElement As DicomElement
            Private referenceUID As String
            Private imageElement As DicomElement
            Private output As MedicalViewerSeriesManager
            ' 您需要找到使用了科目实例UID的科目,并且在找到之后返回其DicomElement。 
            Private Function FindStudy(ByVal ds As DicomDataSet, ByVal studyInstanceUID As String) As DicomElement
              ' 获取父元素。
              Dim patientElement As DicomElement = ds.GetFirstKey(Nothing, True)
              Dim studyElement As DicomElement = Nothing
              Dim studyInformationElement As DicomElement = Nothing
              Dim studyID As String
              studyElement = ds.GetChildKey(patientElement)
              studyElement = ds.GetChildElement(studyElement, True)
              Do While Not studyElement Is Nothing
                studyInformationElement = ds.FindFirstElement(studyElement, DicomTag.StudyInstanceUID, True)
                If Not studyInformationElement Is Nothing Then
                   studyID = ds.GetConvertValue(studyInformationElement)
                   If studyID = studyInstanceUID Then
                     Return studyInformationElement
                   End If
                End If
                studyElement = ds.GetNextKey(studyElement, True)
                studyElement = ds.GetChildElement(studyElement, True)
              Loop
              Return Nothing
            End Function
            ' 您需要找到使用了系列实例UID的系列,并在找到后返回其DicomElement。
            Private Function FindSeries(ByVal ds As DicomDataSet, ByVal studyElement As DicomElement, ByVal seriesInstanceUID As String) As DicomElement
              Dim seriesElement As DicomElement = Nothing
              Dim seriesInformationElement As DicomElement = Nothing
              Dim seriesID As String
              seriesElement = ds.GetChildKey(studyElement)
              seriesElement = ds.GetChildElement(seriesElement, True)
              Do While Not seriesElement Is Nothing
                seriesInformationElement = ds.FindFirstElement(seriesElement, DicomTag.SeriesInstanceUID, True)
                If Not seriesInformationElement Is Nothing Then
                   seriesID = ds.GetConvertValue(seriesInformationElement)
                   If seriesID = seriesInstanceUID Then
                     Return seriesInformationElement
                   End If
                End If
                seriesElement = ds.GetNextKey(seriesElement, True)
                seriesElement = ds.GetChildElement(seriesElement, True)
              Loop
              Return Nothing
            End Function
            ' 返回该系列的第一帧的文件名。
            Private Function GetFirstImageName(ByVal ds As DicomDataSet, ByVal seriesElement As DicomElement, ByVal directoryPath As String, <System.Runtime.InteropServices.Out()> ByRef imageElement As DicomElement) As String
              Dim imageIDElement As DicomElement = Nothing
              imageElement = ds.GetChildKey(seriesElement)
              imageElement = ds.GetChildElement(imageElement, True)
              Do While Not imageElement Is Nothing
                imageIDElement = ds.FindFirstElement(imageElement, DicomTag.ReferencedFileID, True)
                If Not imageIDElement Is Nothing Then
                   Return directoryPath &"\" & ds.GetConvertValue(imageIDElement)
                End If
              Loop
              Return ""
            End Function
            ' 返回该系列的下一帧的文件名。
            Private Function GetNextImageName(ByVal ds As DicomDataSet, ByVal directoryPath As String, ByRef imageElement As DicomElement) As String
              Dim nextImageElement As DicomElement = Nothing
              imageElement = ds.GetNextKey(imageElement, True)
              imageElement = ds.GetChildElement(imageElement, True)
              Do While Not imageElement Is Nothing
                nextImageElement = ds.FindFirstElement(imageElement, DicomTag.ReferencedFileID, True)
                If Not imageElement Is Nothing Then
                   Dim echoElement As DicomElement = ds.FindFirstElement(imageElement, DicomTag.EchoNumber, True)
                   Return directoryPath & "\" & ds.GetConvertValue(nextImageElement)
                End If
              Loop
              Return ""
            End Function
            ' 这将加载DICOM数据集信息,并将其保存到MedicalViewerImageData类的一个新实例中。
            Private Function AddImageToImageArray(ByVal ds As DicomDataSet, ByVal index As Integer, ByVal imagePath As String, <System.Runtime.InteropServices.Out()> ByRef echoNumber As Integer) As Boolean
              echoNumber = -1
              Dim imageData As MedicalViewerImageData = New MedicalViewerImageData()
              patientElement = ds.FindFirstElement(Nothing, DicomTag.ImagePositionPatient, True)
              doubleArray = ds.GetDoubleValue(patientElement, 0, 3)
              imageData.ImagePosition = Point3D.FromDoubleArray(doubleArray)
              imageData.Data = imagePath
              imageData.EchoNumber = echoNumber
              patientElement = ds.FindFirstElement(Nothing, DicomTag.FrameOfReferenceUID, True)
              referenceUID = ds.GetConvertValue(patientElement)
              imageData.FrameOfReferenceUID = referenceUID
              patientElement = ds.FindFirstElement(Nothing, DicomTag.ImageOrientationPatient, True)
              imageData.ImageOrientation = ds.GetConvertValue(patientElement)
              patientElement = ds.FindFirstElement(Nothing, DicomTag.PixelSpacing, True)
              doubleArray = ds.GetDoubleValue(patientElement, 0, 2)
              imageData.PixelSpacing = New Point2D(CSng(doubleArray(0)), CSng(doubleArray(1)))
              patientElement = ds.FindFirstElement(Nothing, DicomTag.InstanceNumber, True)
              If Not patientElement Is Nothing Then
                imageData.InstanceNumber = Convert.ToInt32(ds.GetConvertValue(patientElement))
              End If
              patientElement = ds.FindFirstElement(Nothing, DicomTag.InstanceCreationTime, True)
              If Not patientElement Is Nothing Then
                imageData.CaptureTime = Convert.ToDateTime(ds.GetConvertValue(patientElement))
              End If
              _imageDataList.Add(imageData)
              Return True
            End Function
            Public Function Load_James_CT_Localizer() As MedicalViewerSeriesManager
              Dim fileName As String = "C:\Leadtools_DICOMDIR\Miller James\"
              Dim studyInstanceUID As String = "1.3.12.2.1107.5.1.4.50772.30000009122208074910900000022"
              Dim seriesInstanceUID As String = "1.3.12.2.1107.5.1.4.50772.30000009122208074910900000023"
              Return LoadSeries(fileName, studyInstanceUID, seriesInstanceUID, 1)
            End Function
            Public Function Load_James_CT() As MedicalViewerSeriesManager
              Dim fileName As String = "C:\Leadtools_DICOMDIR\Miller James\"
              Dim studyInstanceUID As String = "1.3.12.2.1107.5.1.4.50772.30000009122208074910900000022"
              Dim seriesInstanceUID As String = "1.3.12.2.1107.5.1.4.50772.30000009122208215356200001997"
              Return LoadSeries(fileName, studyInstanceUID, seriesInstanceUID, 256)
            End Function
            ' 这将加载由seriesInstanceUID和studyInstanceUID所指定的系列,而这两个UID来自fileName指定的文件。
            Private Function LoadSeries(ByVal fileName As String, ByVal studyInstanceUID As String, ByVal seriesInstanceUID As String, ByVal count As Integer) As MedicalViewerSeriesManager
              DicomEngine.Startup()
              Dim ds As DicomDataSet = New DicomDataSet()
              ds.Load(fileName &"DICOMDIR", DicomDataSetLoadFlags.None)
              Dim directoryPath As String = fileName
              ' 在这里,该程序将会对包含指定的studyInstanceUID的科目进行搜索。 
              _studyElement = FindStudy(ds, studyInstanceUID)
              ' 在这里,该程序将会对包含指定的seriesInstanceUID的系列进行搜索。
              _seriesElement = FindSeries(ds, _studyElement, seriesInstanceUID)
              ' 请创建一个MedicalViewerSeriesManager的新实例。它将被用于对图像进行排序,以便创建正确的3D对象。
              _seriesManager = New MedicalViewerSeriesManager()
              ' 请创建一个MedicalViewerImageData的阵列。该类将被用于保存帧信息。而该信息将被用于对图像进行排序。
              _imageDataList = New List(Of MedicalViewerImageData)()
              Dim dicomDataSet As DicomDataSet
              Dim imageIndex As Integer
              Dim imagePath As String
              Dim echoNumber As Integer = 0
              ' 现在,该程序将对该系列中的每一帧进行审查。
              imagePath = GetFirstImageName(ds, _seriesElement, directoryPath, imageElement)
              imageIndex = 0
              Do While imageIndex < count
                Try
                   ' 该系列中的每个图像都将被加载。
                   dicomDataSet = New DicomDataSet()
                   dicomDataSet.Load(imagePath, DicomDataSetLoadFlags.None)
                   ' 该程序可以加载它的信息,并将其保存到MedicalViewerImageData类的一个新实例中。
                   AddImageToImageArray(dicomDataSet, imageIndex, imagePath, echoNumber)
                   dicomDataSet.Dispose()
                   ' 跳转到下一个图像。
                   imagePath = GetNextImageName(ds, directoryPath, imageElement)
                Catch exception As System.Exception
                   System.Diagnostics.Debug.Assert(False, exception.Message)
                   Throw
                End Try
                 imageIndex += 1
              Loop
              ' 根据它的数据对这些图像进行排序。
              _seriesManager.Sort(_imageDataList)
              DicomEngine.Shutdown()
              Return _seriesManager
            End Function
            Private Sub LoadLocalizer(ByVal cell As MedicalViewerMultiCell)
              ' 启动允许加载各种图像的编解码器。
              Dim _codecs As RasterCodecs = New RasterCodecs()
              ' 加载CT定位器。
              output = Load_James_CT_Localizer()
              cell.Image = _codecs.Load(CStr(output.Localizers(0).LocalizerData.Data), 0, CodecsLoadByteOrder.BgrOrGrayOrRomm, 1, 1)
              ' 设置以下三行代码非常重要。否则,可能会发生基准线结果错误。
  ' 设置定位器的图像位置。             
 cell.SetImagePosition(0, _seriesManager.Localizers(0).LocalizerData.ImagePosition, True)
              ' 设置定位器的图像方向。
              cell.ImageOrientation = _seriesManager.Localizers(0).LocalizerData.ImageOrientationArray
              ' 设置定位器的像素间隔。
              cell.PixelSpacing = _seriesManager.Localizers(0).LocalizerData.PixelSpacing
              ' 设置定位器的帧引用UID。如果系列和定位器具有相同的引用UID的话,这样就可以在它们之间创建一条基准线。
              cell.FrameOfReferenceUID = _seriesManager.Localizers(0).LocalizerData.FrameOfReferenceUID
            End Sub
            Private Sub Load2DCell(ByVal cell As MedicalViewerMultiCell)
              ' 启动允许加载各种图像的编解码器。
              Dim _codecs As RasterCodecs = New RasterCodecs()
              ' 加载CT DICOMDIR,并返回排列好的图像集合。
              output = Load_James_CT()
              ' 循环处理这些图像,并将它们一个接一个地添加到最终的图像。
              Dim image As RasterImage = Nothing
              Dim depth As Integer = output.Stacks(0).Items.Count
              Dim index As Integer
              index = 0
              Do While index < depth
                If image Is Nothing Then
                   image = _codecs.Load(CStr(output.Stacks(0).Items(index).Data), 0, CodecsLoadByteOrder.BgrOrGrayOrRomm, 1, 1)
                Else
                   image.AddPage(_codecs.Load(CStr(output.Stacks(0).Items(index).Data), 0, CodecsLoadByteOrder.BgrOrGrayOrRomm, 1, 1))
                End If
                 index += 1
              Loop
              cell.Image = image
              ' 设置以下这几行代码非常重要。否则,可能会出现基准线结果错误。
              index = 0
              Do While index < depth
                ' 设置每帧的图像位置。
                cell.SetImagePosition(index, _seriesManager.Stacks(0).Items(index).ImagePosition, False)
                 index += 1
              Loop
              ' 请对该系列的图像方向进行设置,且它只需被设置一次,因为所有的帧必须具有相同的方向值。
              cell.ImageOrientation = _seriesManager.Stacks(0).Items(0).ImageOrientationArray
              ' 请对该系列的像素间隔进行设置,且它只需被设置一次,因为所有的帧必须具有相同的像素间隔值。
              cell.PixelSpacing = _seriesManager.Stacks(0).Items(0).PixelSpacing
              ' 请对该系列的帧引用UID进行设置。如果该系列和定位器具有相同的引用UID的话,这将在它们之间创建一条基准线。
              cell.FrameOfReferenceUID = _seriesManager.Stacks(0).Items(0).FrameOfReferenceUID
            End Sub
            
[C#]
            DicomElement _studyElement;
            DicomElement _seriesElement;
            MedicalViewerSeriesManager _seriesManager;
            List<MedicalViewerImageData> _imageDataList;
            double[] doubleArray;
            DicomElement patientElement;
            string referenceUID;
            DicomElement imageElement;
            MedicalViewerSeriesManager output;
            // 您需要找到使用了科目实例UID的科目,并且在找到之后返回其DicomElement。
            private DicomElement FindStudy(DicomDataSet ds, string studyInstanceUID)
            {
               // 获取父元素。
               DicomElement patientElement = ds.GetFirstKey(null, true);
               DicomElement studyElement = null;
               DicomElement studyInformationElement = null;
               string studyID;
               studyElement = ds.GetChildKey(patientElement);
               studyElement = ds.GetChildElement(studyElement, true);
               while (studyElement != null)
               {
                  studyInformationElement = ds.FindFirstElement(studyElement,
                                                                DicomTag.StudyInstanceUID,
                                                                true);
                  if (studyInformationElement != null)
                  {
                     studyID = ds.GetConvertValue(studyInformationElement);
                     if (studyID == studyInstanceUID)
                        return studyInformationElement;
                  }
                  studyElement = ds.GetNextKey(studyElement, true);
                  studyElement = ds.GetChildElement(studyElement, true);
               }
               return null;
            }
            // 您需要找到使用了系列实例UID的系列,并在找到后返回其DicomElement。
            private DicomElement FindSeries(DicomDataSet ds, DicomElement studyElement, string seriesInstanceUID)
            {
               DicomElement seriesElement = null;
               DicomElement seriesInformationElement = null;
               string seriesID;
               seriesElement = ds.GetChildKey(studyElement);
               seriesElement = ds.GetChildElement(seriesElement, true);
               while (seriesElement != null)
               {
                  seriesInformationElement = ds.FindFirstElement(seriesElement,
                                                                 DicomTag.SeriesInstanceUID,
                                                                 true);
                  if (seriesInformationElement != null)
                  {
                     seriesID = ds.GetConvertValue(seriesInformationElement);
                     if (seriesID == seriesInstanceUID)
                        return seriesInformationElement;
                  }
                  seriesElement = ds.GetNextKey(seriesElement, true);
                  seriesElement = ds.GetChildElement(seriesElement, true);
               }
               return null;
            }
            // 返回该系列的第一帧的文件名。
            private string GetFirstImageName(DicomDataSet ds, DicomElement seriesElement, string directoryPath, out DicomElement imageElement)
            {
               DicomElement imageIDElement = null;
               imageElement = ds.GetChildKey(seriesElement);
               imageElement = ds.GetChildElement(imageElement, true);
               while (imageElement != null)
               {
                  imageIDElement = ds.FindFirstElement(imageElement,
                                                     DicomTag.ReferencedFileID,
                                                     true);
                  if (imageIDElement != null)
                  {
                     return directoryPath + "\\" + ds.GetConvertValue(imageIDElement);
                  }
               }
               return "";
            }
            // 返回该系列的下一帧的文件名。
            private string GetNextImageName(DicomDataSet ds, string directoryPath, ref DicomElement imageElement)
            {
               DicomElement nextImageElement = null;
               imageElement = ds.GetNextKey(imageElement, true);
               imageElement = ds.GetChildElement(imageElement, true);
               while (imageElement != null)
               {
                  nextImageElement = ds.FindFirstElement(imageElement,
                                                     DicomTag.ReferencedFileID,
                                                     true);
                  if (imageElement != null)
                  {
                     DicomElement echoElement = ds.FindFirstElement(imageElement,
                                                       DicomTag.EchoNumber,
                                                       true);
                     return directoryPath + "\\" + ds.GetConvertValue(nextImageElement);
                  }
               }
               return "";
            }
            // 这将加载DICOM数据集信息,并将其保存到MedicalViewerImageData类的一个新实例中。
            private bool AddImageToImageArray(DicomDataSet ds, int index, string imagePath, out int echoNumber)
            {
               echoNumber = -1;
               MedicalViewerImageData imageData = new MedicalViewerImageData();
               patientElement = ds.FindFirstElement(null,
                                                    DicomTag.ImagePositionPatient,
                                                    true);
               doubleArray = ds.GetDoubleValue(patientElement, 0, 3);
               imageData.ImagePosition = Point3D.FromDoubleArray(doubleArray);
               imageData.Data = imagePath;
               imageData.EchoNumber = echoNumber;
               patientElement = ds.FindFirstElement(null,
                                                   DicomTag.FrameOfReferenceUID,
                                                   true);
               referenceUID = ds.GetConvertValue(patientElement);
               imageData.FrameOfReferenceUID = referenceUID;
               patientElement = ds.FindFirstElement(null,
                                                   DicomTag.ImageOrientationPatient,
                                                   true);
               imageData.ImageOrientation = ds.GetConvertValue(patientElement);
               patientElement = ds.FindFirstElement(null,
                                                    DicomTag.PixelSpacing,
                                                    true);
               doubleArray = ds.GetDoubleValue(patientElement, 0, 2);
               imageData.PixelSpacing = new Point2D((float)doubleArray[0], (float)doubleArray[1]);
               patientElement = ds.FindFirstElement(null,
                                                   DicomTag.InstanceNumber,
                                                   true);
               if (patientElement != null)
                  imageData.InstanceNumber = Convert.ToInt32(ds.GetConvertValue(patientElement));
               patientElement = ds.FindFirstElement(null,
                                                   DicomTag.InstanceCreationTime,
                                                   true);
               if (patientElement != null)
                  imageData.CaptureTime = Convert.ToDateTime(ds.GetConvertValue(patientElement));
               _imageDataList.Add(imageData);
               return true;
            }
            public MedicalViewerSeriesManager Load_James_CT_Localizer()
            {
               string fileName = @"C:\Leadtools_DICOMDIR\Miller James\";
               string studyInstanceUID = "1.3.12.2.1107.5.1.4.50772.30000009122208074910900000022";
               string seriesInstanceUID = "1.3.12.2.1107.5.1.4.50772.30000009122208074910900000023";
               return LoadSeries(fileName, studyInstanceUID, seriesInstanceUID, 1);
            }
            public MedicalViewerSeriesManager Load_James_CT()
            {
               string fileName = @"C:\Leadtools_DICOMDIR\Miller James\";
               string studyInstanceUID = "1.3.12.2.1107.5.1.4.50772.30000009122208074910900000022";
               string seriesInstanceUID = "1.3.12.2.1107.5.1.4.50772.30000009122208215356200001997";
               return LoadSeries(fileName, studyInstanceUID, seriesInstanceUID, 256);
            }
            // 这将加载由seriesInstanceUID和studyInstanceUID所指定的系列,而这两个UID来自fileName指定的文件。
            private MedicalViewerSeriesManager LoadSeries(string fileName, string studyInstanceUID, string seriesInstanceUID, int count)
            {
               DicomEngine.Startup();
               DicomDataSet ds = new DicomDataSet();
               ds.Load(fileName + "DICOMDIR", DicomDataSetLoadFlags.None);
               string directoryPath = fileName;
               // 在这里,该程序将会对包含指定的studyInstanceUID的科目进行搜索。
               _studyElement = FindStudy(ds, studyInstanceUID);
               // 在这里,该程序将会对包含指定的seriesInstanceUID的系列进行搜索。
               _seriesElement = FindSeries(ds, _studyElement, seriesInstanceUID);
               // 请创建一个MedicalViewerSeriesManager的新实例。它将被用于对图像进行排序,以便创建正确的3D对象。
               _seriesManager = new MedicalViewerSeriesManager();
               // 请创建一个MedicalViewerImageData的阵列。该类将被用于保存帧信息。而该信息将被用于对图像进行排序。
               _imageDataList = new List<MedicalViewerImageData>();
               DicomDataSet dicomDataSet;
               int imageIndex;
               string imagePath;
               int echoNumber = 0;
               // 现在,该程序将对该系列中的每一帧进行审查。
               imagePath = GetFirstImageName(ds, _seriesElement, directoryPath, out imageElement);
               for (imageIndex = 0; imageIndex < count; imageIndex++)
               {
                  try
                  {
                     // 该系列中的每个图像都将被加载。
                     dicomDataSet = new DicomDataSet();
                     dicomDataSet.Load(imagePath, DicomDataSetLoadFlags.None);
                     // 该程序可以加载它的信息,并将其保存到MedicalViewerImageData类的一个新实例中。
                     AddImageToImageArray(dicomDataSet, imageIndex, imagePath, out echoNumber);
                     dicomDataSet.Dispose();
                     // 跳转到下一个图像。
                     imagePath = GetNextImageName(ds, directoryPath, ref imageElement);
                  }
                  catch (System.Exception exception)
                  {
                     System.Diagnostics.Debug.Assert(false, exception.Message);
                     throw;
                  }
               }
               // 根据它的数据对这些图像进行排序。
               _seriesManager.Sort(_imageDataList);
               DicomEngine.Shutdown();
               return _seriesManager;
            }
            void LoadLocalizer(MedicalViewerMultiCell cell)
            {
               // 启动允许加载各种图像的编解码器。
               RasterCodecs _codecs = new RasterCodecs();
               // 加载CT定位器。
               output = Load_James_CT_Localizer();
               cell.Image = _codecs.Load((string)output.Localizers[0].LocalizerData.Data, 0, CodecsLoadByteOrder.BgrOrGrayOrRomm, 1, 1);
               // 设置以下三行代码非常重要。否则,可能会发生基准线结果错误。
               // 设置定位器的图像位置。
               cell.SetImagePosition(0, _seriesManager.Localizers[0].LocalizerData.ImagePosition, true);
               // 设置定位器的图像方向。
               cell.ImageOrientation = _seriesManager.Localizers[0].LocalizerData.ImageOrientationArray;
               // 设置定位器的像素间隔。
               cell.PixelSpacing = _seriesManager.Localizers[0].LocalizerData.PixelSpacing;
               // 设置定位器的帧引用UID。如果该系列和定位器具有相同的引用UID的话,这样就可以在它们之间创建一条基准线。
               cell.FrameOfReferenceUID = _seriesManager.Localizers[0].LocalizerData.FrameOfReferenceUID;
            }
            void Load2DCell(MedicalViewerMultiCell cell)
            {
               // 启动允许加载各种图像的编解码器。
               RasterCodecs _codecs = new RasterCodecs();
               // 加载CT DICOMDIR,并返回排列好的图像集合。
               output = Load_James_CT();
               // 循环处理这些图像,并将它们一个接一个地添加到最终的图像。
               RasterImage image = null;
               int depth = output.Stacks[0].Items.Count;
               int index;
               for (index = 0; index < depth; index++)
               {
                  if (image == null)
                  {
                     image = _codecs.Load((string)output.Stacks[0].Items[index].Data, 0, CodecsLoadByteOrder.BgrOrGrayOrRomm, 1, 1);
                  }
                  else
                     image.AddPage(_codecs.Load((string)output.Stacks[0].Items[index].Data, 0, CodecsLoadByteOrder.BgrOrGrayOrRomm, 1, 1));
               }
               cell.Image = image;
               // 设置以下这几行代码非常重要。否则,可能会出现基准线结果错误。               for (index = 0; index < depth; index++)
               {
                  // 设置每帧的图像位置。.
                  cell.SetImagePosition(index, _seriesManager.Stacks[0].Items[index].ImagePosition, false);
               }
               // 请对该系列的图像方向进行设置,且它只需被设置一次,因为所有的帧必须具有相同的方向值。
               cell.ImageOrientation = _seriesManager.Stacks[0].Items[0].ImageOrientationArray;
               // 请对该系列的像素间隔进行设置,且它只需被设置一次,因为所有的帧必须具有相同的像素间隔值。.
               cell.PixelSpacing = _seriesManager.Stacks[0].Items[0].PixelSpacing;
               // 请对该系列的帧引用UID进行设置。如果该系列和定位器具有相同的引用UID的话,这将在它们之间创建一条基准线。
               cell.FrameOfReferenceUID = _seriesManager.Stacks[0].Items[0].FrameOfReferenceUID;
            }
            

 

17.将如下几行代码添加到InitClass()方法的末尾(这将创建一个新的单元格,并将指定的系列填充到其中):

 [Visual Basic]
            ' 创建一个包含图像集合的单元格。
            Dim cell As MedicalViewerMultiCell = New MedicalViewerMultiCell()
            ' 加载该图像集合。
            Load2DCell(cell)
            
[C#]
            //创建一个包含图像集合的单元格。
            MedicalViewerMultiCell cell = new MedicalViewerMultiCell();
            // 加载该图像集合。
            Load2DCell(cell);

 

18.将如下几行代码添加到InitClass()方法的末尾(这将创建一个新的单元格,并将一个被称为定位器的帧填充到其中):

[Visual Basic]
            ' 创建一个包含定位器的单元格。
            Dim localizerCell As MedicalViewerMultiCell = New MedicalViewerMultiCell()
            ' 加载该定位器。
            LoadLocalizer(localizerCell)
            
[C#]
            // 创建一个包含定位器的单元格。
            MedicalViewerMultiCell localizerCell = new MedicalViewerMultiCell();
            // 加载该定位器。
            LoadLocalizer(localizerCell);

 

19.现在,将这两个单元格(系列单元格和定位器单元格)添加到MedicalViewer。为了做到这一点,请将如下这几行代码添加到InitClass()方法的末尾:

[Visual Basic]
            ' 将以上的多帧单元格添加到MedicalViewer。
            viewer.Cells.Add(cell)
            ' 将以上的定位器单元格添加到MedicalViewer。 
           viewer.Cells.Add(localizerCell)
            
[C#]
            // 将以上的多帧单元格添加到MedicalViewer。
            viewer.Cells.Add(cell);
            // 将以上的定位器单元格添加到MedicalViewer。
            viewer.Cells.Add(localizerCell);

 

20.最后,您需要同时启用这两个单元格的基准线。为了做到这一点,您只需要将以下这几行代码添加到InitClass()方法的末尾:

[Visual Basic]
            ' 在定位器图像中启用基准线。
            cell.ReferenceLine.Enabled = True
            ' 在图像集合中启用基准线。
            localizerCell.ReferenceLine.Enabled = True
            
[C#]
            // 在定位器图像中启用基准线。
            cell.ReferenceLine.Enabled = true;
            // 在图像集合中启用基准线。
            localizerCell.ReferenceLine.Enabled = true;

21.如果您运行该程序,现在您将看到两个单元格:一个上面绘制有一条垂直线,而另外一个上面绘制有一条水平线。

支持

关于其他产品的更多信息,请访问我们的官方网站

欢迎下载免费的全功能评估版SDK,全功能试用版中有这个例子的全部源代码。

同时欢迎您使用评估版期间的免费技术支持


关于葡萄城

赋能开发者!葡萄城是专业的集开发工具、商业智能解决方案、低代码开发平台于一身的软件和服务提供商,为超过 75% 的全球财富 500 强企业提供服务。葡萄城专注控件软件领域30年,希望通过模块化的开发控件、灵活的低代码应用开发平台等一系列开发工具、解决方案和服务,帮助开发者快速响应复杂多变的业务需求,最大程度地发挥开发者的才智和潜能,让开发者的 IT 人生更从容更美好。

了解详情,请访问葡萄城官网