这个是ITK的例子,读dcm文件夹
https://itk.org/Doxygen/html/Examples_2IO_2DicomSeriesReadImageWrite2_8cxx-example.html#_a2
下面程序可以亲测,根据上面的官网例子编写:搞了半天多,终于调通:
下面实现的是读一组CT dcm文件,并执行面绘制。顺便提一句:.dcm序列的命名最好是有规则可循的,否则会读不全。
中间用到ITK转换VTK的函数,有兴趣的可以看看。
#include <vtkImageData.h>
#include <vtkProperty.h>
#include <vtkDataSetMapper.h>
#include <vtkRendererCollection.h>
#include <itkImageToVTKImageFilter.h>
#include <vtkPolyDataMapper.h>
#include <vtkPolyData.h>
#include <vtkPointData.h>
#include "vtkRenderWindowInteractor.h"
#include "vtkRenderer.h"
#include "vtkRenderWindow.h"
#include "vtkMarchingCubes.h"
#include "vtkStripper.h"
#include "vtkActor.h"
#include "vtkSmoothPolyDataFilter.h"
#include "vtkPolyDataNormals.h"
#include "vtkImageShrink3D.h"
#include "vtkDecimatePro.h"
#include "vtkProperty.h"
#include <vtkInteractorStyleImage.h>
#include "itkImageToVTKImageFilter.h"
#include "itkImage.h"
#include "itkGDCMImageIO.h"
#include "itkGDCMSeriesFileNames.h"
#include "itkImageSeriesReader.h"
VTK_MODULE_INIT(vtkRenderingOpenGL2);
VTK_MODULE_INIT(vtkInteractionStyle);
using PixelType = float;
constexpr unsigned int Dimension = 3;
using ImageType = itk::Image< PixelType, Dimension >;
// Software Guide : EndCodeSnippet
int main( int argc, char* argv[] )
{
using ReaderType = itk::ImageSeriesReader< ImageType >;
using ImageIOType = itk::GDCMImageIO;
using NamesGeneratorType = itk::GDCMSeriesFileNames;
ReaderType::Pointer reader = ReaderType::New();
ImageIOType::Pointer dicomIO = ImageIOType::New();
reader->SetImageIO( dicomIO );
NamesGeneratorType::Pointer nameGenerator = NamesGeneratorType::New();
nameGenerator->SetUseSeriesDetails( true );
nameGenerator->SetDirectory( "/Users/mac/Desktop/我的文件/血管分割项目/CT数据/CT扫描数据" );
using SeriesIdContainer = std::vector< std::string >;
const SeriesIdContainer & seriesUID = nameGenerator->GetSeriesUIDs();
auto seriesItr = seriesUID.begin();
auto seriesEnd = seriesUID.end();
using FileNamesContainer = std::vector< std::string >;
FileNamesContainer fileNames ;
std::string seriesIdentifier;
while( seriesItr != seriesEnd )
{
seriesIdentifier = seriesItr->c_str();
fileNames = nameGenerator->GetFileNames( seriesIdentifier );
++seriesItr;
}
reader->SetFileNames( fileNames );
try
{
reader->Update();
}
catch (itk::ExceptionObject &ex)
{
std::cout << ex << std::endl;
return EXIT_FAILURE;
}
ImageType::SizeType imgSize = reader->GetOutput()->GetLargestPossibleRegion().GetSize();
cout << "read done!Original size: " << imgSize << endl;
typedef itk::ImageToVTKImageFilter< ImageType> itkTovtkFilterType;
itkTovtkFilterType::Pointer itkTovtkImageFilter = itkTovtkFilterType::New();
itkTovtkImageFilter->SetInput(reader->GetOutput());
itkTovtkImageFilter->Update();
vtkSmartPointer<vtkMarchingCubes> vesselExtractor = vtkMarchingCubes::New();
vesselExtractor->SetInputData(itkTovtkImageFilter->GetOutput());
vesselExtractor->SetNumberOfContours(10);
vesselExtractor->SetValue( 0 , 1); //轮廓
//将提取的等值面拼接成连续的
vtkSmartPointer<vtkStripper> vesselStripper = vtkStripper::New(); //建立三角带对象
vesselStripper->SetInputConnection(vesselExtractor->GetOutputPort());
vtkSmartPointer<vtkPolyDataMapper> vesselMapper = vtkPolyDataMapper::New(); //建立一个数据映射对象
vesselMapper->SetInputConnection(vesselStripper->GetOutputPort()); //将三角带映射为几何数据
vesselMapper->SetScalarRange(0,7);
//对象和对象属性等设置
vtkSmartPointer<vtkActor> vessel = vtkActor::New();
vessel->SetMapper(vesselMapper);
vessel->GetProperty()->SetColor(0,0,1);
// A renderer and render window
vtkSmartPointer<vtkRenderer> renderer =vtkSmartPointer<vtkRenderer>::New();
vtkSmartPointer<vtkRenderWindow> renderWindow =vtkSmartPointer<vtkRenderWindow>::New();
renderWindow->AddRenderer(renderer);
renderWindow->SetSize(1000, 1000);
renderer->AddActor(vessel);
// An interactor
vtkSmartPointer<vtkRenderWindowInteractor> renderWindowInteractor =
vtkSmartPointer<vtkRenderWindowInteractor>::New();
renderWindowInteractor->SetRenderWindow(renderWindow);
renderWindow->Render();
renderWindow->SetWindowName(“啦啦啦,我是卖报的小行家”);//这一句一定是在render()后面,否则无效,为什么没人告诉我
renderWindowInteractor->Initialize();
renderWindow->Render();
renderWindowInteractor->Start();
return 0;
}
一步步摸索,且珍惜 吧 !!!