三正交面

此代码来源于《三维图像编程实验》周振环 郑小中 赵明著 ,第三章,三正交面。但是源码没有显示冠状面,失状面,横断面,随怀疑出错,修改后如下,貌似正确。

#include "vtkAutoInit.h"
VTK_MODULE_INIT(vtkRenderingOpenGL2)
VTK_MODULE_INIT(vtkInteractionStyle)
VTK_MODULE_INIT(vtkRenderingContextOpenGL2)
VTK_MODULE_INIT(vtkRenderingFreeType)

#include "vtkRenderer.h"
#include "vtkRenderWindow.h"
#include "vtkRenderWindowInteractor.h"
#include "vtkVolume16Reader.h"
#include "vtkPolyData.h"
#include "vtkPolyDataMapper.h"
#include "vtkActor.h"
#include "vtkOutlineFilter.h"
#include "vtkCamera.h"
#include "vtkStripper.h"
#include "vtkLookupTable.h"
#include "vtkImageDataGeometryFilter.h"
#include "vtkProperty.h"
#include "vtkPolyDataNormals.h"
#include "vtkContourFilter.h"
#include "vtkImageData.h"
#include "vtkImageMapToColors.h"
#include "vtkImageActor.h"

int main()
{
	vtkRenderer* aRenderer = vtkRenderer::New();
	vtkRenderWindow *renWin = vtkRenderWindow::New();
	renWin->AddRenderer(aRenderer);
	vtkRenderWindowInteractor* iren = vtkRenderWindowInteractor::New();
	iren->SetRenderWindow(renWin);

	//读取图像
	vtkVolume16Reader *v16 = vtkVolume16Reader::New();
	v16->SetDataDimensions(64, 64);
	v16->SetDataByteOrderToLittleEndian();
	v16->SetFilePrefix("E:/vtk/VTKData/Data/headsq/quarter");
	v16->SetImageRange(1, 93);
	v16->SetDataSpacing(3.2, 3.2, 1.5);
	v16->Update();

	//抽取皮肤
	vtkContourFilter *skinExtractor = vtkContourFilter::New();
	skinExtractor->SetInputConnection(v16->GetOutputPort());
	skinExtractor->SetValue(0, 500);
	vtkPolyDataNormals *skinNormals = vtkPolyDataNormals::New();
	skinNormals->SetInputConnection(skinExtractor->GetOutputPort());
	skinNormals->SetFeatureAngle(60.0);
	vtkStripper* skinStripper = vtkStripper::New();
	skinStripper->SetInputConnection(skinNormals->GetOutputPort());
	vtkPolyDataMapper* skinMapper = vtkPolyDataMapper::New();
	skinMapper->SetInputConnection(skinStripper->GetOutputPort());
	skinMapper->ScalarVisibilityOff();
	vtkActor* skin = vtkActor::New();
	skin->SetMapper(skinMapper);
	skin->GetProperty()->SetDiffuseColor(1, .49, .25);
	skin->GetProperty()->SetSpecular(.3);
	skin->GetProperty()->SetSpecularPower(20);


	//抽取骨头
	vtkContourFilter* boneExtractor = vtkContourFilter::New();
	boneExtractor->SetInputConnection(v16->GetOutputPort());
	boneExtractor->SetValue(0, 1150);
	vtkPolyDataNormals* boneNormals = vtkPolyDataNormals::New();
	boneNormals->SetInputConnection(boneExtractor->GetOutputPort());
	boneNormals->SetFeatureAngle(60.0);
	vtkStripper *boneStripper = vtkStripper::New();
	boneStripper->SetInputConnection(boneNormals->GetOutputPort());
	vtkPolyDataMapper* boneMapper = vtkPolyDataMapper::New();
	boneMapper->SetInputConnection(boneStripper->GetOutputPort());
	boneMapper->ScalarVisibilityOff();
	vtkActor* bone = vtkActor::New();
	bone->SetMapper(boneMapper);
	bone->GetProperty()->SetDiffuseColor(1, 1, .9412);

	//产生一个外围边框
	vtkOutlineFilter* outlineData = vtkOutlineFilter::New();
	outlineData->SetInputConnection(v16->GetOutputPort());
	vtkPolyDataMapper* mapOutline = vtkPolyDataMapper::New();
	mapOutline->SetInputConnection(outlineData->GetOutputPort());
	vtkActor* outline = vtkActor::New();
	outline->SetMapper(mapOutline);
	outline->GetProperty()->SetColor(0, 0, 0);


	//下面创建三个穿过之前读取的立体的正交面,每个面使用的纹理贴图不同,因而着色不同

	//首先创建一个灰度查询表
	vtkLookupTable * bwLut = vtkLookupTable::New();
	bwLut->SetTableRange(0, 2000);
	bwLut->SetSaturationRange(0, 0);
	bwLut->SetHueRange(0, 0);
	bwLut->SetValueRange(0, 1);
	bwLut->Build();

	//接着创建一个包含所有色调的查询表
	vtkLookupTable* hueLut = vtkLookupTable::New();
	hueLut->SetTableRange(0, 2000);
	hueLut->SetHueRange(0, 1);
	hueLut->SetSaturationRange(1, 1);
	hueLut->SetValueRange(1, 1);
	hueLut->Build();

	//最后创建一个具有点一色调,但饱和度不同的查询表
	vtkLookupTable *satLut = vtkLookupTable::New();
	satLut->SetTableRange(0, 2000);
	satLut->SetHueRange(.6, .6);
	satLut->SetSaturationRange(0, 1);
	satLut->SetValueRange(1, 1);
	satLut->Build();


	//创建第一个平面。过滤器vtkImageMapToColors通过上面创建的查询表对数据进行映射
	//vtkImageActor是vtkProp类型,它使用纹理映射显示图像,结果很快
	//(注意:输入数据的值类型必须是unsigned char,这正好是vtkImageMapToColors产生的值的类型)
	//同时注意置顶显示范围,流水线会请求范围内的数据
	//并且vtkImageMapToColors只处理一个数据切片
	vtkImageMapToColors* saggitalColors = vtkImageMapToColors::New();
	saggitalColors->SetInputConnection(v16->GetOutputPort());
	saggitalColors->SetLookupTable(bwLut);
	vtkImageActor* saggital = vtkImageActor::New();
	saggital->SetInputData(v16->GetOutput());//原书此处代码为saggitalColors->GetOutput(),但没有显示三个切面,遂改为如此,以下两个切面于此相同
	//设置显示的冠状画面
	saggital->SetDisplayExtent(32, 32, 0, 63, 0, 92);


	//创建第二个平面,与之前的操作一样,除了显示范围不同外
	vtkImageMapToColors* axialColors = vtkImageMapToColors::New();
	axialColors->SetInputConnection(v16->GetOutputPort());
	axialColors->SetLookupTable(hueLut);
	vtkImageActor* axial = vtkImageActor::New();
	axial->SetInputData(v16->GetOutput());//原书此处代码为axialColors->GetOutput(),但没有显示三个切面,遂改为如此,以下两个切面于此相同
	//设置显示的横断面
	axial->SetDisplayExtent(0, 63, 0, 63, 46, 46);


	//创建第三个平面,与之前的操作一样,除了显示范围不同外
	vtkImageMapToColors* coronalColors = vtkImageMapToColors::New();
	coronalColors->SetInputConnection(v16->GetOutputPort());
	coronalColors->SetLookupTable(satLut);
	vtkImageActor* coronal = vtkImageActor::New();
	coronal->SetInputData(v16->GetOutput());//原书此处代码为coronalColors->GetOutput(),但没有显示三个切面,遂改为如此,以下两个切面于此相同
	//设置显示的失状面
	coronal->SetDisplayExtent(0, 63, 32, 32, 0, 92);



	vtkCamera *aCamera = vtkCamera::New();
	aCamera->SetViewUp(0, 0, -1);
	aCamera->SetPosition(0, 1, 0);
	aCamera->SetFocalPoint(0, 0, 0);
	aCamera->ComputeViewPlaneNormal();

	aRenderer->AddActor(outline);
	aRenderer->AddActor(saggital);
	aRenderer->AddActor(axial);
	aRenderer->AddActor(coronal);
	aRenderer->AddActor(axial);
	aRenderer->AddActor(coronal);
	aRenderer->AddActor(skin);
	aRenderer->AddActor(bone);
	//关闭骨头的演示
	bone->VisibilityOff();
	//皮肤设为半透明状态,以便观察三界面效果图
	skin->GetProperty()->SetOpacity(0.5);

	aRenderer->SetActiveCamera(aCamera);
	//aRenderer->Render();
	aRenderer->ResetCamera();
	aCamera->Dolly(1.5);
	aRenderer->SetBackground(1, 1, 1);
	renWin->SetSize(640, 480);
	aRenderer->ResetCameraClippingRange();
	iren->Initialize();
	iren->Start();



	return 0;
}

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值