VTK随笔六:VTK图像处理(图像创建、图像显示)

devtools/2024/9/24 1:35:37/

一、VTK图像创建

1、VTK 图像数据结构

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

        图像数据即为图像像素的像素值,一般采用一维数组来表示和存储。 

2、VTK 图像创建

 1)图像源 Source
        VTK 中内置了多个创建图像的Source类,利用这些Source 类可以快速创建图像。以 vtkImageCanvasSource2D为例。该Source 类的功能是创建一个画布(空白图像),并提供了多种几何图形(点、线段、圆、矩形以及图像等)的绘制填充功能。 

#include <QApplication>
#include <vtkSmartPointer.h>
#include <vtkImageCanvasSource2D.h>
#include <vtkRenderer.h>
#include <vtkImageActor.h>
#include <QVTKOpenGLNativeWidget.h>
#include <vtkGenericOpenGLRenderWindow.h>int main(int argc, char *argv[])
{QApplication a(argc, argv);vtkSmartPointer<vtkImageCanvasSource2D> canvas = vtkSmartPointer<vtkImageCanvasSource2D>::New();canvas->SetScalarTypeToUnsignedChar();canvas->SetNumberOfScalarComponents(1);canvas->SetExtent(0, 100, 0, 100, 0, 0);canvas->SetDrawColor(0, 0, 0, 0);canvas->FillBox(0,100,0,100);canvas->SetDrawColor(255, 0, 0, 0);canvas->FillBox(20,40,20,40);canvas->Update();// Create actorsvtkSmartPointer<vtkImageActor> redActor = vtkSmartPointer<vtkImageActor>::New();redActor->SetInputData(canvas->GetOutput());// Setup renderersvtkSmartPointer<vtkRenderer> redRenderer = vtkSmartPointer<vtkRenderer>::New();redRenderer->AddActor(redActor);redRenderer->ResetCamera();redRenderer->SetBackground(1.0, 1.0, 1.0);// Setup render windowvtkSmartPointer<vtkGenericOpenGLRenderWindow> renderWindow = vtkSmartPointer<vtkGenericOpenGLRenderWindow>::New();renderWindow->AddRenderer(redRenderer);QVTKOpenGLNativeWidget w;w.setWindowTitle("ImageCanvasSource2D");w.setRenderWindow(renderWindow);w.show();return a.exec();
}

 运行效果:

        除了 vkImageCanvasSource2D外,VTK还提供了其他类似的Source 类来快速生成特定的图像,例如 vtkImageEllipsoidSource,该类根据指定的中心以及各个轴的半径来生成一个前景为椭圆(球)的二值图像;vtkImageGaussianSource 类生成一幅像素值服从高斯分布的图像;vtkImageGridSource用于生成网格线图像;vtkImageNoiseSource 生成一个像素值为随机数的噪声图像;vtkImageSinusoidSource生成的图像像素值由正弦函数决定 。

2) 直接创建图像

#include <QApplication>
#include <vtkSmartPointer.h>
#include <vtkImageData.h>
#include <vtkInformation.h>
#include <vtkRenderer.h>
#include <vtkImageActor.h>
#include <QVTKOpenGLNativeWidget.h>
#include <vtkGenericOpenGLRenderWindow.h>int main(int argc, char *argv[])
{QApplication a(argc, argv);vtkSmartPointer<vtkImageData> img =  vtkSmartPointer<vtkImageData>::New();vtkSmartPointer<vtkInformation> info =  vtkSmartPointer<vtkInformation>::New();img->SetDimensions(16,16,1);img->SetScalarType(VTK_UNSIGNED_CHAR,info);img->SetNumberOfScalarComponents(1,info);img->AllocateScalars(info);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->SetInputData(img);vtkSmartPointer<vtkRenderer> redRenderer = vtkSmartPointer<vtkRenderer>::New();redRenderer->AddActor(redActor);redRenderer->ResetCamera();redRenderer->SetBackground(1.0, 1.0, 1.0);vtkSmartPointer<vtkGenericOpenGLRenderWindow> renderWindow = vtkSmartPointer<vtkGenericOpenGLRenderWindow>::New();renderWindow->AddRenderer(redRenderer);QVTKOpenGLNativeWidget w;w.setWindowTitle("CreateVTKImageData");w.setRenderWindow(renderWindow);w.show();return a.exec();
}

        首先定义vtklmageData指针,然后指定图像的维数,而图像的原点和像素间隔则都是采用默认值,因此不需要设置。SetScalarType指定图像的每个像素值的数据类型为unsigned char,SetNumberOfScalarComponents则指定了每个像素值的数据成分为1,每个像素值为1个标量值,参数设置完毕后,调用AllocateScalars()分配内存,生成图像数据。图像生成后,默认所有像素值为0。可以通过访问图像数据数组来设每个像素值GetScalarPointer()即返回图像的数据数组(图像数据数组都采用一维数组),然后根据图像的大小,访问每个像素并为其赋值。生成的图像如下所示:

二、VTK图像显示

 1、vtklmageViewer2

        vtklmageViewer2 中封装了 VTK 图像显示的可视化渲染引擎,包括 vtkActor、vtkRender、vtkRenderWindow、vtkInteractorStypelmage等对象,可以方便地完成图像显示和交互。该类提供的主要交互操作有图像放缩、窗宽窗位调节,并提供切片选择及切片方向设置接口,尤其适合三维图像的切片显示。

#include <QApplication>
#include <vtkSmartPointer.h>
#include <vtkMetaImageReader.h>
#include <vtkImageViewer2.h>
#include <vtkRenderer.h>
#include <QVTKOpenGLNativeWidget.h>int main(int argc, char *argv[])
{QApplication a(argc, argv);vtkSmartPointer<vtkMetaImageReader> reader = vtkSmartPointer<vtkMetaImageReader>::New();reader->SetFileName("D:/data/brain.mhd");reader->Update();vtkSmartPointer<vtkImageViewer2> imageViewer = vtkSmartPointer<vtkImageViewer2>::New();imageViewer->SetInputConnection(reader->GetOutputPort());imageViewer->GetRenderer()->SetBackground(1.0, 1.0, 1.0);QVTKOpenGLNativeWidget w;imageViewer->SetupInteractor(w.interactor()); //初始化交互器imageViewer->SetRenderWindow(w.renderWindow());  //初始化渲染窗口w.setWindowTitle("DisplayImageExample");w.show();imageViewer->SetColorLevel(500); //窗位imageViewer->SetColorWindow(2000); //窗宽imageViewer->SetSlice(40); //切片索引imageViewer->SetSliceOrientationToXY(); //切片方向return a.exec();
}

vtklmageViewer2显示三维图像的某个切片:

 1)窗宽/窗位的概念
        窗宽是图像显示的灰度范围。一般显示器的灰度范围为256级,而医学图像的灰度范围则远远大于该范围,因此通过显示器显示时不能显示所有灰度级,需要使用窗宽来定义欲显示的灰度范围。当灰度值高于该范围的最大值时,均以白影显示;当低于该范围时,均以黑色显示。若增大窗宽,则显示具有不同灰度值的组织结构增多,但是会降低组织之间的对比度,若减小窗宽,则可视的不同灰度组织结构会减少,同时增大组织结构的对比度。

2)医学图像二维视图
        切片(Slice)或切面是三维图像比较常用的概念,尤其在医学图像中,不同方向的切面都有特定的名字,分别是:矢状面(SagitalPlane),沿着身体前后径所做的与地面垂直的切面;冠状面(CoronalPlane),沿着身体左右径所做的与地面垂直的切面;横断面(Transverse/AxialPlane),是指横断身体与地面平行的切面。

 2、vtklmageActor

vtkImageActor 是一个三维图像渲染 Actor,通过纹理映射将图像映射到一个多边形上进行显示。 

#include <QApplication>
#include <vtkSmartPointer.h>
#include <vtkBMPReader.h>
#include <vtkRenderer.h>
#include <vtkImageActor.h>
#include <vtkGenericOpenGLRenderWindow.h>
#include <QVTKOpenGLNativeWidget.h>int main(int argc, char *argv[])
{QApplication a(argc, argv);vtkSmartPointer<vtkBMPReader> reader = vtkSmartPointer<vtkBMPReader>::New();reader->SetFileName ("D:/data/lena.bmp");reader->Update();vtkSmartPointer<vtkImageActor> imgActor =vtkSmartPointer<vtkImageActor>::New();imgActor->SetInputData(reader->GetOutput());vtkSmartPointer<vtkRenderer> renderer =vtkSmartPointer<vtkRenderer>::New();renderer->AddActor(imgActor);renderer->SetBackground(1.0, 1.0, 1.0);vtkSmartPointer<vtkGenericOpenGLRenderWindow> renderWindow = vtkSmartPointer<vtkGenericOpenGLRenderWindow>::New();renderWindow->AddRenderer(renderer);QVTKOpenGLNativeWidget w;w.setRenderWindow(renderWindow);w.setWindowTitle("DisplayImageExample");w.show();return a.exec();
}

运行效果:

        需要注意的是,vtkImageActor 接收的图像数据 vtkImageData像素类型必须为unsigned char,如果类型不符合要求,在显示图像前需要先将图像数据类型转换为unsigned char。 

3、图像融合 

        图像融合是利用图像的不透明度来合成图像。在 VTK 中,用类 vtkImageBlend 实现图像的融合。 vtkmageBlend 可以接收多个图像输入,其输出为融合图像。输出图像的像素间隔、原点、范围以及像素组分个数与第一个图像一致。

#include <QApplication>
#include <vtkSmartPointer.h>
#include <vtkImageData.h>
#include <vtkImageCanvasSource2D.h>
#include <vtkImageBlend.h>
#include <vtkRenderer.h>
#include <vtkJPEGReader.h>
#include <vtkImageActor.h>
#include <vtkGenericOpenGLRenderWindow.h>
#include <QVTKOpenGLNativeWidget.h>int main(int argc, char *argv[])
{QApplication a(argc, argv);vtkSmartPointer<vtkJPEGReader> reader = vtkSmartPointer<vtkJPEGReader>::New();reader->SetFileName ("D:/data/lena-gray.jpg");reader->Update();vtkSmartPointer<vtkImageCanvasSource2D> imageSource = vtkSmartPointer<vtkImageCanvasSource2D>::New();imageSource->SetNumberOfScalarComponents(1);imageSource->SetScalarTypeToUnsignedChar();imageSource->SetExtent(0, 512, 0, 512, 0, 0);imageSource->SetDrawColor(0.0);imageSource->FillBox(0, 512, 0, 512);imageSource->SetDrawColor(255.0);imageSource->FillBox(100,400,100,400);imageSource->Update();vtkSmartPointer<vtkImageBlend> imageBlend = vtkSmartPointer<vtkImageBlend>::New();imageBlend->AddInputData(reader->GetOutput());imageBlend->AddInputData(imageSource->GetOutput());imageBlend->SetOpacity(0, 0.4);imageBlend->SetOpacity(1, 0.6);imageBlend->Update();// Create actorsvtkSmartPointer<vtkImageActor> originalActor1 = vtkSmartPointer<vtkImageActor>::New();originalActor1->SetInputData(reader->GetOutput());vtkSmartPointer<vtkImageActor> originalActor2 =vtkSmartPointer<vtkImageActor>::New();originalActor2->SetInputData(imageSource->GetOutput());vtkSmartPointer<vtkImageActor> blendActor = vtkSmartPointer<vtkImageActor>::New();blendActor->SetInputData(imageBlend->GetOutput());// Define viewport ranges (xmin, ymin, xmax, ymax)double leftViewport[4] = {0.0, 0.0, 0.33, 1.0};double midViewport[4] = {0.33, 0.0, 0.66, 1.0};double rightViewport[4] = {0.66, 0.0, 1.0, 1.0};// Setup renderersvtkSmartPointer<vtkRenderer> originalRenderer1 = vtkSmartPointer<vtkRenderer>::New();originalRenderer1->AddActor(originalActor1);originalRenderer1->ResetCamera();originalRenderer1->SetBackground(1.0, 1.0, 1.0);originalRenderer1->SetViewport(leftViewport);vtkSmartPointer<vtkRenderer> originalRenderer2 = vtkSmartPointer<vtkRenderer>::New();originalRenderer2->AddActor(originalActor2);originalRenderer2->ResetCamera();originalRenderer2->SetBackground(1.0, 1.0, 1.0);originalRenderer2->SetViewport(midViewport);vtkSmartPointer<vtkRenderer> blendRenderer = vtkSmartPointer<vtkRenderer>::New();blendRenderer->AddActor(blendActor);blendRenderer->ResetCamera();blendRenderer->SetBackground(1.0, 1.0, 1.0);blendRenderer->SetViewport(rightViewport);vtkSmartPointer<vtkGenericOpenGLRenderWindow> renderWindow = vtkSmartPointer<vtkGenericOpenGLRenderWindow>::New();renderWindow->AddRenderer(originalRenderer1);renderWindow->AddRenderer(originalRenderer2);renderWindow->AddRenderer(blendRenderer);QVTKOpenGLNativeWidget w;w.resize(640,320);w.setRenderWindow(renderWindow);w.setWindowTitle("ImageBlendExample");w.show();return a.exec();
}

 运行效果:


http://www.ppmy.cn/devtools/100792.html

相关文章

stm32之I2C通信协议

文章目录 前言一、I2C通信协议二、I2C硬件电路三、I2C时序基本单元3.1 起始与终止信号3.2 发送与接收一个字节3.3 发送与接收应答 四、I2C时序分析4.1 指定地址写4.2 当前地址读4.3 指定地址读 前言 提示&#xff1a;本文主要用作在学习江科大自化协STM32入门教程后做的归纳总…

【Google SEO】搜索引擎索引综合SEO指南

有没有想过网站是如何在搜索引擎上列出的&#xff0c;以及 Google、Bing 和其他公司如何在几秒钟内为我们提供大量信息&#xff1f; 这种闪电般快速性能的秘诀在于搜索索引。它可以与所有页面的庞大且完美有序的目录档案进行比较。进入索引意味着搜索引擎已经看到了你的页面&a…

Python中的可迭代对象、迭代器、生成器和装饰器

Python是一种功能强大且灵活的编程语言&#xff0c;它提供了多种高级特性来简化代码和提高效率。本文将深入探讨Python中的可迭代对象&#xff08;Iterable&#xff09;、迭代器&#xff08;Iterator&#xff09;、生成器&#xff08;Generator&#xff09;和装饰器&#xff08…

【binder】【android12】【2.servicemanager启动——全源码分析】

系列文章目录 可跳转到下面链接查看下表所有内容https://blog.csdn.net/handsomethefirst/article/details/138226266?spm1001.2014.3001.5501文章浏览阅读2次。系列文章大全https://blog.csdn.net/handsomethefirst/article/details/138226266?spm1001.2014.3001.5501 目录 …

新手小白Ubuntu18.04超详细安装教程

1、Ubuntu18.04系统下载地址 Ubuntu18.04下载地址 直接下载桌面版 2、Ubuntu18.04安装 &#xff08;1&#xff09;打开VMware虚拟机 文件—>新建虚拟机—>选择典型 &#xff08;2&#xff09;选择稍后安装系统 &#xff08;3&#xff09;选择linux系统&#xff0c;…

第二代骁龙8平台手机nubia Z5拆解

这周末&#xff0c;除非外面下钞票&#xff0c;否则谁也拦不住我玩《黑神话悟空》&#xff08;附&#xff1a;两款可以玩转悟空的显卡推荐&#xff09; 天玑助力联发科力压高通~探秘MTK 5G旗舰智能手机SoC芯片——MT6989&#xff08;天玑9300&#xff09; 第二代骁龙8平台手机…

java 使用 aws s3 sdk 通过分段下载来实现 html 页面 video 的断点播放、拖动进度播放

参考博客&#xff1a; 1. Java 视频流分段返回 1. java 拉取 aws s3 视频流返回给浏览器&#xff1a; Overridepublic void playVideo(Long fileLength,String key,HttpServletRequest request,HttpServletResponse response) {OutputStream outputStream null;S3ObjectInputS…

深入解析ASP.NET Core 中间件:如何构建高效的请求处理管道

使用ASP.NET Core 中间件实现请求处理管道 前言 ASP.NET Core 是一个跨平台的高性能框架&#xff0c;主要用于构建现代的基于云的、互联网连接的应用程序。在ASP.NET Core 中&#xff0c;Middleware&#xff08;中间件&#xff09;是一个核心概念。中间件是处理HTTP请求和响应…