如何通过CT三维图像得到DRR

Posted fantianliang

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何通过CT三维图像得到DRR相关的知识,希望对你有一定的参考价值。

一、介绍

  获取DRR图像是医疗图像配准里面的一个重要的前置步骤。

  在2D/3D的配准流程里面,需要首先通过CT三维图像,能够获取任意位置的DRR图像,然后去与已经获取的X光平面图像配准。

  配准过程如下(下面的描述是不准确的,我只是描述了一种情况,即基于灰度的图像配准算法的过程,并且可能会有纰漏):

  1- 定义一个评价函数:即相似性测度函数,通过这个函数评价当前是否已经达到了配准的要求。

  2- 不断通过调整输入参数得到不同角度下的DRR图像。

  3-通过1里面的评价函数判断是否停止搜索

  实际上这是一个循环,终止条件就是是否满足相似性测度函数。

  具体流程可以参考下面的流程图:

  技术图片

 

 

 

 

 

 

 

 

 

 

 

二、DRR例子运行

  在ITK5.0里面有一个相关的例子,我也是跑了好久才把程序跑通的,跑通以后就觉得做了许多的无用功......

  说到底还是菜,跑一个程序就要两周,醉了(好吧,吐槽完毕^-^)

  1-找到例子,构建工程

  按照之前第一个博客的过程安装ITK之后,我们找到这个例子所在的位置:

  ITK-5.0/Examples/Filtering/DigitallyReconstructedRadiograph1.cxx

       例子的代码也可以在这里找到:

  https://itk.org/Doxygen/html/Examples_2Filtering_2DigitallyReconstructedRadiograph1_8cxx-example.html

  把这个代码复制出来单独的构建一个工程(也是按照第一个博客里面的方法),但是这个时候的工程是无法运行的。

  2- 代码第一个问题

  当我们运行程序的时候,程序无法运行, 提示说是因为没有定义一个IOFactory

  那么现在问题来了,IOFactory是和要写入的图像类型绑定的,

  我们要把这个当做什么类型的文件写入呢?

  这个时候的writer是三维图像,所以我们是不能够写成 bmp, jpg, 等等图像的,我就是在这里尝试很很多遍。

  后来我们经过观察发现,在程序里面有一个写入到文件的一个代码。

技术图片
#ifdef WRITE_CUBE_IMAGE_TO_FILE
    const char *filename = "body.gipl";
    using WriterType = itk::ImageFileWriter< InputImageType >;
    WriterType::Pointer writer = WriterType::New();
    itk::GiplImageIOFactory::RegisterOneFactory();
    writer->SetFileName( filename );
    writer->SetInput( image );

    try
      {
      std::cout << "Writing image: " << filename << std::endl;
      writer->Update();
      }
    catch( itk::ExceptionObject & err )
      {

      std::cerr << "ERROR: ExceptionObject caught !" << std::endl;
      std::cerr << err << std::endl;
      return EXIT_FAILURE;
      }
#endif
View Code

  最开始我根本没有观察过这个,但是后来发现是存在GiplIOFactory的,于是尝试了一下,发现就可以了。

  2.解决方法:

  也就是说,我们需要做两件事情:

  <1>声明一个GiplIOFactory

#include "itkGiplImageIOFactory.h"
itk::GiplImageIOFactory::RegisterOneFactory();

  <2>传入文件的写入参数,比如我传入的是 "1.gipl"  (注意这里的后缀需要时 .gipl, 需要注意如何在VS里面如何传入参数。)

  这个时候程序已经可以成功运行了,并且DRR图像被写入到了工程所在的文件夹。

       2.2-图像观察

  这个时候我们已经可以观察一下这个文件到底生成了一个什么东西:

  我们通过3D  slicer打开这个gipl文件,可以观察到这个三维图像和生成的DRR图像:

  <1> 三维图像

  技术图片

 

   <2>DRR图像

  技术图片

 

   可以看到,例子自己建立的图像其实是一个中空的正方体。

  3-第二个问题

   但是我希望实现的是读取的DRR图像,所以需要读取自己的CT图像。

  目前我拥有的是一系列的CT图像,他们只是2D图像,而历程里面的reader则是读取的三维图像。

  所以需要添加代码,读取自己的CT图像,然后转换为3D图像。

  添加代码如下:

技术图片
 //定义像素类型,图像类型,三维有符号数,定义指针
      typedef signed short PixelType;
      const unsigned int Dimension = 3;
      typedef itk::Image< PixelType, Dimension > ImageType;
      typedef itk::ImageSeriesReader< ImageType > ReaderType;

      //声明读、写 DICOM 图 像 的 itk::GDCMImageIO对象
      //itk::GDCMSeriesFileNames对象将生成并将构成所有体数据的切片的文件名进行排序
      typedef itk::GDCMImageIO ImageIOType;
      typedef itk::GDCMSeriesFileNames NamesGeneratorType;
      ImageIOType::Pointer gdcmIO = ImageIOType::New();
      NamesGeneratorType::Pointer namesGenerator = NamesGeneratorType::New();

      //设置读取路径
      //用文件名发生器生成被读的文件名和被写的文件名
      namesGenerator->SetInputDirectory("D:\\Files\\Data\\3219032438350584179-8\\DICOM\\S258070\\S20");
      const ReaderType::FileNamesContainer& filenames = namesGenerator->GetInputFileNames();

      //设置DICOM图像IO对象和被读的文件名的列表
      ReaderType::Pointer reader = ReaderType::New();
      reader->SetImageIO(gdcmIO);
      reader->SetFileNames(filenames);
View Code

  这个就是第三个博客里面的读取程序,唉,伤心,浪费这么久。

三、参考链接

  1-博客:https://blog.csdn.net/inter_peng/article/details/52155073

  2-第一个图来源:基于灰度的二维三维图像配准方法及其在骨科导航手术中的应用

  

以上是关于如何通过CT三维图像得到DRR的主要内容,如果未能解决你的问题,请参考以下文章

医学图像三维可视化和三维重建的区别

如何在WPF中使用VTK进行三维重建

CT片居然可以这么玩:用头部CT断层扫描片复原三维头像

CT片居然可以这么玩:用头部CT断层扫描片复原三维头像

如何在来自 Firebase 存储的片段 ImageView 中显示图像

MATLAB教程案例50通过VisualSFM工具箱提取360度等间隔环绕拍摄得到的图像序列点云数据,并进行目标三维重建matlab仿真