体绘制-vtkVolumeMapper

在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();
要使用vtk.js实现绘制,可以按照以下步骤: 1. 加载数据:使用`vtkXMLImageDataReader`或`vtkHttpDataSetReader`来读取数据。这些读取器可以从本地文件或远程URL加载数据。 2. 创建渲染器和场景:使用`vtkRenderer`和`vtkRenderWindow`创建渲染器和场景。 3. 创建绘制器:使用`vtkVolume`和`vtkVolumeMapper`创建绘制器。`vtkVolumeMapper`将数据映射到绘制器中,并使用`vtkColorTransferFunction`和`vtkPiecewiseFunction`定义颜色和不透明度。 4. 将绘制器添加到场景中:使用`vtkRenderer`的`AddViewProp`方法将绘制器添加到渲染器中。 5. 渲染场景:使用`vtkRenderWindow`的`Render`方法将场景渲染到屏幕上。 下面是一个使用vtk.js实现绘制的示例代码: ```javascript // 加载数据 const reader = vtkXMLImageDataReader.newInstance(); reader.setUrl('data.vti'); reader.loadData().then(() => { const imageData = reader.getOutputData(0); // 创建渲染器和场景 const renderer = vtkRenderer.newInstance(); const renderWindow = vtkRenderWindow.newInstance(); renderWindow.addRenderer(renderer); // 创建绘制器 const volumeMapper = vtkVolumeMapper.newInstance(); volumeMapper.setInputData(imageData); const volume = vtkVolume.newInstance(); volume.setMapper(volumeMapper); const ctfun = vtkColorTransferFunction.newInstance(); ctfun.addRGBPoint(0, 0.0, 0.0, 0.0); ctfun.addRGBPoint(255, 1.0, 1.0, 1.0); const ofun = vtkPiecewiseFunction.newInstance(); ofun.addPoint(0, 0.0); ofun.addPoint(255, 1.0); volume.getProperty().setRGBTransferFunction(0, ctfun); volume.getProperty().setScalarOpacity(0, ofun); // 将绘制器添加到场景中 renderer.addVolume(volume); // 渲染场景 renderWindow.render(); }); ```
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值