下面简单地介绍三种读取序列图像的方法,后续在窗口中的显示使用vtkImageActor、vtkImageviewer2或vtkActor都可以 。
方法一
使用一个数组先读入文件名,然后再将数组名作为reader->SetFileNames的参数传入
void MainWindow::ReadSeriesImages1(){
//生成图像序列的文件名数组
vtkSmartPointer< vtkStringArray > fileArray =
vtkSmartPointer< vtkStringArray >::New();
char fileName[128];
for(int i = 1; i < 100; i++)
{
sprintf(fileName, "VTK_test/Head/head%03d.jpg", i);
std::string fileStr(fileName);
fileArray->InsertNextValue(fileStr);
}
//读取JPG序列图像
vtkSmartPointer<vtkJPEGReader> reader =
vtkSmartPointer<vtkJPEGReader>::New();
reader->SetFileNames(fileArray);
vtkSmartPointer<vtkInteractorStyleImage> style =
vtkSmartPointer<vtkInteractorStyleImage>::New();
//显示读取的JPG图像
vtkSmartPointer<vtkImageViewer2> imageViewer =
vtkSmartPointer<vtkImageViewer2>::New();
imageViewer->SetInputConnection(reader->GetOutputPort());
vtkSmartPointer<vtkRenderWindowInteractor> renderWindowInteractor =
vtkSmartPointer<vtkRenderWindowInteractor>::New();
renderWindowInteractor->SetInteractorStyle(style);
imageViewer->SetSlice(50); //默认显示第50个切片(即第50层)
imageViewer->SetSliceOrientationToXY();
//imageViewer->SetSliceOrientationToYZ();
//imageViewer->SetSliceOrientationToXZ();
imageViewer->SetupInteractor(renderWindowInteractor);
imageViewer->Render();
imageViewer->GetRenderer()->SetBackground(1.0, 1.0, 1.0);
imageViewer->SetSize(640, 480);
imageViewer->GetRenderWindow()->SetWindowName("ReadSeriesImages1");
renderWindowInteractor->Start();
}
方法二
参数SetFilePrefix()表示文件名中相同的部分,SetFilePattern()表示文件名中不同的部分,Reader->SetDataExtent(0, 2047, 0, 2047, 1, 30)表示图像为2048x2048,序号为1-30
//创建reader对象
vtkSmartPointer<vtkBMPReader>Reader =
vtkSmartPointer<vtkBMPReader>::New();
Reader->SetDataScalarTypeToUnsignedChar();
Reader->SetFileDimensionality(3);
//设置图像的文件名前缀
Reader->SetFilePrefix("/home/yanghantao/Documents/ruxian/");
Reader->SetFileNameSliceSpacing(1);
//设置图像文件名后缀
Reader->SetFilePattern("%s%03d_R.bmp");
//图像大小为2048*2048,序号为1-30
Reader->SetDataExtent(0, 2047, 0, 2047, 1, 30);
Reader->SetDataSpacing(1, 1, 10);
//数据流更新
Reader->Update();
// 显示读取的BMP图像
vtkSmartPointer<vtkImageViewer2> imageViewer =
vtkSmartPointer<vtkImageViewer2>::New();
imageViewer->SetInputConnection(Reader->GetOutputPort());
vtkSmartPointer<vtkRenderWindowInteractor> renderWindowInteractor =
vtkSmartPointer<vtkRenderWindowInteractor>::New();
imageViewer->SetupInteractor(renderWindowInteractor);
imageViewer->SetColorLevel(128);
imageViewer->SetColorWindow(256);
imageViewer->SetSlice(2);
imageViewer->SetSliceOrientationToXY();
//imageViewer->SetSize(512,512);
imageViewer->Render();
renderWindowInteractor->Start();
方法三
vtkSmartPointer<vtkImageAppend > append =
vtkSmartPointer<vtkImageAppend >::New();
/*
This axis is expanded to hold the multiple images.
The default AppendAxis is the X axis.
If you want to create a volue from a series of XY images,
then you should set the AppendAxis to 2 (Z axis).
*/
append->SetAppendAxis(2);//设置图片叠加方式为沿Z轴叠加
for(int i = 1; i < 31; i++)
{
//reader一定要在循环体里面新建
vtkSmartPointer<vtkBMPReader>reader =
vtkSmartPointer<vtkBMPReader>::New();
char fileName[128];
sprintf(fileName,"/home/yanghantao/Documents/ruxian/%03d_R.bmp", i);
reader->SetFileName(fileName);
append->AddInputConnection(reader->GetOutputPort());
}
append->Update();
关于方法三的一些问题:
网传的大部分代码是这样写的:
vtkSmartPointer<vtkImageAppend > append =
vtkSmartPointer<vtkImageAppend >::New();
/*
This axis is expanded to hold the multiple images.
The default AppendAxis is the X axis.
If you want to create a volue from a series of XY images,
then you should set the AppendAxis to 2 (Z axis).
*/
append->SetAppendAxis(2);//设置图片叠加方式为沿Z轴叠加
vtkSmartPointer<vtkBMPReader>reader =
vtkSmartPointer<vtkBMPReader>::New();
for(int i = 1; i < 31; i++)
{
char fileName[128];
sprintf(fileName,"/home/yanghantao/Documents/ruxian/%03d_R.bmp", i);
reader->SetFileName(fileName);
append->AddInputConnection(reader->GetOutputPort());
}
append->Update();
这个在教程及网页上广为流传的代码有问题,也就是AddInputConnection,是一个建立数据流的指针,他指向的reader的输出,但这里reader是一个唯一地址,每次读取,其地址不变,但内容变了,append因此add了30个同一个地址指向,而reader内容会随着每个循环动态更新,最后,所有的append的指向指针都是同一图,然后怎样更新,都不变。所以我们需要在循环里面每次新建一个reader。
详细请看:Wrong behaviour stacking different images with vtkImageAppend - Support - VTK