赞
踩
使用vtkDICOMImageReader读取dicom数据
DICOM(代表通信和医学数字成像)是一种广泛用于交换数据的医学图像文件格式。
该类可能会处理 ACR-NEMA 文件(医学图像 DICOM 格式的前身)。但该类不处理封装格式,仅处理普通原始文件。
该类不处理多帧 DICOM 数据集。
常用的成员函数:
SetFileName(const char *)
:设置文件读取路径,读取单张单帧的DCM文件SetDirectoryName(const char *)
:设置文件夹读取路径,读取多张单帧的DCM文件vtkGetFilePathMacro(DirectoryName)
:返回目录名称GetPixelSpacing ()
:获取体数据的x/y/z三轴的像素间距(mm),返回double*GetWidth ()/GetHeight ()
:获取image数据的宽、高,返回intGetImagePositionPatient()
:最后一个图像中左上角的x,y,z 坐标返回float*GetImageOrientationPatient()
:获取 (DICOM) 方向余弦GetBitsAllocated()
:获取为文件中每个像素分配的位数,返回intGetTransferSyntaxUID()
:获取最后处理的图像的传输语法 UID,GetGantryAngle()
:获取最后处理的图像的绕y轴的旋转角度,返回floatGetPatientName ()/GetStudyUID ()/GetStudyID ()
:获取病人的姓名、检查UID和检查ID等,返回const char *#include <vtkDICOMImageReader.h> #include <vtkSmartPointer.h> #include <vtkImageData.h> #include <vtkImageViewer2.h> #include <vtkAutoInit.h> VTK_MODULE_INIT(vtkRenderingOpenGL2) VTK_MODULE_INIT(vtkInteractionStyle) //path:单张:DICOM数据的存储路径,多张:DICOM数据的存储文件夹 int loadDcmDataByVTK(std::string path) { //读取单张单帧DICOM数据 //vtkSmartPointer<vtkDICOMImageReader> reader = // vtkSmartPointer<vtkDICOMImageReader>::New(); //reader->SetFileName(path.c_str()); reader->SetFileDimensionality(3); //reader->Update(); //读取多张单帧DICOM数据 vtkNew<vtkDICOMImageReader> reader; reader->SetDirectoryName(path.c_str()); reader->Update(); vtkSmartPointer<vtkImageData> imgData = vtkSmartPointer<vtkImageData>::New(); imgData->DeepCopy(reader->GetOutput()); //深拷贝 //imgData->ShallowCopy(reader->GetOutput()); //浅拷贝 std::cout << imageViewer[0] << endl; //打印体数据详细信息 this->showDiocmData(imgData); return 1; } int showDiocmData(vtkSmartPointer<vtkImageData> reader) { int size = reader->GetNumberOfPoints(); if (size <= 0) { std::cerr<< ": 输入的Dicom数据为空,请重新输入!" << std::endl; return 0; } vtkSmartPointer<vtkImageViewer2> imageViewer = vtkSmartPointer<vtkImageViewer2>::New(); imageViewer->SetInputData(reader); int index = 0; imageViewer->SetSlice(index); //设置切片index //imageViewer->SetColorLevel(int); //imageViewer->SetColorWindow(int); //设置窗宽窗位 imageViewer->GetRenderer()->ResetCamera(); imageViewer->Render(); renderWindowInteractor->Start(); return 1; }
实际应用过程中,经常会遇到多帧的DICOM数据的读取与现实,由于VTK不支持多帧数据的读取,因此可以利用DCMTK库先读取DICOM数据,再将其转换为vtkimagedata进行后续处理
DCMTK读取多帧数据的方法参见之前的帖子:
【DCMTK】使用DCMTK库读取多帧DICOM数据
读取后的两种库数据转换代码如下:
//将DCMTK读入的dicom数据存入vtkimagedata中 #include <vtkSmartPointer.h> #include <vtkImageData.h> #include <dcmtk/dcmimgle/dcmimage.h> //imgDCM:利用dcmtk库读取的多帧dicom数据 int DCMTKtoVTKImageData(DicomImage *imgDCM,double[3] spacing) { //开辟vtkimagedata的空间,初值为0 vtkSmartPointer<vtkImageData > imageVTK= vtkSmartPointer<vtkImageData >::New(); vtkSmartPointer<vtkInformation> info = vtkSmartPointer<vtkInformation>::New(); //dicom图像的宽、高和帧数(z),可以在dcmtk读取文件时获得 int row = 512; int col = 512; int frameCount = 100; int extent[6] = { 0,row - 1,0,col - 1,0,frameCount - 1 }; imageVTK->SetDimensions(row, col, framecount); imageVTK->SetExtent(extent); imageVTK->SetSpacing(spacing[0],spacing[1],spacing[2]); imageVTK->SetOrigin(0, 0, 0); imageVTK->SetScalarType(VTK_INT, info); imageVTK->SetNumberOfScalarComponents(1, info); imageVTK->AllocateScalars(info); //将DcmDataset中的像素值写入vtk for (int k = 0; k < framecount; k++) { Uint8 /*unsigned short*/ *pixelData = (Uint8*)/*(unsigned short*)*/(img->getOutputData(8, k, 0)); //获得图像数据指针 if (pixelData != NULL) { for (int i = 0; i < row; i++) { for (int j = 0; j < col; j++) { int*p = (int*)(imageVTK->GetScalarPointer(i, j, k)); *p = int(*(pixelData + row * i + j)); } } } } return 1; }
实际应用过程中,经常可能碰到itk库和vtk库的共同应用,就需要两种库数据的互相转换
具体转换代码如下:
#include <itkVTKImageToImageFilter.h> #include <vtkImageData.h> #include <itkImageToVTKImageFilter.h> #include <itkImage.h> #include <vtkSmartPointer.h> typedef int PixelType; typedef itk::Image< PixelType, 3> ImageType; //imageVTK:传入的vtk体数据 vtkSmartPointer<vtkImageData> imageVTK = vtkSmartPointer<vtkImageData>::New(); bool VTKImageToITKImage(vtkImageData* imageVTK) { typedef itk::VTKImageToImageFilter<ImageType> vtkToitkFilter; vtkToitkFilter::Pointer itkFilter = vtkToitkFilter::New(); itkFilter->SetInput(imageVTK); itkFilter->UpdateLargestPossibleRegion(); try { itkFilter->Update(); } catch (itk::ExceptionObject) { std::cerr<<"vtk to itk failed!"<<std::endl; return false; } return true; } //itkImage: 传入的itk体数据 ImageType::Pointer itkImage = ImageType::New(); bool ITKImageToVTKImage(ImageType::Pointer itkImage) { typedef itk::ImageToVTKImageFilter<ImageType> ConnectorType; ConnectorType::Pointer connector = ConnectorType::New(); connector->SetInput(itkImage ); try { connector->Update(); } catch (itk::ExceptionObject) { std::cerr<<"itk to vtk failed!"<<std::endl; return false; } vtkSmartPointer<vtkImageData> imageVTK = vtkSmartPointer<vtkImageData>::New(); imageVTK->ShallowCopy(connector->GetOutput()); return true; }
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。