【VTK】关于VTK图像的系列功能

news2024/9/23 17:22:19

很高兴在雪易的CSDN遇见你 ,给你糖糖

欢迎大家加入雪易社区-CSDN社区云 


前言

        本文总结VTK中图像的系列功能,包括图像的导入(读取)、显示、交互和导出(保存)等。详细讲解VTK中提供的各种解决思路,各位小伙伴按需领取!

感谢各位小伙伴的点赞+关注,小易会继续努力分享,一起进步!

你的点赞就是我的动力(^U^)ノ~YO

目录

前言

1. 图像的导入(读取)

2.vtkImageData解析

3.图像的可视化(图像的显示)

      窗宽窗位

     vtkImageViewer2   

      vtkImageActor

     vtkImagePlaneWidget  

4. 切片图像数据的提取 

结论


        如果用一句话来介绍VTK的话,那就是图像和图形库。VTK包含了对图像的各种处理,我们今天来详细梳理一遍。

1. 图像的导入(读取)

        source路径: ...VTK-9.*.*\IO\Image

        常见的二维图像有PNG、JPG、BMP等,VTK为这类图像的导入提供了接口如

        VTK: vtkPNGReader Class Reference、

        VTK: vtkJPEGReader Class Reference

        VTK: vtkBMPReader Class Reference

        上述导入的图像数据的维度为(X,Y,1),可直接赋予vtkImageActor对象进行显示。

        * 提示:若图像的维度为(X,1,Z)直接赋予vtkImageActor时,Actor为一条线,无法显示出理想的图像数据。 

        VTK常见的应用领域为医学,在医学图像如CT图像、mha、mhd图像等的导入,vtk也提供了相应的接口,如VTK: vtkMetaImageReader Class Reference、VTK: vtkDICOMImageReader Class Reference

示例:可视化CT图像

        读取CT图像数据后,可以使用VTK提供的各种可视化工具对图像进行可视化处理。例如,可以使用vtkImageMapper3D将图像数据映射成3D模型。以下是示例代码:

#include <vtkSmartPointer.h>
#include <vtkRenderWindow.h>
#include <vtkRenderer.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkImageMapper3D.h>
#include <vtkImageData.h>

int main(int argc, char* argv[])
{
    // 读取图像数据
    vtkSmartPointer<vtkDICOMImageReader> reader = vtkSmartPointer<vtkDICOMImageReader>::New();  
    reader->SetDirectoryName("path/to/dicom/files");  // 设置DICOM文件路径
    reader->Update();  // 读取DICOM文件
    vtkSmartPointer<vtkImageData> imageData = reader->GetOutput();  // 获取图像数据

    // 创建渲染器和可视化窗口
    vtkSmartPointer<vtkRenderer> renderer = vtkSmartPointer<vtkRenderer>::New();
    vtkSmartPointer<vtkRenderWindow> renderWindow = vtkSmartPointer<vtkRenderWindow>::New();
    renderWindow->AddRenderer(renderer);
    renderWindow->SetSize(800, 800);

    // 将图像数据映射成3D模型,并添加到渲染器中
    vtkSmartPointer<vtkImageMapper3D> imageMapper = vtkSmartPointer<vtkImageMapper3D>::New();
    imageMapper->SetInputData(imageData);
    vtkSmartPointer<vtkActor> imageActor = vtkSmartPointer<vtkActor>::New();
    imageActor->SetMapper(imageMapper);
    renderer->AddActor(imageActor);

    // 启动可视化窗口
    vtkSmartPointer<vtkRenderWindowInteractor> interactor = vtkSmartPointer<vtkRenderWindowInteractor>::New();
    interactor->SetRenderWindow(renderWindow);
    renderWindow->Render();
    interactor->Start();

    return 0;
}

以上是基于VTK读取CT图像的基础代码示例,可以根据实际需要进行修改和扩展。

2.vtkImageData解析

        VTK图像数据结构由两部分组成:图像头信息和数据。图像头信息定义了图像的基本信息,主要包括起点位置(Origin)、像素间隔(Spacing)和维数(Dimension),通过这三个参数即可确定图像空间位置和大小。

        图像数据即为图像像素的像素值,一般采用一维数组来表示和存储。已知像素索引和图像维数的情况下,即可计算每个像素对应的像素值。一般来讲灰度图像的像素范围为0~255,可以采用一个unsigned char类型表示。医学图像数据的灰度范围为0~65536,数据类型为unsigned short

        VTK中提供了多个创建图像的Source类,位置在 VTK-9.*.*\Imaging\Sources,可以利用此类快速创建图像。

示例:创建VTK图像

#include <vtkSmartPointer.h>
#include <vtkImageData.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkRenderer.h>
#include <vtkImageActor.h>
#include <vtkInteractorStyleImage.h>
#include <vtkRenderWindow.h>

int main()
{
	vtkSmartPointer<vtkImageData> img =  vtkSmartPointer<vtkImageData>::New();
	img->SetDimensions(16,16,1);
	img->SetScalarTypeToUnsignedChar();
	img->SetNumberOfScalarComponents(1);
	img->AllocateScalars();

	unsigned char *ptr = (unsigned char*)img->GetScalarPointer();
	for(int i=0; i<16*16*1; i++)
	{
		*ptr ++ =i%256; 
	}

	vtkSmartPointer<vtkImageActor> redActor =
		vtkSmartPointer<vtkImageActor>::New();
	redActor->SetInput(img);

	double redViewport[4] = {0.0, 0.0, 1.0, 1.0};

	vtkSmartPointer<vtkRenderer> redRenderer =
		vtkSmartPointer<vtkRenderer>::New();
	redRenderer->SetViewport(redViewport);
	redRenderer->AddActor(redActor);
	redRenderer->ResetCamera();
	redRenderer->SetBackground(1.0, 1.0, 1.0);

	vtkSmartPointer<vtkRenderWindow> renderWindow =
		vtkSmartPointer<vtkRenderWindow>::New();
	renderWindow->AddRenderer(redRenderer);
	renderWindow->SetSize( 640, 480 );
	renderWindow->Render();
	renderWindow->SetWindowName("CreateVTKImageData");

	vtkSmartPointer<vtkRenderWindowInteractor> renderWindowInteractor =
		vtkSmartPointer<vtkRenderWindowInteractor>::New();
	vtkSmartPointer<vtkInteractorStyleImage> style =
		vtkSmartPointer<vtkInteractorStyleImage>::New();
	renderWindowInteractor->SetInteractorStyle(style);

	renderWindowInteractor->SetRenderWindow(renderWindow);
	renderWindowInteractor->Initialize();
	renderWindowInteractor->Start();

	return EXIT_SUCCESS;
}

3.图像的可视化(图像的显示)

      窗宽窗位

        窗宽为图像显示的灰度范围,窗位是窗宽的中心位置。窗宽只是确定了CT图像灰度范围上可视部分范围,还需要窗位来确定可视灰度范围的具体位置。比如,窗宽为200,窗位为100时,可视范围为0~200;当窗位为500时,可视范围为400~600。

     vtkImageViewer2   

        目前的VTK版本中使用vtkImageViewer2来进行图像显示。vtkImageViewer2封装了图像显示的可视化渲染引擎,包括vtkActor、vtkRenderer 、vtkRenderWindow、vtkInteractorStyleImage等对象,方便地完成图像显示和交互。包括图像缩放、窗宽窗位调整、切片切换等。

#include <vtkSmartPointer.h>
#include <vtkImageViewer2.h>
#include <vtkRenderWindow.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkRenderer.h>
#include <vtkMetaImageReader.h>

//测试图像:../data/brain.mhd
int main(int argc, char* argv[])
{
	if (argc < 2)
	{
		std::cout<<argv[0]<<" "<<"ImageFile(*.mhd)"<<std::endl;
		return EXIT_FAILURE;
	}
	vtkSmartPointer<vtkMetaImageReader> reader =
		vtkSmartPointer<vtkMetaImageReader>::New();
	reader->SetFileName(argv[1]);
	reader->Update();

	vtkSmartPointer<vtkImageViewer2> imageViewer =
		vtkSmartPointer<vtkImageViewer2>::New();
	imageViewer->SetInputConnection(reader->GetOutputPort());

	vtkSmartPointer<vtkRenderWindowInteractor> renderWindowInteractor =
		vtkSmartPointer<vtkRenderWindowInteractor>::New();
	imageViewer->SetupInteractor(renderWindowInteractor);

	imageViewer->SetColorLevel(500);
	imageViewer->SetColorWindow(2000);
	imageViewer->SetSlice(40);
	imageViewer->SetSliceOrientationToXY();
	imageViewer->Render();

	imageViewer->GetRenderer()->SetBackground(1.0, 1.0, 1.0);
	imageViewer->SetSize(640, 480);
	imageViewer->GetRenderWindow()->SetWindowName("DisplayImageExample");

	renderWindowInteractor->Start();

	return EXIT_SUCCESS;
}

      vtkImageActor

        vtkImageActor是一个三维图像渲染Actor,通过纹理映射将图像映射到一个多边形上进行显示。使用vtkImageActor需要建立完整的渲染管线包括vtkImageActor、vtkRenderer 、vtkRenderWindow、vtkInteractorStyleImage。

示例

#include <vtkSmartPointer.h>
#include <vtkRenderWindow.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkInteractorStyleImage.h>
#include <vtkRenderer.h>
#include <vtkBMPReader.h>
#include <vtkImageActor.h>

//测试图像:../data/lena.bmp
int main(int argc, char* argv[])
{
	if (argc < 2)
	{
		std::cout<<argv[0]<<" "<<"ImageFile(*.bmp)"<<std::endl;
		return EXIT_FAILURE;
	}
	vtkSmartPointer<vtkBMPReader> reader =
		vtkSmartPointer<vtkBMPReader>::New();
	reader->SetFileName ( argv[1] );
	reader->Update();

	vtkSmartPointer<vtkImageActor> imgActor =
		vtkSmartPointer<vtkImageActor>::New();
	imgActor->SetInput(reader->GetOutput());

	vtkSmartPointer<vtkRenderer> renderer =
		vtkSmartPointer<vtkRenderer>::New();
	renderer->AddActor(imgActor);
	renderer->SetBackground(1.0, 1.0, 1.0);

	vtkSmartPointer<vtkRenderWindow> renderWindow =
		vtkSmartPointer<vtkRenderWindow>::New();
	renderWindow->AddRenderer(renderer);
	renderWindow->SetSize( 640, 480 );
	renderWindow->Render();
	renderWindow->SetWindowName("DisplayImageExample2");

	vtkSmartPointer<vtkRenderWindowInteractor> renderWindowInteractor =
		vtkSmartPointer<vtkRenderWindowInteractor>::New();
	vtkSmartPointer<vtkInteractorStyleImage> style =
		vtkSmartPointer<vtkInteractorStyleImage>::New();

	renderWindowInteractor->SetInteractorStyle(style);
	renderWindowInteractor->SetRenderWindow(renderWindow);
	renderWindowInteractor->Initialize();

	renderWindowInteractor->Start();

	return EXIT_SUCCESS;
}

注意: 若图像的维度为(X,1,Z)直接赋予vtkImageActor时,Actor为一条线,无法显示出理想的图像数据。 

注意2:vtkImageActor接收的像素数据类型必须为unsigned char,如果类型不符合要求,需要提前转换为unsigned char类型图像。

     vtkImagePlaneWidget  

        vtkImagePlaneWidget采用vtkImageReslice将切片数据取出,并通过纹理映射将切片图像数据映射到对应的Plane上,从而显示图像。

4. 切片图像数据的提取 

        vtk中vtkImageReslice类可以实现图像切片的提取。

示例

#include <vtkSmartPointer.h>
#include <vtkMatrix4x4.h>
#include <vtkImageReslice.h>
#include <vtkImageActor.h>
#include <vtkRenderer.h>
#include <vtkRenderWindow.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkInteractorStyleImage.h>
#include <vtkImageData.h>
#include <vtkMetaImageReader.h>
#include <vtkImageCast.h>
#include <vtkLookupTable.h>
#include <vtkImageMapToColors.h>

//测试图像:..\\data\\brain.mhd
int main(int argc, char* argv[])
{
	if (argc < 2)
	{
		std::cout<<argv[0]<<" "<<"ImageFile(*.mhd)"<<std::endl;
		return EXIT_FAILURE;
	}
	vtkSmartPointer<vtkMetaImageReader> reader =
		vtkSmartPointer<vtkMetaImageReader>::New();
	reader->SetFileName(argv[1]);
	reader->Update();

	int extent[6];
	double spacing[3];
	double origin[3];

	reader->GetOutput()->GetExtent(extent);
	reader->GetOutput()->GetSpacing(spacing);
	reader->GetOutput()->GetOrigin(origin);

	double center[3];
	center[0] = origin[0] + spacing[0] * 0.5 * (extent[0] + extent[1]);
	center[1] = origin[1] + spacing[1] * 0.5 * (extent[2] + extent[3]);
	center[2] = origin[2] + spacing[2] * 0.5 * (extent[4] + extent[5]);

	static double axialElements[16] = {
		1, 0, 0, 0,
		0, 1, 0, 0,
		0, 0, 1, 0,
		0, 0, 0, 1 
	};

	vtkSmartPointer<vtkMatrix4x4> resliceAxes =
		vtkSmartPointer<vtkMatrix4x4>::New();
	resliceAxes->DeepCopy(axialElements);
	resliceAxes->SetElement(0, 3, center[0]);
	resliceAxes->SetElement(1, 3, center[1]);
	resliceAxes->SetElement(2, 3, center[2]);

	vtkSmartPointer<vtkImageReslice> reslice =
		vtkSmartPointer<vtkImageReslice>::New();
	reslice->SetInputConnection(reader->GetOutputPort());
	reslice->SetOutputDimensionality(2);
	reslice->SetResliceAxes(resliceAxes);
	reslice->SetInterpolationModeToLinear();

	vtkSmartPointer<vtkLookupTable> colorTable =
		vtkSmartPointer<vtkLookupTable>::New();
	colorTable->SetRange(0, 1000); 
	colorTable->SetValueRange(0.0, 1.0);
	colorTable->SetSaturationRange(0.0, 0.0);
	colorTable->SetRampToLinear();
	colorTable->Build();

	vtkSmartPointer<vtkImageMapToColors> colorMap =
		vtkSmartPointer<vtkImageMapToColors>::New();
	colorMap->SetLookupTable(colorTable);
	colorMap->SetInputConnection(reslice->GetOutputPort());

	vtkSmartPointer<vtkImageActor> imgActor =
		vtkSmartPointer<vtkImageActor>::New();
	imgActor->SetInput(colorMap->GetOutput());

	vtkSmartPointer<vtkRenderer> renderer =
		vtkSmartPointer<vtkRenderer>::New();
	renderer->AddActor(imgActor);
	renderer->SetBackground(1.0, 1.0, 1.0);

	vtkSmartPointer<vtkRenderWindow> renderWindow =
		vtkSmartPointer<vtkRenderWindow>::New();
	renderWindow->AddRenderer(renderer);
	renderWindow->Render();
	renderWindow->SetSize(640, 480);
	renderWindow->SetWindowName("ImageResliceExample");

	vtkSmartPointer<vtkRenderWindowInteractor> renderWindowInteractor =
		vtkSmartPointer<vtkRenderWindowInteractor>::New();
	vtkSmartPointer<vtkInteractorStyleImage> imagestyle =
		vtkSmartPointer<vtkInteractorStyleImage>::New();

	renderWindowInteractor->SetInteractorStyle(imagestyle);
	renderWindowInteractor->SetRenderWindow(renderWindow);
	renderWindowInteractor->Initialize();
	renderWindowInteractor->Start();

	return EXIT_SUCCESS;
}

结论:

        本文主要介绍了VTK中Image图像数据的使用方法以及一些心得体会,希望对各位小伙伴有所帮助。

感谢各位小伙伴的点赞+关注,小易会继续努力分享,一起进步!

你的赞赏是我的最最最最大的动力(^U^)ノ~YO

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1143709.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

DreamTexture.js - 基于稳定扩散的3D模型自动纹理化开发包

DreamTexture.js 是面向 three.js 开发者的 3D 模型纹理自动生成与设置开发包&#xff0c;可以为 webGL 应用增加 3D 模型的快速自动纹理化能力&#xff0c;官方下载地址&#xff1a;DreamTexture.js自动纹理化开发包 。 图一为原始模型, 图二图三为贴图后的模型。提示词&#…

PN8370 超低待机功耗准谐振原边反馈交直流转换器 适用于5V 2A的充电器芯片

PN8370集成超低待机功耗准谐振原边控制器及650V高雪崩能力智能功率MOSFET&#xff0c;用于高性能、外围元器件精简的充电器、适配器和内置电源。 PN8370为原边反馈工作模式,可省略光耦和TL431。内置高压启动电路,可实现芯片空载损耗(230VAC)小于30mW。在恒压模式&#xff0c;采…

FindDiff_Qt找不同项目

文章目录 项目简介源代码widget.hwidget.cppwidget.ui配置文件找不同.json 项目简介 开发平台 win10Qt6.6msvc2022 简介 微信上有一些好玩的游戏, 找不同一种比较轻松有趣的游戏,也曾经在街机上被坑过N币, 玩了几次后,发现还是太难了,于是开始截屏放大,慢慢找,再然后就发展到截…

2023软件测试高频面试题

前言 今天&#xff0c;我们来整理与解析一些比较高频的测试行业面试题&#xff0c;大家可以通过面试题内的一些解析&#xff0c;再结合自己的真实工作经验来进行答题思路的提取、整理。 友情提示&#xff1a;硬背答案虽可&#xff0c;但容易翻车哦。 同时&#xff0c;我也准备…

【蓝桥杯选拔赛真题04】C++计算24数字游戏 青少年组蓝桥杯C++选拔赛真题 STEMA比赛真题解析

目录 C/C++计算24数字游戏 一、题目要求 1、编程实现 2、输入输出 二、算法分析

7、电路综合-基于简化实频的SRFT微带线巴特沃兹低通滤波器设计

7、电路综合-基于简化实频的SRFT微带线巴特沃兹低通滤波器设计 5、电路综合-超酷-基于S11参数直接综合出微带线电路图中已经介绍了如何从传输函数或S参数综合出电路图。 24、基于原型的切比雪夫低通滤波器设计理论&#xff08;插入损耗法&#xff09;中介绍了使用集总参数元件…

基于SSM的航班订票管理系统的设计与实现

末尾获取源码 开发语言&#xff1a;Java Java开发工具&#xff1a;JDK1.8 后端框架&#xff1a;SSM 前端&#xff1a;采用JSP技术开发 数据库&#xff1a;MySQL5.7和Navicat管理工具结合 服务器&#xff1a;Tomcat8.5 开发软件&#xff1a;IDEA / Eclipse 是否Maven项目&#x…

【Python · PyTorch】线性代数 微积分

本文采用Python及PyTorch版本如下&#xff1a; Python&#xff1a;3.9.0 PyTorch&#xff1a;2.0.1cpu 本文为博主自用知识点提纲&#xff0c;无过于具体介绍&#xff0c;详细内容请参考其他文章。 线性代数 & 微积分 1. 线性代数1.1 基础1.1.1 标量1.1.2 向量长度&…

PyTorch中grid_sample的使用方法

官方文档首先Pytorch中grid_sample函数的接口声明如下&#xff1a; torch.nn.functional.grid_sample(input, grid, modebilinear, padding_modezeros, align_cornersNone)input : 输入tensor&#xff0c; shape为 [N, C, H_in, W_in]grid: 一个field flow&#xff0c; shape为…

PS 安装教程 2022版(全网最详细图文教程)

目录 一.简介 二.安装步骤 软件&#xff1a;PS版本&#xff1a;2022语言&#xff1a;简体中文大小&#xff1a;2.83G安装环境&#xff1a;Win10&#xff08;1903&#xff09;及以上版本&#xff0c;64位操作系统硬件要求&#xff1a;CPU2.0GHz 内存4G(或更高&#xff0c;不支…

【Unity小技巧】如何在 Unity 中使用我们的Cinemachine虚拟相机跟踪多个目标

文章目录 每篇一句前言安装虚拟相机跟随多个目标和间隙占比代码控制添加主角目标代码控制添加敌人目标扩展代码如何实现虚拟相机跟随玩家呢&#xff1f;我们来实现一下修改虚拟相机的视野修改虚拟相机的位置和角度 推荐完结 每篇一句 岂不闻天无绝人之路&#xff0c;只要我想走…

变压器分析

参考方向 如图所示&#xff0c;是变压器的原理图。其中&#xff0c; ϕ \phi ϕ是变压器铁芯的有效磁通&#xff0c; ϕ 1 \phi_1 ϕ1​是主线圈的漏磁通&#xff0c; ϕ 2 \phi_2 ϕ2​是副线圈的漏磁通。图中 u 1 u_1 u1​为初级线圈输入电压&#xff0c; i 1 i_1 i1​为初级…

iOS Autolayout 约束设置【顺序】的重要性!

0x00 顺序不同&#xff0c;结果不同 看图说话 1 代码是这样滴~ 设置好约束&#xff0c;让 4 个按钮&#xff0c;宽度均分~ 结果如上图 [_pastButton.topAnchor constraintEqualToAnchor:_textView.bottomAnchor constant:6].active YES;[_pastButton.leftAnchor constraintEq…

电子学会C/C++编程等级考试2023年05月(四级)真题解析

C/C等级考试&#xff08;1~8级&#xff09;全部真题・点这里 第1题&#xff1a;怪盗基德的滑翔翼 怪盗基德是一个充满传奇色彩的怪盗&#xff0c;专门以珠宝为目标的超级盗窃犯。而他最为突出的地方&#xff0c;就是他每次都能逃脱中村警部的重重围堵&#xff0c;而这也很大程度…

云原生安全:如何保护云上应用不受攻击

文章目录 云原生安全的概念1. 多层次的安全性2. 自动化安全3. 容器安全4. 持续监控5. 合规性 云原生安全的关键挑战1. 无边界的环境2. 动态性3. 多云环境4. 容器化应用程序5. API和微服务 如何保护云上应用不受攻击1. 身份验证和访问控制示例代码&#xff1a; 2. 数据加密示例代…

Python时间序列分析库介绍:statsmodels、tslearn、tssearch、tsfresh

时间序列分析在金融和医疗保健等领域至关重要&#xff0c;在这些领域&#xff0c;理解随时间变化的数据模式至关重要。在本文中&#xff0c;我们将介绍四个主要的Python库——statmodels、tslearn、tssearch和tsfresh——每个库都针对时间序列分析的不同方面进行了定制。这些库…

深入浅出排序算法之计数排序

目录 1. 原理 2. 代码实现 3. 性能分析 1. 原理 首先看一个题目&#xff0c;有n个数&#xff0c;取值范围是 0~n&#xff0c;写出一个排序算法&#xff0c;要求时间复杂度和空间复杂度都是O(n)的。 为了达到这种效果&#xff0c;这一篇将会介绍一种不基于比较的排序方法。这…

Day 11 python学习笔记

模块 内置模块 random random&#xff1a;随机数模块 我们可以在解释器中看到其蕴含的方法 接下来我解释一些常用的方法&#xff1a; random.random( ) random.random( ) 返回0-1的随机数 [0,1) >>> random.random() 0.364183511476754 random.randint(n,m) r…

Java JSON字符串转换成JSON对象

方法一&#xff1a;要先转为LinkedHashMap&#xff0c;再转json&#xff08;推荐&#xff0c;我使用这种方法&#xff09; String jsonStr"{\"id\":\"10001\",\"name\":\"肉类\",\"menus\":[{\"name\":\&qu…

Node切换版本

以非安转版本方式安装Node&#xff0c;经常会需要进行Node的版本切换。 官方的做法是&#xff1a;nvm use version。 但是这种方法经常会失败。如下&#xff1a; 其实nvm命令的本质就是给当前node版本添加一个快捷方式&#xff08;或软连接&#xff09;&#xff0c;因为环境变…