基于C++的VTK不同格式文件读取与另存整理

实例1:读取STL文件并渲染显示

实例2:读取VTI文件并渲染显示

实例3:读取VTK文件并渲染显示

实例4:读取MHA文件并渲染显示

实例5:读取DCM文件并渲染显示

实例6:读取MHD文件并渲染显示

实例7:读取VTK格式文件并另存为OBJ格式

实例8:读取STL格式文件并另存为OBJ格式

实例9:读取STL格式文件并另存为MHD格式(切片处理)

实例10:读取STL格式文件并另存为MHA格式(切片处理)

实例11:读取STL格式文件并另存为VTI格式(切片处理)

本例程配套完整源码和素材下载

 

实例1:读取STL文件并渲染显示

#include <vtkAutoInit.h>
VTK_MODULE_INIT(vtkRenderingOpenGL2);
VTK_MODULE_INIT(vtkInteractionStyle);
#include <vtkPolyData.h>
#include <vtkSTLReader.h>
#include <vtkSmartPointer.h>
#include <vtkPolyDataMapper.h>
#include <vtkActor.h>
#include <vtkRenderWindow.h>
#include <vtkRenderer.h>
#include <vtkRenderWindowInteractor.h>
//读取STL文件并显示(可视化)
int main(int argc, char* argv[])
{
    /*if (argc != 2)
    {
        cout << "Required parameters: Filename" << endl;
        return EXIT_FAILURE;
    }*/

    std::string inputFilename = "骨盆模型.stl";//读取STL模型

    vtkSmartPointer<vtkSTLReader> reader =
        vtkSmartPointer<vtkSTLReader>::New();
    reader->SetFileName(inputFilename.c_str());
    reader->Update();

    // Visualize
    vtkSmartPointer<vtkPolyDataMapper> mapper =
        vtkSmartPointer<vtkPolyDataMapper>::New();
    mapper->SetInputConnection(reader->GetOutputPort());

    vtkSmartPointer<vtkActor> actor =
        vtkSmartPointer<vtkActor>::New();
    actor->SetMapper(mapper);

    vtkSmartPointer<vtkRenderer> renderer =
        vtkSmartPointer<vtkRenderer>::New();
    vtkSmartPointer<vtkRenderWindow> renderWindow =
        vtkSmartPointer<vtkRenderWindow>::New();
    renderWindow->AddRenderer(renderer);
    vtkSmartPointer<vtkRenderWindowInteractor> renderWindowInteractor =
        vtkSmartPointer<vtkRenderWindowInteractor>::New();
    renderWindowInteractor->SetRenderWindow(renderWindow);

    renderer->AddActor(actor);
    renderer->SetBackground(.3, .6, .3); // Background color green

    renderWindow->Render();
    renderWindowInteractor->Start();

    return EXIT_SUCCESS;
}

     

实例2:读取VTI文件并渲染显示

#include <vtkAutoInit.h>
VTK_MODULE_INIT(vtkRenderingOpenGL2);
VTK_MODULE_INIT(vtkInteractionStyle);
#include <vtkSmartPointer.h>
#include <vtkProperty.h>
#include <vtkDataSetMapper.h>
#include <vtkImageActor.h>
#include <vtkImageViewer2.h>
#include <vtkXMLImageDataReader.h>
#include <vtkRenderWindow.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkRenderer.h>
#include <vtkImageCast.h>

int main() {

    std::string inputFilename = "血管.vti";
    // 读取数据
    vtkSmartPointer<vtkXMLImageDataReader> reader =
        vtkSmartPointer<vtkXMLImageDataReader>::New();
    reader->SetFileName(inputFilename.c_str());
    reader->Update();
    //转换数据类型
    vtkNew<vtkImageCast> readercast;
    readercast->SetInputConnection(reader->GetOutputPort());
    readercast->SetOutputScalarTypeToUnsignedChar();//转换为图像数据
    readercast->ClampOverflowOn();//默认情况下,该变量值为0;当设置为1时,输出的像素值不能超过输出类型的最大值。
    readercast->Update();

    // 可视化
    vtkSmartPointer<vtkDataSetMapper> mapper =
        vtkSmartPointer<vtkDataSetMapper>::New();
    mapper->SetInputConnection(readercast->GetOutputPort());
    //渲染
    vtkSmartPointer<vtkActor> actor =
        vtkSmartPointer<vtkActor>::New();
    actor->SetMapper(mapper);
    actor->GetProperty()->SetRepresentationToWireframe();

    vtkSmartPointer<vtkRenderer> renderer =
        vtkSmartPointer<vtkRenderer>::New();
    renderer->AddActor(actor);
    renderer->ResetCamera();
    renderer->SetBackground(1, 1, 1);

    vtkSmartPointer<vtkRenderWindow> renderWindow =
        vtkSmartPointer<vtkRenderWindow>::New();
    renderWindow->AddRenderer(renderer);

    vtkSmartPointer<vtkRenderWindowInteractor> renderWindowInteractor =
        vtkSmartPointer<vtkRenderWindowInteractor>::New();
    renderWindowInteractor->SetRenderWindow(renderWindow);
    renderWindowInteractor->Initialize();
    renderWindowInteractor->Start();

    return EXIT_SUCCESS;
}

      

实例3:读取VTK文件并渲染显示

#include "vtkAutoInit.h" 
VTK_MODULE_INIT(vtkRenderingOpenGL2);
VTK_MODULE_INIT(vtkInteractionStyle);

#include <vtkConeSource.h>//源数据
#include <vtkPolyDataReader.h>//vtk格式数据读取
#include <vtkPolyDataMapper.h>//数据映射
#include <vtkRenderer.h>//绘制器
#include <vtkRenderWindow.h>//绘制窗口
#include <vtkActor.h>//演员
#include <vtkCamera.h>//照相机
#include <vtkRenderWindowInteractor.h>//加入交互机制类

int main()
{
	vtkSmartPointer<vtkRenderer> aRenderer =
		vtkSmartPointer<vtkRenderer>::New();
	vtkSmartPointer<vtkRenderWindow> renWin =
		vtkSmartPointer<vtkRenderWindow>::New();
	renWin->AddRenderer(aRenderer);

	vtkSmartPointer<vtkRenderWindowInteractor> iren =
		vtkSmartPointer<vtkRenderWindowInteractor>::New();
	iren->SetRenderWindow(renWin);

	vtkSmartPointer<vtkPolyDataReader> vtkReader = vtkSmartPointer<vtkPolyDataReader>::New();
	vtkReader->SetFileName("股骨.vtk");//读取VTK格式文件

	vtkSmartPointer<vtkPolyDataMapper> skinMapper =
		vtkSmartPointer<vtkPolyDataMapper>::New();
	skinMapper->SetInputConnection(vtkReader->GetOutputPort());
	skinMapper->ScalarVisibilityOff();    //这样不会带颜色

	vtkSmartPointer<vtkActor> skin =
		vtkSmartPointer<vtkActor>::New();
	skin->SetMapper(skinMapper);

	vtkSmartPointer<vtkCamera> aCamera =
		vtkSmartPointer<vtkCamera>::New();
	aCamera->SetViewUp(0, 0, -1);
	aCamera->SetPosition(0, 1, 0);
	aCamera->SetFocalPoint(0, 0, 0);
	aCamera->ComputeViewPlaneNormal();
	aCamera->Azimuth(30.0);
	aCamera->Elevation(30.0);
	aCamera->Dolly(1.5);

	aRenderer->AddActor(skin);
	aRenderer->SetActiveCamera(aCamera);
	aRenderer->ResetCamera();
	aRenderer->SetBackground(.2, .3, .4);
	aRenderer->ResetCameraClippingRange();

	renWin->Render();
	iren->Initialize();
	iren->Start();
}

     

实例4:读取MHA文件并渲染显示

#include "vtkSmartPointer.h"
#include "vtkMetaImageReader.h"
#include "vtkImageViewer2.h"
#include "vtkRenderWindowInteractor.h"
#include "vtkInteractorStyleTrackballCamera.h"
#include "vtkAutoInit.h"

VTK_MODULE_INIT(vtkRenderingOpenGL2); // VTK was built with vtkRenderingOpenGL2
VTK_MODULE_INIT(vtkInteractionStyle);
int main()
{
    vtkSmartPointer<vtkMetaImageReader> reader = vtkSmartPointer<vtkMetaImageReader>::New();
  //mhd与mha文件其实格式是一样的,记录mhd对应的raw文件应在同一目录
  //mhd格式图像信息头与实际图像的存储分为两个文件(*.mhd文件记录图像信息头;*.raw或//*.zraw(zraw指有压缩)记录实际图像)
  //mha格式将图像信息头与实际的像素值等数据写入到同一个文件中
  //reader->SetFileName("test1.mhd");
    //.mha和.raw文件需要在同一个文件夹
    reader->SetFileName("脑部切片_3.mha");
    reader->Update();

    vtkSmartPointer<vtkImageViewer2> imgViewer = vtkSmartPointer<vtkImageViewer2>::New();
    vtkSmartPointer<vtkRenderWindowInteractor> renderWindowInteractor = vtkSmartPointer<vtkRenderWindowInteractor>::New();

    imgViewer->SetInputConnection(reader->GetOutputPort());
    imgViewer->SetupInteractor(renderWindowInteractor);
    imgViewer->SetColorLevel(1000);
    imgViewer->SetColorWindow(2000);
    imgViewer->SetSlice(0);//查看切片1  (0表示第一个切片)
    //横断面、矢状面、冠状面
    //SetSliceOrientationToXY()、SetSliceOrientationToXZ()、SetSliceOrientationToYZ()
    imgViewer->SetSliceOrientationToXY();//SetSliceOrientationToXZ();SetSliceOrientationToYZ()
    imgViewer->Render();

    renderWindowInteractor->Start();
    return 0;

}

查看切片1:                            查看切片2:

      

实例5:读取DCM文件并渲染显示

#include "vtkAutoInit.h" 
VTK_MODULE_INIT(vtkRenderingOpenGL2);
VTK_MODULE_INIT(vtkInteractionStyle);

#include <vtkDICOMImageReader.h>//DCM医学文件读取类
#include <vtkImageViewer.h>//显示2D图像类
#include <vtkRenderWindowInteractor.h>//交互器类

int main()
{
	int dim[2];
	//实例化一个对象dcmReader
	vtkDICOMImageReader* dcmReader = vtkDICOMImageReader::New();
	dcmReader->SetFileName("股骨头.dcm");//读单张切片
	//reader->SetDirectoryName("C:\\Users\\Administrator\\Desktop\\VTK2\\hellovtk\\CT_all");//读DCM序列切片

	//实例化一个对象dcmViewer
	vtkImageViewer* dcmViewer = vtkImageViewer::New();
	dcmViewer->SetInputConnection(dcmReader->GetOutputPort());//读取的图像数据输出给显示对象输入
	//dcmViewer->SetColorLevel(400);//设置窗位   
	//dcmViewer->SetColorWindow(800);//设置窗宽  
	dim[0] = dcmViewer->GetColorLevel();//显示窗位1000   
	dim[1] = dcmViewer->GetColorWindow();//显示窗宽2000
	printf("%d   %d", dim[0], dim[1]);

	dcmViewer->Render();//显示图像

	//加入交互机制
	//实例化一个交互器对象interactor
	vtkRenderWindowInteractor* interactor = vtkRenderWindowInteractor::New();
	dcmViewer->SetupInteractor(interactor);
	interactor->Initialize();
	interactor->Start();//使交互器处于等待状态

	/*getchar();*/
	//释放内存
	dcmReader->Delete();
	dcmViewer->Delete();
	interactor->Delete();

	return 0;

}

      

实例6:读取MHD文件并渲染显示

#include <vtkSmartPointer.h>
#include <vtkMetaImageReader.h>
#include <vtkImageViewer2.h>
#include <vtkRenderer.h>
#include <vtkRenderWindow.h>
#include "vtkRenderWindowInteractor.h"
#include "vtkAutoInit.h" 
VTK_MODULE_INIT(vtkRenderingOpenGL2); // VTK was built with vtkRenderingOpenGL2
VTK_MODULE_INIT(vtkInteractionStyle);

int main(int argc, char* argv[])

{
    vtkSmartPointer<vtkMetaImageReader> reader =
        vtkSmartPointer<vtkMetaImageReader>::New();
    reader->SetFileName("FullHead.mhd");//读取MHD文件(注:mhd和源文件raw必须在同一文件夹)
    reader->Update();
    vtkSmartPointer<vtkImageViewer2> viewer =
        vtkSmartPointer<vtkImageViewer2>::New();
    viewer->SetInputConnection(reader->GetOutputPort());
    //设置基本属性
    viewer->SetSize(640, 480);
    viewer->SetColorLevel(500);
    viewer->SetColorWindow(2000);
    viewer->SetSlice(10);  //显示具体切片
    viewer->SetSliceOrientationToXY();
    viewer->Render();
    viewer->GetRenderer()->SetBackground(1, 1, 1);
    viewer->GetRenderWindow()->SetWindowName("ImageViewer2D");
    vtkSmartPointer<vtkRenderWindowInteractor> rwi =
        vtkSmartPointer<vtkRenderWindowInteractor>::New();
    //设置交互属性
    viewer->SetupInteractor(rwi);
    rwi->Start();
    return 0;
}

查看切片10:                            查看切片40:

      

实例7:读取VTK格式文件并另存为OBJ格式

#include "vtkAutoInit.h" 
VTK_MODULE_INIT(vtkRenderingOpenGL2);
VTK_MODULE_INIT(vtkInteractionStyle);

#include <vtkConeSource.h>//源数据
#include <vtkPolyDataReader.h>//vtk格式数据读取
#include <vtkPolyDataMapper.h>//数据映射
#include <vtkRenderer.h>//绘制器
#include <vtkRenderWindow.h>//绘制窗口
#include <vtkActor.h>//演员
#include <vtkCamera.h>//照相机
#include <vtkRenderWindowInteractor.h>//加入交互机制类
#include <vtkOBJExporter.h>//
int main()
{
	//读数据
	vtkSmartPointer<vtkPolyDataReader> reader =
		vtkSmartPointer<vtkPolyDataReader>::New();
	reader->SetFileName("face.vtk");
	reader->Update();

	//实例化一个映射器coneMapper
	vtkPolyDataMapper* coneMapper = vtkPolyDataMapper::New();
	coneMapper->SetInputConnection(reader->GetOutputPort());//源数据输出给映射器输入

	//创建一个演员对象coneActor
	vtkActor* coneActor = vtkActor::New();
	coneActor->SetMapper(coneMapper);//为演员指定mapper进行映射

	//搭建舞台  实例化对象renderer
	vtkRenderer* renderer = vtkRenderer::New();
	renderer->AddActor(coneActor);//将演员加入场景
	renderer->SetBackground(0.1, 0.2, 0.4);//设置场景背景颜色是(R,G,B)

	//实例化一个窗口对象renWin
	vtkRenderWindow* renWin = vtkRenderWindow::New();
	renWin->SetSize(640, 320);//设置窗口大小宽*高
	renWin->AddRenderer(renderer);//将场景renderer加入renWin窗口中

	//实例化一个交互对象
	vtkRenderWindowInteractor* interactor = vtkRenderWindowInteractor::New();//交互对象加入renWin窗口中
	interactor->SetRenderWindow(renWin);

	renWin->Render();//绘制舞台上的东西

	//保存为obj文件
	vtkSmartPointer<vtkOBJExporter> porter = vtkSmartPointer<vtkOBJExporter>::New();
	porter->SetFilePrefix("face");
	porter->SetInput(renWin);
	porter->Write();

	interactor->Initialize();//交互对象初始化
	interactor->Start();//开始交互事件

	//释放内存
	reader->Delete();
	coneActor->Delete();
	coneMapper->Delete();
	renderer->Delete();
	renWin->Delete();
	interactor->Delete();

	return 0;

}

     

另存生成的face.obj格式文件:

实例8:读取STL格式文件并另存为OBJ格式

#include <vtkAutoInit.h>
VTK_MODULE_INIT(vtkRenderingOpenGL2);
VTK_MODULE_INIT(vtkInteractionStyle);
#include <vtkPolyData.h>
#include <vtkSTLReader.h>
#include <vtkSmartPointer.h>
#include <vtkPolyDataMapper.h>
#include <vtkActor.h>
#include <vtkRenderWindow.h>
#include <vtkRenderer.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkOBJExporter.h>//obj文件类
int main(int argc, char* argv[])
{
    /*if (argc != 2)
    {
        cout << "Required parameters: Filename" << endl;
        return EXIT_FAILURE;
    }*/

    std::string inputFilename = "血管.stl";//tmp.stl

    vtkSmartPointer<vtkSTLReader> reader =
        vtkSmartPointer<vtkSTLReader>::New();
    reader->SetFileName(inputFilename.c_str());
    reader->Update();

    // Visualize
    vtkSmartPointer<vtkPolyDataMapper> mapper =
        vtkSmartPointer<vtkPolyDataMapper>::New();
    mapper->SetInputConnection(reader->GetOutputPort());

    vtkSmartPointer<vtkActor> actor =
        vtkSmartPointer<vtkActor>::New();
    actor->SetMapper(mapper);

    vtkSmartPointer<vtkRenderer> renderer =
        vtkSmartPointer<vtkRenderer>::New();
    vtkSmartPointer<vtkRenderWindow> renderWindow =
        vtkSmartPointer<vtkRenderWindow>::New();
    renderWindow->AddRenderer(renderer);
    vtkSmartPointer<vtkRenderWindowInteractor> renderWindowInteractor =
        vtkSmartPointer<vtkRenderWindowInteractor>::New();
    renderWindowInteractor->SetRenderWindow(renderWindow);

    renderer->AddActor(actor);
    renderer->SetBackground(.3, .6, .3); // Background color green

    //保存为obj文件
    vtkSmartPointer<vtkOBJExporter> porter = vtkSmartPointer<vtkOBJExporter>::New();
    porter->SetFilePrefix("血管");
    porter->SetInput(renderWindow);
    porter->Write();

    renderWindow->Render();
    renderWindowInteractor->Start();

    return EXIT_SUCCESS;
}

       

另存生成的血管.obj文件:

实例9:读取STL格式文件并另存为MHD格式

#include <vtkSmartPointer.h>
#include <vtkPolyData.h>
#include <vtkImageData.h>
#include <vtkSphereSource.h>
#include <vtkMetaImageWriter.h>
#include <vtkPolyDataToImageStencil.h>
#include <vtkImageStencil.h>
#include <vtkPointData.h>
#include <vtkSTLReader.h>
#include <vtkXMLImageDataWriter.h>


int main(int, char* []) {
    vtkNew<vtkPolyData> pd;
    vtkNew<vtkSTLReader> reader;
    reader->SetFileName("femoral.stl");
    reader->Update();
    pd->DeepCopy(reader->GetOutput());
    vtkNew<vtkImageData> whiteImage;
    double bounds[6];
    pd->GetBounds(bounds);
    double spacing[3]; // 所需的MHD文件体积间距
    spacing[0] = 0.5;
    spacing[1] = 0.5;
    spacing[2] = 0.5;
    whiteImage->SetSpacing(spacing);
    // 计算尺寸
    int dim[3];
    for (int i = 0; i < 3; i++) {
        dim[i] = static_cast<int>(ceil((bounds[i * 2 + 1] - bounds[i * 2]) / spacing[i]));
    }
    whiteImage->SetDimensions(dim);
    whiteImage->SetExtent(0, dim[0] - 1, 0, dim[1] - 1, 0, dim[2] - 1);
    double origin[3];
    origin[0] = bounds[0] + spacing[0] / 2;
    origin[1] = bounds[2] + spacing[1] / 2;
    origin[2] = bounds[4] + spacing[2] / 2;
    whiteImage->SetOrigin(origin);
    whiteImage->AllocateScalars(VTK_UNSIGNED_CHAR, 1);
    // 用前景体素填充图像:
    unsigned char inval = 255;
    unsigned char outval = 0;
    vtkIdType count = whiteImage->GetNumberOfPoints();
    for (vtkIdType i = 0; i < count; ++i) {
        whiteImage->GetPointData()->GetScalars()->SetTuple1(i, inval);
    }
    // 多边形数据->图像模具:
    vtkNew<vtkPolyDataToImageStencil> pol2stenc;
    pol2stenc->SetInputData(pd);
    pol2stenc->SetOutputOrigin(origin);
    pol2stenc->SetOutputSpacing(spacing);
    pol2stenc->SetOutputWholeExtent(whiteImage->GetExtent());
    pol2stenc->Update();
    // 剪切相应的白色图像并设置背景:
    vtkNew<vtkImageStencil> imgstenc;
    imgstenc->SetInputData(whiteImage);
    imgstenc->SetStencilConnection(pol2stenc->GetOutputPort());
    imgstenc->ReverseStencilOff();
    imgstenc->SetBackgroundValue(outval);
    imgstenc->Update();
    保存为MHD格式
    vtkNew<vtkMetaImageWriter> writer;
    writer->SetInputData(imgstenc->GetOutput());
    writer->SetFileName("femoral.mhd");
    writer->Write();

    return 0;
}

      

另存为MHD格式的femoral.mhd文件(z轴进行切割):

   

实例10:读取STL格式文件并另存为MHA格式(切片处理)

#include <vtkSmartPointer.h>
#include <vtkPolyData.h>
#include <vtkImageData.h>
#include <vtkSphereSource.h>
#include <vtkMetaImageWriter.h>
#include <vtkPolyDataToImageStencil.h>
#include <vtkImageStencil.h>
#include <vtkPointData.h>
#include <vtkSTLReader.h>

/**
 * This program generates a sphere (closed surface, vtkPolyData) and converts it into volume
 * representation (vtkImageData) where the foreground voxels are 1 and the background voxels are
 * 0. Internally vtkPolyDataToImageStencil is utilized. The resultant image is saved to disk
 * in metaimage file format (SphereVolume.mhd).
 */
int main(int argc, char *argv[]) {
    // Verify input arguments
    /*if(argc != 5) {
        std::cout << "argv0: Input model path \n"
                  << "argv1: Output model path \n"
                  << "argv2: Spacing x,y \n"
                  << "argv3: Spacing z \n"
                  << std::endl;
        return EXIT_FAILURE;
    }*/
    // read data
    vtkSmartPointer<vtkSTLReader> reader =
        vtkSmartPointer<vtkSTLReader>::New();
    reader->SetFileName("artifacts.stl");//读入数据
    reader->Update();
    //实例化vtkPolyData(多边形类型数据)类型对象pd
    vtkSmartPointer<vtkPolyData> pd = reader->GetOutput();
    //实例化vtkImageData类型对象whiteImage
    vtkSmartPointer<vtkImageData> whiteImage =
        vtkSmartPointer<vtkImageData>::New();
    double bounds[6];
    pd->GetBounds(bounds);//获取STL三个方向范围(mm)
    std::cout << "STL模型三个方向的范围分别为(单位mm)" << std::endl;

    std::cout << "X方向的范围为(单位mm):" << std::endl;
    std::cout << "bounds[0]-->bounds[1] :\n"
        << bounds[0] << " " << bounds[1] << " "
        << std::endl;
 
    std::cout << "Y方向的范围为(单位mm):" << std::endl;
    std::cout << "bounds[2]-->bounds[3] :\n"
        << bounds[2] << " " << bounds[3] << " "
        << std::endl;

    std::cout << "Z方向的范围为(单位mm):" << std::endl;
    std::cout << "bounds[4]-->bounds[5] :\n"
        << bounds[4] << " " << bounds[5] << " "
        << std::endl;
    std::cout << "正在切割...." <<
                 "Waiting Please..." << std::endl;
    //期待的体素三个方向的spacing定义
    double spacing[3]; // desired volume spacing
    spacing[0] = atof("5");
    spacing[1] = atof("5");
    spacing[2] = atof("5");
    //设置图像类型对象whiteImage三个方向相邻像素之间的间隔spacing
    whiteImage->SetSpacing(spacing);
    //根据给定的spacing计算采样STL模型三个方向(x,y,z)的维度(即采样三个方向体素个数)
    // compute dimensions
    int dim[3];
    for (int i = 0; i < 3; i++) {
        dim[i] = static_cast<int>(
                     ceil((bounds[i * 2 + 1] - bounds[i * 2]) / spacing[i]));
    }
    //设置图像类型对象whiteImage的三个方向的维度dim
    whiteImage->SetDimensions(dim);
    //设置图像类型对象whiteImage的三个方向的维度的具体范围
    whiteImage->SetExtent(0, dim[0] - 1, 0, dim[1] - 1, 0, dim[2] - 1);
    设置图像类型对象whiteImage的起始点origin
    double origin[3];
    //进行切片处理的第一张位置为STL模型Z轴向上spacing[2] / 2间隔
    origin[0] = bounds[0] + spacing[0] / 2;
    origin[1] = bounds[2] + spacing[1] / 2;
    origin[2] = bounds[4] + spacing[2] / 2;
    whiteImage->SetOrigin(origin);
    whiteImage->AllocateScalars(VTK_UNSIGNED_CHAR, 1);
    // fill the image with foreground voxels:
    //以前景色填充图像
    unsigned char inval = 255;//白色255  前景色
    unsigned char outval = 0;//黑色0   背景色
    //获取whiteImage对象所需要的体素点总数count
    vtkIdType count = whiteImage->GetNumberOfPoints();
    //获取whiteImage对象所需要的体素点总数count
    for (vtkIdType i = 0; i < count; ++i) {
        //将整张图像都以前景色inval填充
        whiteImage->GetPointData()->GetScalars()->SetTuple1(i, inval);
    }
    //STL输出的PolyData类型的pd对象到ImageStencil类型的pol2stenc对象的转换
    // polygonal data --> image stencil:
    //定义PolyData到ImageStencil类型转换对象pol2stenc,其输出为图像切片ImageStencil类型
    vtkSmartPointer<vtkPolyDataToImageStencil> pol2stenc =
        vtkSmartPointer<vtkPolyDataToImageStencil>::New();
    //PolyData类型的pd对象输入
    pol2stenc->SetInputData(pd);
    //设置pol2stenc对象原点
    pol2stenc->SetOutputOrigin(origin);
    //设置pol2stenc对象间隔
    pol2stenc->SetOutputSpacing(spacing);
    //设置pol2stenc对象维度具体范围
    pol2stenc->SetOutputWholeExtent(whiteImage->GetExtent());
    pol2stenc->Update();//开始执行
    // cut the corresponding white image and set the background:
    //定义ImageStencil类型对象imgstenc
    vtkSmartPointer<vtkImageStencil> imgstenc =
        vtkSmartPointer<vtkImageStencil>::New();
    //设置输入数据
    imgstenc->SetInputData(whiteImage);
    imgstenc->SetStencilConnection(pol2stenc->GetOutputPort());
    imgstenc->ReverseStencilOff();
    //设置背景颜色为outval
    imgstenc->SetBackgroundValue(outval);//取反操作,没有数据(即不是STL模型)地方颜色取反(outval),有则不变
    imgstenc->Update();
    vtkSmartPointer<vtkMetaImageWriter> writer =
        vtkSmartPointer<vtkMetaImageWriter>::New();
    writer->SetFileName("artifacts.mha");
    writer->SetInputData(imgstenc->GetOutput());
    writer->Write();
    std::cout << "Finish !!!" << std::endl;
    return EXIT_SUCCESS;
}

    

另存为MHA格式的artifacts.mhd文件(z轴进行切割):

   

实例11:读取STL格式文件并另存为VTI格式(切片处理)

#include <vtkSmartPointer.h>
#include <vtkPolyData.h>
#include <vtkImageData.h>
#include <vtkSphereSource.h>
#include <vtkMetaImageWriter.h>
#include <vtkPolyDataToImageStencil.h>
#include <vtkImageStencil.h>
#include <vtkPointData.h>
#include <vtkSTLReader.h>
//#include <vtkDICOMWriter.h>
#include <vtkXMLImageDataWriter.h>


int main(int, char* []) {
    vtkNew<vtkPolyData> pd;
    vtkNew<vtkSTLReader> reader;
    reader->SetFileName("pelvis.stl");
    reader->Update();
    pd->DeepCopy(reader->GetOutput());
    vtkNew<vtkImageData> whiteImage;
    double bounds[6];
    pd->GetBounds(bounds);
    double spacing[3]; // 所需的体积间距
    spacing[0] = 2;
    spacing[1] = 2;
    spacing[2] = 5;
    whiteImage->SetSpacing(spacing);
    // 计算尺寸
    int dim[3];
    for (int i = 0; i < 3; i++) {
        dim[i] = static_cast<int>(ceil((bounds[i * 2 + 1] - bounds[i * 2]) / spacing[i]));
    }
    whiteImage->SetDimensions(dim);
    whiteImage->SetExtent(0, dim[0] - 1, 0, dim[1] - 1, 0, dim[2] - 1);
    double origin[3];
    origin[0] = bounds[0] + spacing[0] / 2;
    origin[1] = bounds[2] + spacing[1] / 2;
    origin[2] = bounds[4] + spacing[2] / 2;
    whiteImage->SetOrigin(origin);
    whiteImage->AllocateScalars(VTK_UNSIGNED_CHAR, 1);
    // 用前景体素填充图像:
    unsigned char inval = 255;
    unsigned char outval = 0;
    vtkIdType count = whiteImage->GetNumberOfPoints();
    for (vtkIdType i = 0; i < count; ++i) {
        whiteImage->GetPointData()->GetScalars()->SetTuple1(i, inval);
    }
    // 多边形数据->图像模具:
    vtkNew<vtkPolyDataToImageStencil> pol2stenc;
    pol2stenc->SetInputData(pd);
    pol2stenc->SetOutputOrigin(origin);
    pol2stenc->SetOutputSpacing(spacing);
    pol2stenc->SetOutputWholeExtent(whiteImage->GetExtent());
    pol2stenc->Update();
    // 剪切相应的白色图像并设置背景:
    vtkNew<vtkImageStencil> imgstenc;
    imgstenc->SetInputData(whiteImage);
    imgstenc->SetStencilConnection(pol2stenc->GetOutputPort());
    imgstenc->ReverseStencilOff();
    imgstenc->SetBackgroundValue(outval);
    imgstenc->Update();
    vtkNew<vtkXMLImageDataWriter> writer;
    writer->SetInputData(imgstenc->GetOutput());
    writer->SetFileName("pelvis.vti");
    writer->Write();
    return 0;
}

     

另存为VTI格式的pelvis.vti文件(z轴进行切割):

   

 

  • 13
    点赞
  • 59
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

亦我飞也

你的鼓励将是我创作的最大动力!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值