DCMTK读取压缩格式的DICOM文件并使用Vtk显示

5 篇文章 3 订阅
3 篇文章 2 订阅

想必看这篇文章的读者都对vtk有或多或少的认识,vtk中的vtkDICOMImageReader是用来读取DICOM文件的类,但是其只能读取未压缩格式的DICOM文件,本人手头上需要显示和处理的DICOM均为压缩格式的DICOM文件(1.2.840.10008.1.2.4.70 [JPEG Lossless, Non-Hierarchical, First-Order Prediction (Process 14 [Selection Value 1]): Default Transfer Syntax for Lossless JPEG Image Compression]),直接使用该类读取会报如下错误

ERROR: In E:\SourceCode\VTK-8.2.0\IO\Image\vtkDICOMImageReader.cxx, line 270

vtkDICOMImageReader (000001D37701A6D0): There was a problem retrieving data from: E://DICOM//2021071009//0200.dcm

这时候就需要借助其他库来读取这种格式的DICOM文件,通过网上冲浪得知,以下库可以完成读取:GDCM、ITK(读取也是gdcm实现的)、DCMTK等,这里作者选择使用dcmtk进行读取。

1-下载、编译

和vtk一样,这里就不作详细介绍了,dcmtk官方地址:dicom.offis.de - Home,如果编译不成功可以和我联系,这里是在windows 10操作系统中编译,使用cmake+VS2017。

2-Demo

IDE工具用的是Qt 5.14.1 + VS2017。创建项目,配置pro文件,为了方便就把所有文件都添加了进来,后期项目上可以按需求添加。

INCLUDEPATH += \
    D:/ThridPartyLibrary/gdcm/debug/include/gdcm-3.0 \
    D:/ThridPartyLibrary/vtk/debug/include/vtk-8.2 \
    D:/ThridPartyLibrary/dcmtk/debug/include \

LIBS += \
    -LD:/ThridPartyLibrary/gdcm/debug/lib/ \
    -LD:/ThridPartyLibrary/vtk/debug/lib \
    -LD:/ThridPartyLibrary/dcmtk/debug/lib \
    -lgdcmcharls \
    -lgdcmCommon \
    -lgdcmDICT \
    -lgdcmDSED \
    -lgdcmexpat \
    -lgdcmgetopt \
    -lgdcmIOD \
    -lgdcmjpeg12 \
    -lgdcmjpeg16 \
    -lgdcmjpeg8 \
    -lgdcmMEXD \
    -lgdcmMSFF \
    -lgdcmopenjp2 \
    -lgdcmzlib \
    -lsocketxx \
    -lvtkgdcm \
    -lvtkChartsCore-8.2 \
    -lvtkCommonColor-8.2 \
    -lvtkCommonComputationalGeometry-8.2 \
    -lvtkCommonCore-8.2 \
    -lvtkCommonDataModel-8.2 \
    -lvtkCommonExecutionModel-8.2 \
    -lvtkCommonMath-8.2 \
    -lvtkCommonMisc-8.2 \
    -lvtkCommonSystem-8.2 \
    -lvtkCommonTransforms-8.2 \
    -lvtkDICOMParser-8.2 \
    -lvtkDomainsChemistry-8.2 \
    -lvtkDomainsChemistryOpenGL2-8.2 \
    -lvtkdoubleconversion-8.2 \
    -lvtkexodusII-8.2 \
    -lvtkexpat-8.2 \
    -lvtkFiltersAMR-8.2 \
    -lvtkFiltersCore-8.2 \
    -lvtkFiltersExtraction-8.2 \
    -lvtkFiltersFlowPaths-8.2 \
    -lvtkFiltersGeneral-8.2 \
    -lvtkFiltersGeneric-8.2 \
    -lvtkFiltersGeometry-8.2 \
    -lvtkFiltersHybrid-8.2 \
    -lvtkFiltersHyperTree-8.2 \
    -lvtkFiltersImaging-8.2 \
    -lvtkFiltersModeling-8.2 \
    -lvtkFiltersParallel-8.2 \
    -lvtkFiltersParallelImaging-8.2 \
    -lvtkFiltersPoints-8.2 \
    -lvtkFiltersProgrammable-8.2 \
    -lvtkFiltersSelection-8.2 \
    -lvtkFiltersSMP-8.2 \
    -lvtkFiltersSources-8.2 \
    -lvtkFiltersStatistics-8.2 \
    -lvtkFiltersTexture-8.2 \
    -lvtkFiltersTopology-8.2 \
    -lvtkFiltersVerdict-8.2 \
    -lvtkfreetype-8.2 \
    -lvtkGeovisCore-8.2 \
    -lvtkgl2ps-8.2 \
    -lvtkglew-8.2 \
    -lvtkGUISupportMFC-8.2 \
    -lvtkGUISupportQt-8.2 \
    -lvtkGUISupportQtOpenGL-8.2 \
    -lvtkGUISupportQtSQL-8.2 \
    -lvtkhdf5-8.2 \
    -lvtkhdf5_hl-8.2 \
    -lvtkImagingColor-8.2 \
    -lvtkImagingCore-8.2 \
    -lvtkImagingFourier-8.2 \
    -lvtkImagingGeneral-8.2 \
    -lvtkImagingHybrid-8.2 \
    -lvtkImagingMath-8.2 \
    -lvtkImagingMorphological-8.2 \
    -lvtkImagingSources-8.2 \
    -lvtkImagingStatistics-8.2 \
    -lvtkImagingStencil-8.2 \
    -lvtkInfovisCore-8.2 \
    -lvtkInfovisLayout-8.2 \
    -lvtkInteractionImage-8.2 \
    -lvtkInteractionStyle-8.2 \
    -lvtkInteractionWidgets-8.2 \
    -lvtkIOAMR-8.2 \
    -lvtkIOAsynchronous-8.2 \
    -lvtkIOCityGML-8.2 \
    -lvtkIOCore-8.2 \
    -lvtkIOEnSight-8.2 \
    -lvtkIOExodus-8.2 \
    -lvtkIOExport-8.2 \
    -lvtkIOExportOpenGL2-8.2 \
    -lvtkIOExportPDF-8.2 \
    -lvtkIOGeometry-8.2 \
    -lvtkIOImage-8.2 \
    -lvtkIOImport-8.2 \
    -lvtkIOInfovis-8.2 \
    -lvtkIOLegacy-8.2 \
    -lvtkIOLSDyna-8.2 \
    -lvtkIOMINC-8.2 \
    -lvtkIOMovie-8.2 \
    -lvtkIONetCDF-8.2 \
    -lvtkIOParallel-8.2 \
    -lvtkIOParallelXML-8.2 \
    -lvtkIOPLY-8.2 \
    -lvtkIOSegY-8.2 \
    -lvtkIOSQL-8.2 \
    -lvtkIOTecplotTable-8.2 \
    -lvtkIOVeraOut-8.2 \
    -lvtkIOVideo-8.2 \
    -lvtkIOXML-8.2 \
    -lvtkIOXMLParser-8.2 \
    -lvtkjpeg-8.2 \
    -lvtkjsoncpp-8.2 \
    -lvtklibharu-8.2 \
    -lvtklibxml2-8.2 \
    -lvtkLocalExample-8.2 \
    -lvtklz4-8.2 \
    -lvtklzma-8.2 \
    -lvtkmetaio-8.2 \
    -lvtkNetCDF-8.2 \
    -lvtkogg-8.2 \
    -lvtkParallelCore-8.2 \
    -lvtkpng-8.2 \
    -lvtkproj-8.2 \
    -lvtkpugixml-8.2 \
    -lvtkRenderingAnnotation-8.2 \
    -lvtkRenderingContext2D-8.2 \
    -lvtkRenderingContextOpenGL2-8.2 \
    -lvtkRenderingCore-8.2 \
    -lvtkRenderingFreeType-8.2 \
    -lvtkRenderingGL2PSOpenGL2-8.2 \
    -lvtkRenderingImage-8.2 \
    -lvtkRenderingLabel-8.2 \
    -lvtkRenderingLOD-8.2 \
    -lvtkRenderingOpenGL2-8.2 \
    -lvtkRenderingQt-8.2 \
    -lvtkRenderingVolume-8.2 \
    -lvtkRenderingVolumeOpenGL2-8.2 \
    -lvtksqlite-8.2 \
    -lvtksys-8.2 \
    -lvtkTestingGenericBridge-8.2 \
    -lvtkTestingIOSQL-8.2 \
    -lvtkTestingRendering-8.2 \
    -lvtktheora-8.2 \
    -lvtktiff-8.2 \
    -lvtkverdict-8.2 \
    -lvtkViewsContext2D-8.2 \
    -lvtkViewsCore-8.2 \
    -lvtkViewsInfovis-8.2 \
    -lvtkViewsQt-8.2 \
    -lvtkzlib-8.2 \
    -lcmr \
    -ldcmdata \
    -ldcmdsig \
    -ldcmect \
    -ldcmfg \
    -ldcmimage \
    -ldcmimgle \
    -ldcmiod \
    -ldcmjpeg \
    -ldcmjpls \
    -ldcmnet \
    -ldcmpmap \
    -ldcmpstat \
    -ldcmqrdb \
    -ldcmrt \
    -ldcmseg \
    -ldcmsr \
    -ldcmtkcharls \
    -ldcmtls \
    -ldcmtract \
    -ldcmwlm \
    -li2d \
    -lijg12 \
    -lijg16 \
    -lijg8 \
    -loflog \
    -lofstd \

引入头文件,初始化vtk

#include <dcmtk/dcmdata/dctk.h>
#include <dcmtk/dcmdata/dcfilefo.h>
#include <dcmtk/dcmimgle/dcmimage.h>
#include <dcmtk/dcmimage/diregist.h>
#include <dcmtk/dcmjpeg/djdecode.h>
#include <dcmtk/ofstd/ofstring.h>
#include <dcmtk/dcmdata/dcostrmb.h>

#include <vtkAutoInit.h>
VTK_MODULE_INIT(vtkRenderingOpenGL2) ;
VTK_MODULE_INIT(vtkInteractionStyle) ;
VTK_MODULE_INIT(vtkRenderingFreeType);

#include <vtkImageImport.h>
#include <vtkRenderWindow.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkRenderer.h>
#include <vtkSmartPointer.h>
#include <vtkImageViewer2.h>


读取、解压缩并显示dicom文件

DJDecoderRegistration::registerCodecs(); // register JPEG codecs
    DcmFileFormat fileformat;
    if (fileformat.loadFile("E://DICOM//2021071009//0200.dcm").good())
    {
      DcmDataset *dataset = fileformat.getDataset();

      // decompress data set if compressed
      if (dataset->chooseRepresentation(EXS_LittleEndianExplicit, NULL).good() &&
          dataset->canWriteXfer(EXS_LittleEndianExplicit))
      {
        //fileformat.saveFile("0200_decompressed.dcm", EXS_LittleEndianExplicit);
          DicomImage* image = new DicomImage(dataset, EXS_LittleEndianExplicit); //生成DicomImage
          if (image != NULL && image->getStatus() == EIS_Normal)
          {
              IntType *SliceData = (IntType *)(image->getOutputData(BIT /* bits per sample */));
              cout << SliceData << endl;
              if(SliceData != NULL)
              {
                  vtkSmartPointer<vtkImageImport> import = vtkImageImport::New();
                  import->SetImportVoidPointer(SliceData);
                  import->SetDataScalarTypeToShort();
                  import->SetDataExtent(0,775,0,775,0,0);
                  import->SetWholeExtent(0,775,0,775,0,0);
                  import->Update();

                  vtkSmartPointer<vtkImageViewer2> viewer = vtkImageViewer2::New();
                  vtkSmartPointer<vtkRenderWindowInteractor> interactor = vtkRenderWindowInteractor::New();
                  viewer->SetupInteractor(interactor);

                  viewer->SetInputConnection(import->GetOutputPort());
                  viewer->SetColorLevel(600);
                  viewer->SetColorWindow(3200);

                  viewer->Render();

                  interactor->Start();
              }

          }
          else
          {
              cerr << "Error: cannot load DICOM image ("
                  << DicomImage::getString(image->getStatus())
                  << ").\nError code: 3" << endl;
              return 3;
          }
          delete image;
      }
    }
    DJDecoderRegistration::cleanup();

显示效果图:

 以上仅为简易版本demo,如有错误请指出,谢谢!

不要去做一个成功的人,要去做一个有价值的人。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

把我格子衫拿来

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值