体绘制之vtkVolumeMapper

基本概念

        vtkVolumeMapper是所有体绘制Mapper类虚基类,提供接口函数,并由其子类实现具体的功能。

        光线投射法是最常用的体绘制方法。它是一种基于图像序列的直接体绘制方法,其基本原理是从投影图像平面(通常是平面)的每个像素沿着视线方向发射一条穿过体数据的射线,然后在射线上按照一定的步长进行等距采样,对每个采样点采用插值技术来计算其体素值,根据颜色传输函数和不透明传输函数来获取相应的颜色值和不透明度,最后利用光线吸收模型将颜色值进行累加直至光线穿过体数据,即可得当前平面像素的渲染颜色,生成最终的显示图像。在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合成的体绘制方法和最大密度体绘制方法的效果。

/**********************************************************************

Copyright (c) Mr.Bin. All rights reserved.
For more information visit: http://blog.csdn.net/webzhuce

**********************************************************************/
#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;
}

运行结果

在这里插入图片描述

  • 7
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 13
    评论
评论 13
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值