第5章 VTK图像处理
学习教程:《VTK图形图像开发进阶》张晓东,罗火灵
特别感谢:东灵工作室
5.1 VTK图像创建
5.1.1 VTK图像数据结构
图像可以看作是空间中的一个规则的网格,网格中的最小单元称为像素(二维)或体素(三维),网格在每个方向上的像素或体素的个数即为图像在该方向上的维数。像素索引表示的是该像素在图像网格中的位置,是图像内部的网格坐标。医学图像中,除了内部坐标外,还有一个世界坐标,依赖于成像设备,通过起点位置、像素间隔和像素索引即可计算每个像素的世界坐标。
数字图像文件内容包括两部分:图像头信息和图像数据。
- 图像头信息:定义图像基本信息,主要包括起点位置、像素间隔和维数。
- 图像数据:图像像素的像素值。图像像素值一般为标量(灰度图像),也可以为矢量(梯度图像),还可以是张量(弥散张量成像)。
注意:灰度图像像素或体素的数据类型在一般的灰度图像处理中不需要考虑,默认范围是0 ~ 255,采用unsigned char表示即可。但在医学图像处理中,由于256灰度级不能满足要求,因此常见医学图像的像素数据类型为unsigned short,灰度范围是0 ~ 65536。
5.1.2 VTK图像创建
- 图像源Source快速创建图像
VTK中内置多个创建图像的Source类,以vtkImageCanvasSource2D为代表说明。该类的功能是:创建一个空白的画布,并在其中绘制填充点、线段、圆、矩形等几何图形。
创建代码
#include <vtkSmartPointer.h>
#include <vtkImageData.h>
#include <vtkImageCanvasSource2D.h>
#include <vtkRenderWindow.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkInteractorStyleImage.h>
#include <vtkRenderer.h>
#include <vtkImageActor.h>
int main()
{
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();
//创建actors
vtkSmartPointer<vtkImageActor>redActor = vtkSmartPointer<vtkImageActor>::New();
redActor->SetInputData(canvas->GetOutput());
//定义viewport范围 (xmin,ymin,xmax,ymax) 视图位置
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("ImageCanvasSource2D");
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;
}
创建结果
参考:Solve error: ‘class vtkImageActor’ has no member named ‘SetInput’
提高:VTK修炼之道24:图像基本操作_单颜色通道图像合成彩色
- 直接创建——手动生成图像,再根据需要进行像素赋值
创建代码
#include <vtkSmartPointer.h>
#include <vtkImageData.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkRenderer.h>
#include <vtkRenderWindow.h>
#include <vtkInteractorStyleImage.h>
#include <vtkImageActor.h>
#include <vtkInformation.h>
int main()
{
//vtk的新版本在vtkImageData类中取消了SetScalarTypeToUnsignedChar()方法;
//现在仅能用如下方法设置:
//static void SetScalarType(int, vtkInformation* meta_data);
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);//每个像素需要表示的组份 =1是指标量图
img->AllocateScalars(info);//很重要
unsigned char *ptr = (unsigned char*)img->GetScalarPointer();
for (int i = 0; i < 16 * 16; i++)
{
*ptr++ = i % 256;
}
vtkSmartPointer<vtkImageActor>redActor = vtkSmartPointer<vtkImageActor>::New();
redActor->SetInputData(img);
double redViewport[4] = {
0.0,0.0,1.0,1.0 };
//Setup Renderer
vtkSmartPointer<vtkRenderer>redRenderer = vtkSmartPointer<vtkRenderer>::New();
redRenderer->SetViewport(redViewport);
redRenderer->AddActor(redActor);
redRenderer->ResetCamera();
redRenderer->SetBackground(1.0, 1.0, 1.0);
//Setup RenderWindow
vtkSmartPointer<vtkRenderWindow>renderWindow = vtkSmartPointer<vtkRenderWindow>::New();
renderWindow->AddRenderer(redRenderer);
renderWindow->SetSize(640, 480);
renderWindow->Render();
renderWindow->SetWindowName("CreateVTKImageData");
//Setup RenderWindowInteractor
vtkSmartPointer<vtkRenderWindowInteractor>renderWindowInteractor = vtkSmartPointer<vtkRenderWindowInteractor>::New();
vtkSmartPointer<vtkInteractorStyleImage>style = vtkSmartPointer<vtkInteractorStyleImage>::New();
renderWindowInteractor->SetInteractorStyle(style);
renderWindowInteractor->SetRenderWindow(renderWindow);
renderWindowInteractor->Initialize();
renderWindowInteractor->Start();
return 0;
}
创建结果