在VTK中,
vtkVolumeRayCastMapper类(在VTK8.x.x已被移除)可用于实现光线投射体数据算法,并生成渲染图元数据传递给vtkVolume对象进行渲染。vtkVolumeRayCastMapper类采用软件方法来实现光线投射算法,精度高但是计算量比较大。其内部两个最重要的函数:

SetVolumeRayCastMapper::SetInput(vtkImageData*) //该函数用于设置输入图像数据。
SetVolumeRayCastMapper::SetVolumeRay(vtkVolumeRayCastFunction*) //该函数用于设置光线投射函数。

vtkVolumeRayCastMapper中计算每条光线在通过体数据后的颜色是通过定义的vtkVolumeRayCastFunction对象实现的。vtkVolumeRayCastFunction是一个虚基类,它有三个子类。
1、vtkVolumeRayCastCompositeFunction该方式通过Alpha合成技术生成每个像素的颜色值。
2、vtkVolumeRayCastMIPFunction最大密度投影函数主要用于对体数据中高灰度值的结构进行可视化。
3、vtkVolumeRayCastIsosurfaceFunction等值面绘制函数能够渲染体数据中特定的等值面。

替代者:
vtkFixedPointVolumeRayCastMapper是一个较好的vtkVolumeRayCastMapper的替代者。该类能够实现基于Alpha合成的体绘制和最大密度投影体绘制方法,能够支持任意类型的一元或独立多元数据。vtkFixedPointVolumeRayCastMapper的使用方法的使用方法与vtkVolumeRayCastMapper基本相同,如支持设置投射光线采样步长、设置图像采样距离、设置自动调节图像采样距离等。

二者的区别:

vtkFixedPointVolumeRayCastFMapper只支持基于Alpha合成的体绘制方法和最大密度体绘制方法,可以通过基类vtkVolumeMapper的接口函数来设置。

void SetBlendModeToComposite();
void SetBlendModeToMaximumIntensity();
void SetBlendModeToMinimumIntensity();
void SetBlendModeToAddictive();

List item

对于Alpha合成体绘制方法,vtkFixedPointVolumeRayCastFMapper类仅支持先插值在分类操作;
vtkFixedPointVolumeRayCastFMapper类支持更多种数据类型。

我们利用vtkFixedPointVolumeRayCastMapper类来显示基于Alpha合成的体绘制方法和最大密度体绘制方法的效果。

#include <vtkSmartPointer.h>
#include <vtkImageData.h>
#include <vtkStructuredPoints.h>
#include <vtkStructuredPointsReader.h>
#include <vtkColorTransferFunction.h>
#include <vtkPiecewiseFunction.h>
#include <vtkRenderer.h>
#include <vtkRenderWindow.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkVolumeProperty.h>
#include <vtkFixedPointVolumeRayCastMapper.h>

int main(int argc, char *argv[])
{
	vtkNew<vtkStructuredPointsReader> reader;
	reader->SetFileName("E:\\TestData\\mummy.128.vtk");
	reader->Update();
	vtkNew<vtkFixedPointVolumeRayCastMapper> volumeMapper0;
	volumeMapper0->SetInputData(reader->GetOutput());
	volumeMapper0->SetBlendModeToComposite();

	vtkNew<vtkFixedPointVolumeRayCastMapper> volumeMapper1;
	volumeMapper1->SetInputData(reader->GetOutput());
	volumeMapper1->SetBlendModeToMaximumIntensity();

	vtkNew<vtkVolumeProperty> volumeProperty;
	volumeProperty->SetInterpolationTypeToLinear();
	volumeProperty->SetAmbient(0.4);
	volumeProperty->SetDiffuse(0.6);
	volumeProperty->SetSpecular(0.2);

	vtkNew<vtkPiecewiseFunction> compositeOpacity;
	compositeOpacity->AddPoint(70,   0.00);
	compositeOpacity->AddPoint(90,   0.40);
	compositeOpacity->AddPoint(180,  0.60);
	volumeProperty->SetScalarOpacity(compositeOpacity); //设置不透明度传输函数

	vtkNew<vtkPiecewiseFunction> volumeGradientOpacity;
	volumeGradientOpacity->AddPoint(10,  0.0);
	volumeGradientOpacity->AddPoint(90,  0.5);
	volumeGradientOpacity->AddPoint(100, 1.0);
	//volumeProperty->SetGradientOpacity(volumeGradientOpacity);//设置梯度不透明度效果对比

	vtkNew<vtkColorTransferFunction> color;
	color->AddRGBPoint(0.000,  0.00, 0.00, 0.00);
	color->AddRGBPoint(64.00,  1.00, 0.52, 0.30);
	color->AddRGBPoint(190.0,  1.00, 1.00, 1.00);
	color->AddRGBPoint(220.0,  0.20, 0.20, 0.20);
	volumeProperty->SetColor(color);

	vtkNew<vtkVolume> volume0;
	volume0->SetMapper(volumeMapper0);
	volume0->SetProperty(volumeProperty);

	vtkNew<vtkVolume> volume1;
	volume1->SetMapper(volumeMapper1);
	volume1->SetProperty(volumeProperty);

	double leftViewport[4] = { 0.0, 0.0, 0.5, 1.0 };
	double rightViewport[4] = { 0.5, 0.0, 1.0, 1.0 };
	vtkNew<vtkRenderer> renderer0;
	renderer0->SetBackground(1.0, 1.0, 1.0);
	renderer0->SetViewport(leftViewport);
	renderer0->AddVolume(volume0);

	vtkNew<vtkRenderer> renderer1;
	renderer1->SetBackground(1.0, 1.0, 1.0);
	renderer1->SetViewport(rightViewport);
	renderer1->AddVolume(volume1);

	vtkNew<vtkRenderWindow> renWin;
	renWin->AddRenderer(renderer0);
	renWin->AddRenderer(renderer1);
	renWin->SetSize(640, 480);
	renWin->SetWindowName("VolumeMapper");

	vtkNew<vtkRenderWindowInteractor> iren;
	iren->SetRenderWindow(renWin);
	renWin->Render();
	iren->Start();

	return EXIT_SUCCESS;
}

效果图:
在这里插入图片描述

这个下面是最大密度投影法的结果:


#include <vtkSmartPointer.h>
#include <vtkImageData.h>
#include <vtkStructuredPoints.h>
#include <vtkStructuredPointsReader.h>
//#include <vtkVolumeRayCastMIPFunction.h>
//#include <vtkVolumeRayCastMapper.h>
#include <vtkFixedPointVolumeRayCastMapper.h>
#include <vtkColorTransferFunction.h>
#include <vtkPiecewiseFunction.h>
#include <vtkRenderer.h>
#include <vtkRenderWindow.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkVolumeProperty.h>
#include <vtkAxesActor.h>
#include <vtkImageShiftScale.h>
#include <vtkImageCast.h>


int main(int argc, char *argv[]) {
    vtkSmartPointer<vtkStructuredPointsReader> reader =
        vtkSmartPointer<vtkStructuredPointsReader>::New();
    reader->SetFileName("../data/ironProt.vtk");//mummy.128.vtk
    reader->Update();

    vtkSmartPointer<vtkFixedPointVolumeRayCastMapper> volumeMapper =
        vtkSmartPointer<vtkFixedPointVolumeRayCastMapper>::New();
    volumeMapper->SetInputData(reader->GetOutput());
    volumeMapper->SetBlendModeToMaximumIntensity();

    vtkSmartPointer<vtkVolumeProperty> volumeProperty =
        vtkSmartPointer<vtkVolumeProperty>::New();
    volumeProperty->SetInterpolationTypeToLinear();
    volumeProperty->ShadeOn();
    volumeProperty->SetAmbient(0.4);
    volumeProperty->SetDiffuse(0.6);
    volumeProperty->SetSpecular(0.2);

    vtkSmartPointer<vtkPiecewiseFunction> compositeOpacity =
        vtkSmartPointer<vtkPiecewiseFunction>::New();
    compositeOpacity->AddPoint(70,   0.00);
    compositeOpacity->AddPoint(90,   0.40);
    compositeOpacity->AddPoint(180,  0.60);
    volumeProperty->SetScalarOpacity(compositeOpacity);

    vtkSmartPointer<vtkColorTransferFunction> color =
        vtkSmartPointer<vtkColorTransferFunction>::New();
    color->AddRGBPoint(0.000,  0.00, 0.00, 0.00);
    color->AddRGBPoint(64.00,  1.00, 0.52, 0.30);
    color->AddRGBPoint(190.0,  1.00, 1.00, 1.00);
    color->AddRGBPoint(220.0,  0.20, 0.20, 0.20);
    volumeProperty->SetColor(color);

    vtkSmartPointer<vtkVolume> volume =
        vtkSmartPointer<vtkVolume>::New();
    volume->SetMapper(volumeMapper);
    volume->SetProperty(volumeProperty);

    vtkSmartPointer<vtkRenderer> ren = vtkSmartPointer<vtkRenderer>::New();
    ren->SetBackground(1.0, 1.0, 1.0);
    ren->AddVolume(volume);

    vtkSmartPointer<vtkRenderWindow> renWin = vtkSmartPointer<vtkRenderWindow>::New();
    renWin->AddRenderer(ren);
    renWin->SetSize(640, 480);
    renWin->Render();
    renWin->SetWindowName("VolRenderingApp");

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

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

    return EXIT_SUCCESS;
}

效果如下:
在这里插入图片描述

如果是DICOM影像则替换一下即可

    std::string str = "/media/xuli/TOSHIBA EXT/CTP-data/CTP-data-dicom/同层";
    vtkSmartPointer<vtkDICOMImageReader> reader = vtkSmartPointer<vtkDICOMImageReader>::New();
    reader->SetDirectoryName(str.c_str());
    reader->Update();
Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐