VTK读取DICOM医学图片进行体绘制的几种方法

时间:2021-05-13 10:06:26

注意的是:VTK中不同的vtkVolumeMapper支持不同的数据类型。比如vtkVolumeRayCastMapper和vtkVolumeTextureMapper2D只能支持单分组VTK_UNSIGNED_CHAR和VTK_UNSIGNED_SHORT类型数据,因此当读入其他类型的图像数据时,需要对数据进行转换,比如采用vtkImageCast或者vtkImageScale:而vtkVolumeTextMapper3D则支持任意数据类型,但是必须是单分组数据或者多元独立数据。vtkFixedPointVolumeRayCastMapper灵活性最高,可以支持所有类型数据,最高四元数据。

使用vtkFixedPointVolumeRayCastMapper类

#include "vtkRenderer.h"  
#include "vtkRenderWindow.h"  
#include "vtkRenderWindowInteractor.h"  
#include "vtkActor.h"  
#include "vtkSmartPointer.h"  
#include "vtkProperty.h"  
#include "vtkCamera.h"  
#include "vtkDICOMImageReader.h"  
#include "vtkImageCast.h"  
#include "vtkPiecewiseFunction.h"  
#include "vtkColorTransferFunction.h"  
#include "vtkVolumeProperty.h"  
#include "vtkVolumeRayCastCompositeFunction.h"  
#include "vtkVolumeRayCastMapper.h"  
#include "vtkVolume.h" 
#include "vtkAutoInit.h"
#include "vtkFixedPointVolumeRayCastMapper.h"

VTK_MODULE_INIT(vtkRenderingOpenGL);
VTK_MODULE_INIT(vtkInteractionStyle);
VTK_MODULE_INIT(vtkRenderingFreeType);
VTK_MODULE_INIT(vtkRenderingVolumeOpenGL);

int main()
{
    std::string str = "F:\\CT3";
    vtkSmartPointer<vtkDICOMImageReader> reader = vtkSmartPointer<vtkDICOMImageReader>::New();
    reader->SetDirectoryName(str.c_str());
    reader->Update();




    vtkSmartPointer<vtkPiecewiseFunction> opacityFun = vtkSmartPointer<vtkPiecewiseFunction>::New();
    opacityFun->AddPoint(120,0.0);
    opacityFun->AddPoint(250,1.0);
    opacityFun->AddPoint(520,1.0);
    opacityFun->AddPoint(650,0.0);


    vtkSmartPointer<vtkColorTransferFunction> TransferFun = vtkSmartPointer<vtkColorTransferFunction>::New();
    TransferFun->AddRGBPoint(120, 255 / 255.0, 98 / 255.0, 98 / 255.0);
    TransferFun->AddRGBPoint(250, 255 / 255.0, 255 / 255.0, 180 / 255.0);
    TransferFun->AddRGBPoint(520, 1.0, 1.0, 1.0);
    TransferFun->AddRGBPoint(650, 1.0, 1.0, 1.0);

    vtkSmartPointer<vtkPiecewiseFunction> grideFun = vtkSmartPointer<vtkPiecewiseFunction>::New();
    grideFun->AddPoint(120, 2.0);
    grideFun->AddPoint(250, 2.0);
    grideFun->AddPoint(520, 0.1);
    grideFun->AddPoint(650, 0.1);

    vtkSmartPointer<vtkVolumeProperty> volumeProperty = vtkSmartPointer<vtkVolumeProperty>::New();
    volumeProperty->SetColor(TransferFun);
    volumeProperty->SetScalarOpacity(opacityFun);
    volumeProperty->SetGradientOpacity(grideFun);
    volumeProperty->ShadeOn();

    volumeProperty->SetAmbient(0.2);
    volumeProperty->SetDiffuse(0.9);
    volumeProperty->SetSpecular(0.2);
    volumeProperty->SetSpecularPower(10);

    vtkSmartPointer<vtkVolumeRayCastCompositeFunction> rayCastFun = vtkSmartPointer<vtkVolumeRayCastCompositeFunction>::New();

    vtkSmartPointer<vtkFixedPointVolumeRayCastMapper> mapper1 = vtkSmartPointer<vtkFixedPointVolumeRayCastMapper>::New();
    mapper1->SetInputConnection(reader->GetOutputPort());
    mapper1->SetAutoAdjustSampleDistances(0);





    vtkSmartPointer<vtkVolume> volume = vtkSmartPointer<vtkVolume>::New();
    volume->SetMapper(mapper1);
    volume->SetProperty(volumeProperty);
    vtkSmartPointer<vtkRenderer> ren = vtkSmartPointer<vtkRenderer>::New();
    ren->AddVolume(volume);
    ren->SetBackground(1.0,1.0,1.0);


    vtkSmartPointer<vtkRenderWindow> renwin = vtkSmartPointer<vtkRenderWindow>::New();
    renwin->AddRenderer(ren);
    renwin->SetSize(740, 480);

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

    iren->Initialize();
    renwin->Render();
    iren->Start();
    return 0;
}

使用tkVolumeRayCastCompositeFunction类

#include "vtkRenderer.h"  
#include "vtkRenderWindow.h"  
#include "vtkRenderWindowInteractor.h"  
#include "vtkActor.h"  
#include "vtkSmartPointer.h"  
#include "vtkProperty.h"  
#include "vtkCamera.h"  
#include "vtkDICOMImageReader.h"  
#include "vtkImageCast.h"  
#include "vtkPiecewiseFunction.h"  
#include "vtkColorTransferFunction.h"  
#include "vtkVolumeProperty.h"  
#include "vtkVolumeRayCastCompositeFunction.h"  
#include "vtkVolumeRayCastMapper.h"  
#include "vtkVolume.h" 
#include "vtkAutoInit.h"

VTK_MODULE_INIT(vtkRenderingOpenGL);
VTK_MODULE_INIT(vtkInteractionStyle);
VTK_MODULE_INIT(vtkRenderingFreeType);
VTK_MODULE_INIT(vtkRenderingVolumeOpenGL);

int main()
{
    std::string str = "F:\\CT3";
    vtkSmartPointer<vtkDICOMImageReader> reader = vtkSmartPointer<vtkDICOMImageReader>::New();
    reader->SetDirectoryName(str.c_str());
    reader->SetDataByteOrderToLittleEndian();// 小端字节序
    reader->Update();

    vtkSmartPointer<vtkImageCast> imageCast = vtkSmartPointer<vtkImageCast>::New();
    imageCast->SetInputConnection(reader->GetOutputPort());
    imageCast->SetOutputScalarTypeToUnsignedShort();
    imageCast->Update();

    vtkSmartPointer<vtkPiecewiseFunction> opacityFun = vtkSmartPointer<vtkPiecewiseFunction>::New();
    opacityFun->AddPoint(120,0.0);
    opacityFun->AddPoint(250,1.0);
    opacityFun->AddPoint(520,1.0);
    opacityFun->AddPoint(650,0.0);


    vtkSmartPointer<vtkColorTransferFunction> TransferFun = vtkSmartPointer<vtkColorTransferFunction>::New();
    TransferFun->AddRGBPoint(120, 255 / 255.0, 98 / 255.0, 98 / 255.0);
    TransferFun->AddRGBPoint(250, 255 / 255.0, 255 / 255.0, 180 / 255.0);
    TransferFun->AddRGBPoint(520, 1.0, 1.0, 1.0);
    TransferFun->AddRGBPoint(650, 1.0, 1.0, 1.0);

    vtkSmartPointer<vtkPiecewiseFunction> grideFun = vtkSmartPointer<vtkPiecewiseFunction>::New();
    grideFun->AddPoint(120, 2.0);
    grideFun->AddPoint(250, 2.0);
    grideFun->AddPoint(520, 0.1);
    grideFun->AddPoint(650, 0.1);

    vtkSmartPointer<vtkVolumeProperty> volumeProperty = vtkSmartPointer<vtkVolumeProperty>::New();
    volumeProperty->SetColor(TransferFun);
    volumeProperty->SetScalarOpacity(opacityFun);
    volumeProperty->SetGradientOpacity(grideFun);
    volumeProperty->ShadeOn();

    volumeProperty->SetAmbient(0.2);
    volumeProperty->SetDiffuse(0.9);
    volumeProperty->SetSpecular(0.2);
    volumeProperty->SetSpecularPower(10);

    vtkSmartPointer<vtkVolumeRayCastCompositeFunction> rayCastFun = vtkSmartPointer<vtkVolumeRayCastCompositeFunction>::New();

    vtkSmartPointer<vtkVolumeRayCastMapper> mapper1 = vtkSmartPointer<vtkVolumeRayCastMapper>::New();
    mapper1->SetVolumeRayCastFunction(rayCastFun);
    mapper1->SetInputConnection(imageCast->GetOutputPort());
    mapper1->SetAutoAdjustSampleDistances(0);





    vtkSmartPointer<vtkVolume> volume = vtkSmartPointer<vtkVolume>::New();
    volume->SetMapper(mapper1);
    volume->SetProperty(volumeProperty);
    vtkSmartPointer<vtkRenderer> ren = vtkSmartPointer<vtkRenderer>::New();
    ren->AddVolume(volume);
    ren->SetBackground(1.0,1.0,1.0);


    vtkSmartPointer<vtkRenderWindow> renwin = vtkSmartPointer<vtkRenderWindow>::New();
    renwin->AddRenderer(ren);
    renwin->SetSize(740, 480);

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

    iren->Initialize();
    renwin->Render();
    iren->Start();
    return 0;
}

使用vtkPiecewiseFunction 设置不透明度和梯度不透明vtkTransferFunctiony设置颜色传输。

VTK读取DICOM医学图片进行体绘制的几种方法

VTK读取DICOM医学图片进行体绘制的几种方法