想必看这篇文章的读者都对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,如有错误请指出,谢谢!
不要去做一个成功的人,要去做一个有价值的人。