目前遇到一个需求,需要利用VTK对三维体数据进行切片提取。利用到的类是vtkImageReslice,下面是该类的一个介绍: Reslices a volume along a new set of axes. vtkImageReslice is the swiss-army-knife of image geometry filters: It can permute, rotate, flip, scale, resample, deform, and pad image data in any combination with reasonably high efficiency. Simple operations such as permutation, resampling and padding are done with similar efficiently to the specialized vtkImagePermute, vtkImageResample, and vtkImagePad filters. There are a number of tasks that vtkImageReslice is well suited for:
Application of simple rotations, scales, and translations to an image. It is often a good idea to use vtkImageChangeInformation to center the image first, so that scales and rotations occur around the center rather than around the lower-left corner of the image.Resampling of one data set to match the voxel sampling of a second data set via the SetInformationInput() method, e.g. for the purpose of comparing two images or combining two images. A transformation, either linear or nonlinear, can be applied at the same time via the SetResliceTransform method if the two images are not in the same coordinate space.Extraction of slices from an image volume. The most convenient way to do this is to use SetResliceAxesDirectionCosines() to specify the orientation of the slice. The direction cosines give the x, y, and z axes for the output volume. The method SetOutputDimensionality(2) is used to specify that want to output a slice rather than a volume. The SetResliceAxesOrigin() command is used to provide an (x,y,z) point that the slice will pass through. You can use both the ResliceAxes and the ResliceTransform at the same time, in order to extract slices from a volume that you have applied a transformation to. 这边提取切片利用到的就是第三条,从体中提取切片。 主要用到的几个方法有: 1)SetOutputDimensionality():设置输出的维数。因为我要提取的是一张切片,是一个二维图像,所以括号里应该填2,表示二维 2)SetResliceAxes()::设置输入的坐标。这个坐标是一个4*4的矩阵形式,第1-3行和1-3列的九个元素决定了切片的方向。最后一列前三行决定了坐标中心的位置,通过改变这三个元素的值,可以对不同坐标的切片进行提取。第4行的元素分别为 0,0,0,1.不要修改,否则无法显示切片。 3)此外,还可以设置切片提取的插值方式,有线性插值(SetInterpolationModeToLinear)、最近邻差值(SetInterpolationModeToNearestNeighbor)、三次线性插值(SetInterpolationModeToCubic) 下面代码为东灵工作室VTKExemple中的例程,做一些说明。 /********************************************************************** 文件名: 5.3_ImageResliceExample.cpp Copyright (c) 张晓东, 罗火灵. All rights reserved. 更多信息请访问: http://www.vtkchina.org (VTK中国) http://blog.csdn.net/www_doling_net (东灵工作室) **********************************************************************/ #include <vtkSmartPointer.h> #include <vtkMatrix4x4.h> #include <vtkImageReslice.h> #include <vtkImageActor.h> #include <vtkRenderer.h> #include <vtkRenderWindow.h> #include <vtkRenderWindowInteractor.h> #include <vtkInteractorStyleImage.h> #include <vtkImageData.h> #include <vtkMetaImageReader.h> #include <vtkImageCast.h> #include <vtkLookupTable.h> #include <vtkImageMapToColors.h> //测试图像:..\\data\\brain.mhd int main(int argc, char* argv[]) { if (argc < 2) { std::cout<<argv[0]<<" "<<"ImageFile(*.mhd)"<<std::endl; return EXIT_FAILURE; } vtkSmartPointer<vtkMetaImageReader> reader = vtkSmartPointer<vtkMetaImageReader>::New(); reader->SetFileName(argv[1]); reader->Update(); int extent[6]; double spacing[3]; double origin[3]; reader->GetOutput()->GetExtent(extent); reader->GetOutput()->GetSpacing(spacing); reader->GetOutput()->GetOrigin(origin); double center[3]; center[0] = origin[0] + spacing[0] * 0.5 * (extent[0] + extent[1]); center[1] = origin[1] + spacing[1] * 0.5 * (extent[2] + extent[3]); center[2] = origin[2] + spacing[2] * 0.5 * (extent[4] + extent[5]); //这个函数是坐标信息,代表切片方向是平行于XY平面 static double axialElements[16] = { 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1 }; // XZ平面的坐标为: // 1, 0, 0, 0, // 0, 0, 1, 0, // 0, -1, 0, 0, // 0, 0, 0, 1 // YZ平面的坐标为: // 0, 0, -1, 0, // 1, 0, 0, 0, // 0, -1,0, 0, // 0, 0, 0, 1 //这边是重点,它通过设置最后一列的元素,决定对哪一个平面进行提取,center表示要进行提取的三维体的中心坐标。 //我之前就一直卡在这个地方,改的就是上面的一个4*4的坐标最后一列,发现没有用。后来发现原来是下面的一个函数 //对它的元素进行了更改,改成了以中心为坐标,上面怎么改都没用,最后出来的切片图是同一张 //那么是否可以把下面的SetElement这三行全部注释掉,改上面的就有用了??我觉得应该行,还没试。 vtkSmartPointer<vtkMatrix4x4> resliceAxes = vtkSmartPointer<vtkMatrix4x4>::New(); resliceAxes->DeepCopy(axialElements); resliceAxes->SetElement(0, 3, center[0]); resliceAxes->SetElement(1, 3, center[1]); resliceAxes->SetElement(2, 3, center[2]); //下面就是进行切片提取的方法,提取一个二维的切片,采用线性插值的插值方法 vtkSmartPointer<vtkImageReslice> reslice = vtkSmartPointer<vtkImageReslice>::New(); reslice->SetInputConnection(reader->GetOutputPort()); reslice->SetOutputDimensionality(2); reslice->SetResliceAxes(resliceAxes); reslice->SetInterpolationModeToLinear(); vtkSmartPointer<vtkLookupTable> colorTable = vtkSmartPointer<vtkLookupTable>::New(); colorTable->SetRange(0, 1000); colorTable->SetValueRange(0.0, 1.0); colorTable->SetSaturationRange(0.0, 0.0); colorTable->SetRampToLinear(); colorTable->Build(); vtkSmartPointer<vtkImageMapToColors> colorMap = vtkSmartPointer<vtkImageMapToColors>::New(); colorMap->SetLookupTable(colorTable); colorMap->SetInputConnection(reslice->GetOutputPort()); vtkSmartPointer<vtkImageActor> imgActor = vtkSmartPointer<vtkImageActor>::New(); imgActor->SetInput(colorMap->GetOutput()); vtkSmartPointer<vtkRenderer> renderer = vtkSmartPointer<vtkRenderer>::New(); renderer->AddActor(imgActor); renderer->SetBackground(1.0, 1.0, 1.0); vtkSmartPointer<vtkRenderWindow> renderWindow = vtkSmartPointer<vtkRenderWindow>::New(); renderWindow->AddRenderer(renderer); renderWindow->Render(); renderWindow->SetSize(640, 480); renderWindow->SetWindowName("ImageResliceExample"); vtkSmartPointer<vtkRenderWindowInteractor> renderWindowInteractor = vtkSmartPointer<vtkRenderWindowInteractor>::New(); vtkSmartPointer<vtkInteractorStyleImage> imagestyle = vtkSmartPointer<vtkInteractorStyleImage>::New(); renderWindowInteractor->SetInteractorStyle(imagestyle); renderWindowInteractor->SetRenderWindow(renderWindow); renderWindowInteractor->Initialize(); renderWindowInteractor->Start(); return EXIT_SUCCESS; }通过以上部分就可以对三维体进行提取了。我用的是mha文件,数据格式是否只支持vtkImageData还不清楚,反正我用vtkPolyData数据不能进行提取。
