天天看點

基于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;
}
           
基于C++的VTK不同格式檔案讀取與另存整理
基于C++的VTK不同格式檔案讀取與另存整理

執行個體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;
}
           
基于C++的VTK不同格式檔案讀取與另存整理
基于C++的VTK不同格式檔案讀取與另存整理

執行個體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();
}
           
基于C++的VTK不同格式檔案讀取與另存整理
基于C++的VTK不同格式檔案讀取與另存整理

執行個體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:

基于C++的VTK不同格式檔案讀取與另存整理
基于C++的VTK不同格式檔案讀取與另存整理

執行個體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;

}
           
基于C++的VTK不同格式檔案讀取與另存整理
基于C++的VTK不同格式檔案讀取與另存整理

執行個體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:

基于C++的VTK不同格式檔案讀取與另存整理
基于C++的VTK不同格式檔案讀取與另存整理

執行個體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;

}
           
基于C++的VTK不同格式檔案讀取與另存整理
基于C++的VTK不同格式檔案讀取與另存整理

另存生成的face.obj格式檔案:

基于C++的VTK不同格式檔案讀取與另存整理

執行個體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;
}
           
基于C++的VTK不同格式檔案讀取與另存整理
基于C++的VTK不同格式檔案讀取與另存整理

另存生成的血管.obj檔案:

基于C++的VTK不同格式檔案讀取與另存整理

執行個體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;
}

           
基于C++的VTK不同格式檔案讀取與另存整理
基于C++的VTK不同格式檔案讀取與另存整理
基于C++的VTK不同格式檔案讀取與另存整理

另存為MHD格式的femoral.mhd檔案(z軸進行切割):

基于C++的VTK不同格式檔案讀取與另存整理
基于C++的VTK不同格式檔案讀取與另存整理

執行個體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;
}
           
基于C++的VTK不同格式檔案讀取與另存整理
基于C++的VTK不同格式檔案讀取與另存整理
基于C++的VTK不同格式檔案讀取與另存整理

另存為MHA格式的artifacts.mhd檔案(z軸進行切割):

基于C++的VTK不同格式檔案讀取與另存整理
基于C++的VTK不同格式檔案讀取與另存整理

執行個體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;
}

           
基于C++的VTK不同格式檔案讀取與另存整理
基于C++的VTK不同格式檔案讀取與另存整理
基于C++的VTK不同格式檔案讀取與另存整理

另存為VTI格式的pelvis.vti檔案(z軸進行切割):

基于C++的VTK不同格式檔案讀取與另存整理
基于C++的VTK不同格式檔案讀取與另存整理

繼續閱讀