图像信息的访问与修改
1、 利用vtkImageData的方法
vtkImageData中提供了多个函数用于访问或者获取图像的基本信息,这些函数通常以Set或者Get加上相应的信息名的形式进行命名,例如获取图像维数的方法定义为GetDimension()。 下面通过一个示例来说明怎样访问图像的基本信息。
#include"vtkSmartPointer.h"
#include"vtkBMPReader.h"
#include"vtkProperty.h"
#include"vtkImageData.h"
#include"vtkImageActor.h"
#include"vtkRenderer.h"
#include"vtkRenderWindow.h"
#include"vtkRenderWindowInteractor.h"
#include"vtkAutoInit.h"
#include"vtkPolyDataMapper.h"
VTK_MODULE_INIT(vtkRenderingOpenGL);
VTK_MODULE_INIT(vtkInteractionStyle);
VTK_MODULE_INIT(vtkRenderingFreeType);
VTK_MODULE_INIT(vtkRenderingVolumeOpenGL);
int main()
{
std::string filename = "lena.bmp";
vtkSmartPointer<vtkBMPReader> reader = vtkSmartPointer<vtkBMPReader>::New();
reader->SetFileName(filename.c_str());//读取.bmp图像
reader->Update();
int dims[3];
reader->GetOutput()->GetDimensions();
std::cout << "图像维数" << dims[0] << " " << dims[1] << " " << dims[2] << std::endl;
double origin[3];
reader->GetOutput()->GetOrigin(origin);
std::cout << "图像原点" << origin[0] << " " << origin[1] << " " << origin[2] << std::endl;
double spaceing[3];
reader->GetOutput()->GetSpacing(spaceing);
std::cout << "像素间隔" << spaceing[0] << " " << spaceing[1] << " " << spaceing[2] << std::endl;
vtkSmartPointer<vtkImageActor> actor = vtkSmartPointer<vtkImageActor>::New();
actor->SetInputData(reader->GetOutput());
vtkSmartPointer<vtkRenderer> ren = vtkSmartPointer<vtkRenderer>::New();
ren->AddActor(actor);
ren->SetBackground(1.0,1.0,1.0);
vtkSmartPointer<vtkRenderWindow> renwin = vtkSmartPointer<vtkRenderWindow>::New();
renwin->AddRenderer(ren);
renwin->SetSize(640,480);
renwin->Render();
vtkSmartPointer<vtkRenderWindowInteractor> iren = vtkSmartPointer<vtkRenderWindowInteractor>::New();
iren->SetRenderWindow(renwin);
iren->Initialize();
iren->Start();
return EXIT_SUCCESS;
}
上述示例主要获取了图像的三个信息,即图像维数、图像原点和像素间隔。VTK中无论是二维图像还是三维图像,都用vtkImageData,因此程序中定义图像维数是dims[3],然后利用GetDimension()函数获取图像的维数;图像的原点和像素间隔都是物理空间数值,其数值类型为double。上例读入一幅二维图像。为显示获取的图像信息。从显示结果中可以看到,图像维数为512*512*1,其中Z方向的维数为1,说明该图像为二维图像;而图像原点为(0,0,0)点,像素间隔为(1,1,1)。
利用vtkChangeImageInformation
vtkImageData 中提供了多个Set函数用于设置图像的基本信息,在对一个图像Filter的输出图像信息进行修改后如果Filter重新Update,图像信息又会恢复原来的值。而vtkChangeImageInformation类可以作为管线中的一个Filter来修改图像信息,利用这个Filter可以修改图像原点、像素间隔以及范围,另外还可以实现图像平移缩放等操作。
#include"vtkSmartPointer.h"
#include"vtkBMPReader.h"
#include"vtkProperty.h"
#include"vtkImageData.h"
#include"vtkImageActor.h"
#include"vtkRenderer.h"
#include"vtkRenderWindow.h"
#include"vtkRenderWindowInteractor.h"
#include"vtkAutoInit.h"
#include"vtkPolyDataMapper.h"
#include"vtkImageChangeInformation.h"
VTK_MODULE_INIT(vtkRenderingOpenGL);
VTK_MODULE_INIT(vtkInteractionStyle);
VTK_MODULE_INIT(vtkRenderingFreeType);
VTK_MODULE_INIT(vtkRenderingVolumeOpenGL);
int main()
{
vtkSmartPointer<vtkBMPReader> reader = vtkSmartPointer<vtkBMPReader>::New();
reader->SetFileName("lena.bmp");
reader->Update();
int dims[3];
double origin[3];
double spaceing[3];
reader->GetOutput()->GetDimensions(dims);
std::cout << "原图像维数:" << dims[0] << " " << dims[1] << " " << dims[2] << std::endl;
reader->GetOutput()->GetOrigin(origin);
std::cout << "原图像原点:" << origin[0] << " " << origin[1] << " " << origin[2] << std::endl;
reader->GetOutput()->GetSpacing(spaceing);
std::cout << "原图像间隔:" << spaceing[0] << " " << spaceing[1] << " " << spaceing[2] << std::endl;
vtkSmartPointer<vtkImageChangeInformation> changer = vtkSmartPointer<vtkImageChangeInformation>::New();
changer->SetInputData(reader->GetOutput());
changer->SetOutputOrigin(100, 100, 0);
changer->SetOutputSpacing(5,5,1);
changer->SetCenterImage(1);
changer->Update();
changer->GetOutput()->GetDimensions(dims);
std::cout << "修改后图像维数:" << dims[0] << " " << dims[1] << " " << dims[2] << std::endl;
changer->GetOutput()->GetOrigin(origin);
std::cout << "修改后图像原点:" << origin[0] << " " << origin[1] << " " << origin[2] << std::endl;
changer->GetOutput()->GetSpacing(spaceing);
std::cout << "修改后像素间隔:" << spaceing[0] << " " << spaceing[1] << " " << spaceing[2] << std::endl;
vtkSmartPointer<vtkImageActor> actor = vtkSmartPointer<vtkImageActor>::New();
actor->SetInputData(reader->GetOutput());
vtkSmartPointer<vtkRenderer> ren = vtkSmartPointer<vtkRenderer>::New();
ren->AddActor(actor);
ren->SetBackground(1.0, 1.0, 1.0);
vtkSmartPointer<vtkRenderWindow> renwin = vtkSmartPointer<vtkRenderWindow>::New();
renwin->AddRenderer(ren);
renwin->SetSize(640, 480);
renwin->Render();
vtkSmartPointer<vtkRenderWindowInteractor> iren = vtkSmartPointer<vtkRenderWindowInteractor>::New();
iren->SetRenderWindow(renwin);
iren->Initialize();
iren->Start();
return EXIT_SUCCESS;
}
上述示例先读入图像,由vtkImageData提供的函数接口获取图像的维数,图像原点和像素间隔,然后定义vtkImageChangeInformation对象,并设置输出图像原点为(100,100,0),输出图像像素间隔为(5,5,1),然后调用CenterImage()函数将图像的原点置于图像的中心,程序运行结果如上图所示。
从上述结果可以看出,操作后的结果使得图像的原点位于(-1277.5,-1277.5,0),SetOutputOrigin(100,100,0)并没有起作用。这是为什么呢? 如果看看CenterImage()函数的注释,可以发现该函数的作用是将(0,0,0)点置于图像的中心。当CenterImage()函数执行时会重新调用SetOutputOrigin(),所以开始的SetOutputOrigin()函数设置的原点将会被覆盖。那么(-1277.5,-1277.5,0)又是如何计算出来的呢?如下图根据图像的维数和像素间隔计算得到新的图像的宽度和高度(512-1)*5,初始图像的原点位于(0,0,0),现在将图像的中心平移至原点,平移量为(-(512-1)*5/2,-(512-1)*5/2,0)=(-1277.5,-1277.5,0)。
CenterImage()函数执行的示意图