当前位置: 首页 > news >正文

QT传输函数控件设计2 体渲染和VTK

程序我就先直接放这里:

#include<vtkAutoInit.h>
VTK_MODULE_INIT(vtkRenderingOpenGL2)
VTK_MODULE_INIT(vtkInteractionStyle);
VTK_MODULE_INIT(vtkRenderingFreeType);
VTK_MODULE_INIT(vtkRenderingVolumeOpenGL2);
#include <vtkImageData.h>
#include <vtkDICOMImageReader.h>
#include <vtkRenderWindow.h>
#include <vtkRenderer.h>
#include <vtkInteractorStyleTrackballCamera.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkVolumeProperty.h>
#include <vtkPiecewiseFunction.h>
#include <vtkColorTransferFunction.h>
#include <vtkGPUVolumeRayCastMapper.h>
#include <vtkPointData.h>
#include <vtkCamera.h>
#include <vtkNew.h>
#include <vtkFloatArray.h>

#include <string>

int main(int argc, char *argv[])
{

	vtkSmartPointer<vtkImageData> imageData = vtkSmartPointer<vtkImageData>::New();
	vtkSmartPointer<vtkDICOMImageReader> reader = vtkSmartPointer<vtkDICOMImageReader>::New();
	vtkSmartPointer<vtkRenderWindow> renderWindow = vtkSmartPointer<vtkRenderWindow>::New();
	vtkSmartPointer<vtkRenderer> renderer = vtkSmartPointer<vtkRenderer>::New();
	vtkSmartPointer<vtkInteractorStyleTrackballCamera> style = vtkSmartPointer<vtkInteractorStyleTrackballCamera>::New();
	vtkSmartPointer<vtkRenderWindowInteractor> interactor = vtkSmartPointer<vtkRenderWindowInteractor>::New();
	vtkSmartPointer<vtkVolumeProperty> volumeProperty = vtkSmartPointer<vtkVolumeProperty>::New();

	vtkSmartPointer<vtkPiecewiseFunction> gradientTF = vtkSmartPointer<vtkPiecewiseFunction>::New();
	vtkSmartPointer<vtkPiecewiseFunction> scalarTF = vtkSmartPointer<vtkPiecewiseFunction>::New();
	vtkSmartPointer<vtkColorTransferFunction> colorTF = vtkSmartPointer<vtkColorTransferFunction>::New();

	vtkSmartPointer<vtkGPUVolumeRayCastMapper> mapper = vtkSmartPointer<vtkGPUVolumeRayCastMapper>::New();
	vtkSmartPointer<vtkVolume> volume = vtkSmartPointer<vtkVolume>::New();

	std::string strFolder = "data"; //put your directory path here

	// read the dicom dir
	reader->SetDirectoryName(strFolder.c_str());
	reader->Update();
	imageData->ShallowCopy(reader->GetOutput());

	// properties options
	
	volumeProperty->ShadeOn();
	volumeProperty->SetInterpolationType(VTK_LINEAR_INTERPOLATION);

	// get the real range in hounsfield 
	vtkDataArray* arr = reader->GetOutput()->GetPointData()->GetScalars();
	double range[2];
	arr->GetRange(range);

	

	// 1D transfer functions
	colorTF->AddRGBPoint(-200, 0.0, 0.0, 0.0);
	colorTF->AddRGBPoint(150, 0.1, 0.1, 0.7);
	colorTF->AddRGBPoint(350, 0.2, 0.2, 0.4);
	colorTF->AddRGBPoint(512, 1.0, 1.0, 1.0);
	colorTF->AddRGBPoint(range[1], 0.9, 0.1, 0.1);

	scalarTF->AddPoint(-200, 0.00);
	scalarTF->AddPoint(150, 0.20);
	scalarTF->AddPoint(350, 0.30);
	scalarTF->AddPoint(512, 0.5);
	scalarTF->AddPoint(range[1], 0.4);

	gradientTF->AddPoint(-200, 0.0);
	gradientTF->AddPoint(150, 0.1);
	gradientTF->AddPoint(350, 0.1);
	gradientTF->AddPoint(512, 0.6);
	gradientTF->AddPoint(range[1] / 4.0, 1.0);

	volumeProperty->SetScalarOpacity(scalarTF);
	volumeProperty->SetGradientOpacity(gradientTF);
	volumeProperty->SetColor(colorTF);

	// setup rendering context
	renderWindow->SetSize(512, 512);
	renderWindow->SetMultiSamples(0);

	// mapping data
	mapper->SetInputConnection(reader->GetOutputPort());
	mapper->SetBlendModeToComposite();
	mapper->SetUseJittering(1);

	// renderer and volume
	renderWindow->AddRenderer(renderer);
	renderer->SetBackground(0.03, 0.33, 0.33);

	volume->SetMapper(mapper);
	volume->SetProperty(volumeProperty);
	renderer->AddVolume(volume);

	renderer->ResetCamera();
	renderer->GetActiveCamera()->Zoom(1.3);

	interactor->SetRenderWindow(renderWindow);

	interactor->SetInteractorStyle(style);

	renderWindow->Render();
	interactor->Start();

	return EXIT_SUCCESS;

}


显示效果如下:(注意首先你需要有一组CT影像组,需要各位去网上找,这里提供一组,因为百度网盘实在慢,本人又穷充不起会员,等这60多M的数据传完我再把链接附上来。如果我忘了记得在底下评论我能看到)

怎么装VTK大家自己百度,VTK里面的各种库的编译方法以及配置这里就不涉及了,CSDN博客有一大堆。

我们不需要都清楚细节,只需要知道这么几点

1. std::string strFolder = "data";  这个函数是用来记录存放医学影像文件组的文件夹的。

2. 这段程序

// 1D transfer functions
	colorTF->AddRGBPoint(-200, 0.0, 0.0, 0.0);
	colorTF->AddRGBPoint(150, 0.1, 0.1, 0.7);
	colorTF->AddRGBPoint(350, 0.2, 0.2, 0.4);
	colorTF->AddRGBPoint(512, 1.0, 1.0, 1.0);
	colorTF->AddRGBPoint(range[1], 0.9, 0.1, 0.1);

	scalarTF->AddPoint(-200, 0.00);
	scalarTF->AddPoint(150, 0.20);
	scalarTF->AddPoint(350, 0.30);
	scalarTF->AddPoint(512, 0.5);
	scalarTF->AddPoint(range[1], 0.4);

	gradientTF->AddPoint(-200, 0.0);
	gradientTF->AddPoint(150, 0.1);
	gradientTF->AddPoint(350, 0.1);
	gradientTF->AddPoint(512, 0.6);
	gradientTF->AddPoint(range[1] / 4.0, 1.0);

这些函数是用来设置传输函数的,大家可以看到其实就是一堆断点,相当于之前我们设计的xml解析程序里面的各个Node。

大家注意到我们在这里故意设置每组传输函数(例如 colorTF 和 scalarTF 和 gradientTF)它们对应的第一个参数值都是相同的,所以我们可以用一个Node来同时记录这些数据,第一个参数是表示Intensity,程序里(还记得吗)我们设置的是NormalizedIntensity,即单位化的Intensity。

3. 把设置的断点加进来

	volumeProperty->SetScalarOpacity(scalarTF);
	volumeProperty->SetGradientOpacity(gradientTF);
	volumeProperty->SetColor(colorTF);

这三句话是把属性设置到我们的渲染框架里

4.

后面关于interactor之类的函数是来设置交互方式的,这我们暂时先不用管,注意你们要配置的VTK库一定是要在CMAKE中选择支持QT,然后相关配置查其他博客就好了。弄好以后,会生成QVTKWidget,作为VTK渲染数据的显示区。

我们到时候要在窗口里放置一个QVTKWidget,然后直接用VTK自己带的交互功能就好了(旋转三维物体等)。

关于传输函数如果不会的话就看这篇博客:

VTK修炼之道 不透明度传输函数

其实以前我都是直接在GPU上做渲染引擎的,现在为了方便实现就不把那一大套东西都给搬过来了,直接用VTK实现,这样大家可以比较轻松地入手。下一节我们就开始设计界面了。

相关文章:

  • QT传输函数控件设计3 QVTKWidget和QT图形界面的融合
  • QT传输函数控件设计4 接着进行融合
  • QT传输函数控件设计5 显示体渲染效果
  • QT传输函数控件设计6 设计Dock窗体结构
  • QT传输函数控件设计7 边界和布局规划
  • QT传输函数控件设计8 设计小圆点
  • QT传输函数控件设计9 初步设计视口类
  • QT传输函数控件设计10 包含小圆点的图形项
  • QT传输函数控件设计11 包含小圆点的图形项2
  • QT传输函数控件设计12 自定义信号和槽
  • QT传输函数控件设计13 大结局
  • QT三维图形1
  • QT三维图形2
  • QT三维图形3
  • QT三维图形4
  • 10个确保微服务与容器安全的最佳实践
  • Druid 在有赞的实践
  • EOS是什么
  • Git学习与使用心得(1)—— 初始化
  • golang中接口赋值与方法集
  • Invalidate和postInvalidate的区别
  • JAVA 学习IO流
  • JavaScript DOM 10 - 滚动
  • js如何打印object对象
  • nodejs实现webservice问题总结
  • PHP 7 修改了什么呢 -- 2
  • React as a UI Runtime(五、列表)
  • VuePress 静态网站生成
  • WebSocket使用
  • Yeoman_Bower_Grunt
  • 大型网站性能监测、分析与优化常见问题QA
  • 简单数学运算程序(不定期更新)
  • 简单易用的leetcode开发测试工具(npm)
  • 解决jsp引用其他项目时出现的 cannot be resolved to a type错误
  • 力扣(LeetCode)56
  • 一道面试题引发的“血案”
  • 如何正确理解,内页权重高于首页?
  • 说说我为什么看好Spring Cloud Alibaba
  • 新海诚画集[秒速5センチメートル:樱花抄·春]
  • #每日一题合集#牛客JZ23-JZ33
  • $().each和$.each的区别
  • (14)学习笔记:动手深度学习(Pytorch神经网络基础)
  • (2)STM32单片机上位机
  • (2.2w字)前端单元测试之Jest详解篇
  • (ZT)出版业改革:该死的死,该生的生
  • (差分)胡桃爱原石
  • (未解决)jmeter报错之“请在微信客户端打开链接”
  • (一)使用IDEA创建Maven项目和Maven使用入门(配图详解)
  • (原创)boost.property_tree解析xml的帮助类以及中文解析问题的解决
  • (转)如何上传第三方jar包至Maven私服让maven项目可以使用第三方jar包
  • **python多态
  • .NET 5种线程安全集合
  • .NET Core WebAPI中使用Log4net 日志级别分类并记录到数据库
  • .NET 材料检测系统崩溃分析
  • .net 后台导出excel ,word