5.3 VTK图像基本操作
5.3.1 图像信息的访问与修改
1. 利用vtkImageData的方法
///****************************************************/
///* Examples/Chap05/5.2_GetImageInformationExample.cpp */
///****************************************************/
#include <vtkSmartPointer.h>
#include <vtkJPEGReader.h>
#include <vtkImageData.h>
#include <vtkImageActor.h>
#include <vtkRenderer.h>
#include <vtkRenderWindow.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkInteractorStyleImage.h>
int main(int argn, char* argv[]) {
// 读入灰度图像
vtkSmartPointer<vtkJPEGReader> reader =
vtkSmartPointer<vtkJPEGReader>::New();
reader->SetFileName("D://1.jpg");
reader->Update();
int dims[3];
reader->GetOutput()->GetDimensions(dims);
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;
// Create actors
vtkSmartPointer<vtkImageActor> originalActor1 =
vtkSmartPointer<vtkImageActor>::New();
originalActor1->SetInputData(reader->GetOutput());
// setup renderers
vtkSmartPointer<vtkRenderer> originalRenderer1 =
vtkSmartPointer<vtkRenderer>::New();
originalRenderer1->AddActor(originalActor1);
originalRenderer1->ResetCamera();
originalRenderer1->SetBackground(1.0, 1.0, 1.0);
// setup render window
vtkSmartPointer<vtkRenderWindow> renderWindow =
vtkSmartPointer<vtkRenderWindow>::New();
renderWindow->AddRenderer(originalRenderer1);
renderWindow->SetSize(640, 320);
renderWindow->Render();
// Setup render window interactor
vtkSmartPointer<vtkRenderWindowInteractor> renderWindowInteractor =
vtkSmartPointer<vtkRenderWindowInteractor>::New();
vtkSmartPointer<vtkInteractorStyleImage> style =
vtkSmartPointer<vtkInteractorStyleImage>::New();
renderWindowInteractor->SetInteractorStyle(style);
// Render and start interactor
renderWindowInteractor->SetRenderWindow(renderWindow);
renderWindowInteractor->Initialize();
renderWindowInteractor->Start();
return EXIT_SUCCESS;
}
2. 利用vtkChangeImageInformation的方法
///****************************************************/
///* Examples/Chap05/5.2_ImageChangeInformationExample.cpp */
///****************************************************/
#include <vtkSmartPointer.h>
#include <vtkJPEGReader.h>
#include <vtkImageChangeInformation.h>
#include <vtkImageData.h>
#include <vtkImageActor.h>
#include <vtkRenderer.h>
#include <vtkRenderWindow.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkInteractorStyleImage.h>
int main(int argn, char* argv[]) {
// 读入灰度图像
vtkSmartPointer<vtkJPEGReader> reader =
vtkSmartPointer<vtkJPEGReader>::New();
reader->SetFileName("D://1.jpg");
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;
// Create actors
vtkSmartPointer<vtkImageActor> originalActor1 =
vtkSmartPointer<vtkImageActor>::New();
originalActor1->SetInputData(changer->GetOutput());
// setup renderers
vtkSmartPointer<vtkRenderer> originalRenderer1 =
vtkSmartPointer<vtkRenderer>::New();
originalRenderer1->AddActor(originalActor1);
originalRenderer1->ResetCamera();
originalRenderer1->SetBackground(1.0, 1.0, 1.0);
// setup render window
vtkSmartPointer<vtkRenderWindow> renderWindow =
vtkSmartPointer<vtkRenderWindow>::New();
renderWindow->AddRenderer(originalRenderer1);
renderWindow->SetSize(640, 320);
renderWindow->Render();
// Setup render window interactor
vtkSmartPointer<vtkRenderWindowInteractor> renderWindowInteractor =
vtkSmartPointer<vtkRenderWindowInteractor>::New();
vtkSmartPointer<vtkInteractorStyleImage> style =
vtkSmartPointer<vtkInteractorStyleImage>::New();
renderWindowInteractor->SetInteractorStyle(style);
// Render and start interactor
renderWindowInteractor->SetRenderWindow(renderWindow);
renderWindowInteractor->Initialize();
renderWindowInteractor->Start();
return EXIT_SUCCESS;
}
5.3.2 图像像素值的访问与修改
图像像素值的访问与修改是最常用的一种操作。
VTK提供两种访问图像像素值的方法:
第一种:直接访问vtkImageData的数据数组。vtkImageData提供GetScalarPointer函数获取数据数组指针
第二种:用vtkImageIterator类实现迭代器方法访问图像像素。该类是模板类,使用时需要提供迭代图像的像素类型以及迭代区域大小。
///****************************************************/
///* Examples/Chap05/5.3_VisitImagePixelDirectlyExample.cpp */
///****************************************************/
#include <vtkSmartPointer.h>
#include <vtkJPEGReader.h>
#include <vtkImageData.h>
#include <vtkImageActor.h>
#include <vtkRenderer.h>
#include <vtkRenderWindow.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkInteractorStyleImage.h>
int main(int argn, char* argv[]) {
// 读入灰度图像
vtkSmartPointer<vtkJPEGReader> reader =
vtkSmartPointer<vtkJPEGReader>::New();
reader->SetFileName("D://1.jpg");
reader->Update();
int dims[3];
reader->GetOutput()->GetDimensions(dims); // 得到图像大小
int nbOfComp;
nbOfComp = reader->GetOutput()->GetNumberOfScalarComponents(); // 获取像素的元组组分(是灰度图、梯度图还是RGB)
for (int k = 0; k < dims[2]; k++)
{
for (int j = 0; j < dims[1]; j++)
{
for (int i = 0; i < dims[1]; i++)
{
if (i<100&&j<100)
{
unsigned char * pixel =
(unsigned char *)(reader->GetOutput()->GetScalarPointer(i, j, k));
*pixel = 0;
*(pixel + 1) = 0; // G值的地址
*(pixel + 2) = 0; // B值的地址
}
}
}
}
// Create actors
vtkSmartPointer<vtkImageActor> originalActor1 =
vtkSmartPointer<vtkImageActor>::New();
originalActor1->SetInputData(reader->GetOutput());
// setup renderers
vtkSmartPointer<vtkRenderer> originalRenderer1 =
vtkSmartPointer<vtkRenderer>::New();
originalRenderer1->AddActor(originalActor1);
originalRenderer1->ResetCamera();
originalRenderer1->SetBackground(1.0, 1.0, 1.0);
// setup render window
vtkSmartPointer<vtkRenderWindow> renderWindow =
vtkSmartPointer<vtkRenderWindow>::New();
renderWindow->AddRenderer(originalRenderer1);
renderWindow->SetSize(640, 320);
renderWindow->Render();
// Setup render window interactor
vtkSmartPointer<vtkRenderWindowInteractor> renderWindowInteractor =
vtkSmartPointer<vtkRenderWindowInteractor>::New();
vtkSmartPointer<vtkInteractorStyleImage> style =
vtkSmartPointer<vtkInteractorStyleImage>::New();
renderWindowInteractor->SetInteractorStyle(style);
// Render and start interactor
renderWindowInteractor->SetRenderWindow(renderWindow);
renderWindowInteractor->Initialize();
renderWindowInteractor->Start();
return EXIT_SUCCESS;
}
///****************************************************/
///* Examples/Chap05/5.3_VisitImagePixelIterativeExample.cpp */
///****************************************************/
#include <vtkSmartPointer.h>
#include <vtkJPEGReader.h>
#include <vtkImageIterator.h>
#include <vtkImageData.h>
#include <vtkImageActor.h>
#include <vtkRenderer.h>
#include <vtkRenderWindow.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkInteractorStyleImage.h>
int main(int argn, char* argv[]) {
// 读入灰度图像
vtkSmartPointer<vtkJPEGReader> reader =
vtkSmartPointer<vtkJPEGReader>::New();
reader->SetFileName("D://1.jpg");
reader->Update();
int subRegion[6] = { 0,100,0,100,0,0 };
vtkImageIterator<unsigned char> it(reader->GetOutput(), subRegion);
while (!it.IsAtEnd()) // 判断迭代器是否结束
{
unsigned char* inSI = it.BeginSpan(); // 获取第一个组分
unsigned char* inSIEnd = it.EndSpan(); // 表示组分迭代完毕
while (inSI!=inSIEnd) //判断当前像素的元组Tuple是否迭代完毕
{
*inSI = 255 - *inSI;
++inSI; // 不断迭代组分
}
it.NextSpan(); // 组分迭代完毕后继续迭代像素it至下一个元组
}
// Create actors
vtkSmartPointer<vtkImageActor> originalActor1 =
vtkSmartPointer<vtkImageActor>::New();
originalActor1->SetInputData(reader->GetOutput());
// setup renderers
vtkSmartPointer<vtkRenderer> originalRenderer1 =
vtkSmartPointer<vtkRenderer>::New();
originalRenderer1->AddActor(originalActor1);
originalRenderer1->ResetCamera();
originalRenderer1->SetBackground(1.0, 1.0, 1.0);
// setup render window
vtkSmartPointer<vtkRenderWindow> renderWindow =
vtkSmartPointer<vtkRenderWindow>::New();
renderWindow->AddRenderer(originalRenderer1);
renderWindow->SetSize(640, 320);
renderWindow->Render();
// Setup render window interactor
vtkSmartPointer<vtkRenderWindowInteractor> renderWindowInteractor =
vtkSmartPointer<vtkRenderWindowInteractor>::New();
vtkSmartPointer<vtkInteractorStyleImage> style =
vtkSmartPointer<vtkInteractorStyleImage>::New();
renderWindowInteractor->SetInteractorStyle(style);
// Render and start interactor
renderWindowInteractor->SetRenderWindow(renderWindow);
renderWindowInteractor->Initialize();
renderWindowInteractor->Start();
return EXIT_SUCCESS;
}
5.3.3 图像类型转换
1.vtkImageCast
一些常用的图像算子(如梯度算子)在计算时出于精度考虑,会将结果存储为float或double类型,但在图像显示时,一般要求图像为unsigned char类型,这时需要对数据类型进行转换。最简单的类型转换Filter是vtkImageCast.
2.vtkImageShiftScale
vtkImageShiftScale可以指定偏移和比例参数来对输入图像数据进行操作。
5.3.4 图像颜色映射
1 图像灰度映射
vtkImageLuminance负责将一个RGB彩色图像转换为一个单组分的灰度图像。
///****************************************************/
///* Examples/Chap05/5.3_Color2GrayImageExample.cpp */
///****************************************************/
#include <vtkSmartPointer.h>
#include <vtkJPEGReader.h>
#include <vtkImageLuminance.h>
#include <vtkImageData.h>
#include <vtkImageActor.h>
#include <vtkRenderer.h>
#include <vtkRenderWindow.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkInteractorStyleImage.h>
int main(int argn, char* argv[]) {
// 读入灰度图像
vtkSmartPointer<vtkJPEGReader> reader =
vtkSmartPointer<vtkJPEGReader>::New();
reader->SetFileName("D://1.jpg");
reader->Update();
vtkSmartPointer<vtkImageLuminance> luminanceFilter =
vtkSmartPointer<vtkImageLuminance>::New();
luminanceFilter->SetInputConnection(reader->GetOutputPort());
luminanceFilter->Update();
// Create actors
vtkSmartPointer<vtkImageActor> originalActor =
vtkSmartPointer<vtkImageActor>::New();
originalActor->SetInputData(reader->GetOutput());
vtkSmartPointer<vtkImageActor> shiftscaleActor =
vtkSmartPointer<vtkImageActor>::New();
shiftscaleActor->SetInputData(luminanceFilter->GetOutput());
double originalViewport[4] = { 0.0,0.0,0.5,1.0 };
double shiftscaleViewport[4] = { 0.5,0.0,1.0,1.0 };
// setup renderers
vtkSmartPointer<vtkRenderer> originalRenderer =
vtkSmartPointer<vtkRenderer>::New();
originalRenderer->SetViewport(originalViewport);
originalRenderer->AddActor(originalActor);
originalRenderer->ResetCamera();
originalRenderer->SetBackground(1.0, 1.0, 1.0);
vtkSmartPointer<vtkRenderer> shiftscaleRenderer =
vtkSmartPointer<vtkRenderer>::New();
shiftscaleRenderer->SetViewport(shiftscaleViewport);
shiftscaleRenderer->AddActor(shiftscaleActor);
shiftscaleRenderer->ResetCamera();
shiftscaleRenderer->SetBackground(1.0, 1.0, 1.0);
// setup render window
vtkSmartPointer<vtkRenderWindow> renderWindow =
vtkSmartPointer<vtkRenderWindow>::New();
renderWindow->AddRenderer(originalRenderer);
renderWindow->AddRenderer(shiftscaleRenderer);
renderWindow->SetSize(640, 320);
renderWindow->Render();
// Setup render window interactor
vtkSmartPointer<vtkRenderWindowInteractor> renderWindowInteractor =
vtkSmartPointer<vtkRenderWindowInteractor>::New();
vtkSmartPointer<vtkInteractorStyleImage> style =
vtkSmartPointer<vtkInteractorStyleImage>::New();
renderWindowInteractor->SetInteractorStyle(style);
// Render and start interactor
renderWindowInteractor->SetRenderWindow(renderWindow);
renderWindowInteractor->Initialize();
renderWindowInteractor->Start();
return EXIT_SUCCESS;
}
2 提取颜色组分
VTK中利用vtkImageExtractComponents可以方便地提取彩色图像的各个颜色组分。
///****************************************************/
///* Examples/Chap05/5.3_ImageExtractComponentsExample.cpp */
///****************************************************/
#include <vtkSmartPointer.h>
#include <vtkJPEGReader.h>
#include <vtkImageExtractComponents.h>
#include <vtkImageData.h>
#include <vtkImageActor.h>
#include <vtkRenderer.h>
#include <vtkRenderWindow.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkInteractorStyleImage.h>
int main(int argn, char* argv[]) {
// 读入灰度图像
vtkSmartPointer<vtkJPEGReader> reader =
vtkSmartPointer<vtkJPEGReader>::New();
reader->SetFileName("D://1.jpg");
reader->Update();
vtkSmartPointer<vtkImageExtractComponents> extractRedFilter =
vtkSmartPointer<vtkImageExtractComponents>::New();
extractRedFilter->SetInputConnection(reader->GetOutputPort());
extractRedFilter->SetComponents(0);
extractRedFilter->Update();
vtkSmartPointer<vtkImageExtractComponents> extractGreenFilter =
vtkSmartPointer<vtkImageExtractComponents>::New();
extractGreenFilter->SetInputConnection(reader->GetOutputPort());
extractGreenFilter->SetComponents(1);
extractGreenFilter->Update();
vtkSmartPointer<vtkImageExtractComponents> extractBlueFilter =
vtkSmartPointer<vtkImageExtractComponents>::New();
extractBlueFilter->SetInputConnection(reader->GetOutputPort());
extractBlueFilter->SetComponents(2);
extractBlueFilter->Update();
// Create actors
vtkSmartPointer<vtkImageActor> inputActor =
vtkSmartPointer<vtkImageActor>::New();
inputActor->SetInputData(reader->GetOutput());
vtkSmartPointer<vtkImageActor> redActor =
vtkSmartPointer<vtkImageActor>::New();
redActor->SetInputData(extractRedFilter->GetOutput());
vtkSmartPointer<vtkImageActor> greenActor =
vtkSmartPointer<vtkImageActor>::New();
greenActor->SetInputData(extractGreenFilter->GetOutput());
vtkSmartPointer<vtkImageActor> blueActor =
vtkSmartPointer<vtkImageActor>::New();
blueActor->SetInputData(extractBlueFilter->GetOutput());
double inputViewport[4] = { 0.0, 0.0, 0.25, 1.0 };
double redViewport[4] = { 0.25, 0.0, 0.5, 1.0 };
double greenViewport[4] = { 0.5, 0.0, 0.75, 1.0 };
double blueViewport[4] = { 0.75, 0.0, 1.0, 1.0 };
vtkSmartPointer<vtkRenderer> inputRenderer =
vtkSmartPointer<vtkRenderer>::New();
inputRenderer->SetViewport(inputViewport);
inputRenderer->AddActor(inputActor);
inputRenderer->ResetCamera();
inputRenderer->SetBackground(1.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<vtkRenderer> greenRenderer =
vtkSmartPointer<vtkRenderer>::New();
greenRenderer->SetViewport(greenViewport);
greenRenderer->AddActor(greenActor);
greenRenderer->ResetCamera();
greenRenderer->SetBackground(1.0, 1.0, 1.0);
vtkSmartPointer<vtkRenderer> blueRenderer =
vtkSmartPointer<vtkRenderer>::New();
blueRenderer->SetViewport(blueViewport);
blueRenderer->AddActor(blueActor);
blueRenderer->ResetCamera();
blueRenderer->SetBackground(1.0, 1.0, 1.0);
vtkSmartPointer<vtkRenderWindow> renderWindow =
vtkSmartPointer<vtkRenderWindow>::New();
renderWindow->AddRenderer(inputRenderer);
renderWindow->AddRenderer(redRenderer);
renderWindow->AddRenderer(greenRenderer);
renderWindow->AddRenderer(blueRenderer);
renderWindow->SetSize(1200, 320);
renderWindow->Render();
// Setup render window interactor
vtkSmartPointer<vtkRenderWindowInteractor> renderWindowInteractor =
vtkSmartPointer<vtkRenderWindowInteractor>::New();
vtkSmartPointer<vtkInteractorStyleImage> style =
vtkSmartPointer<vtkInteractorStyleImage>::New();
renderWindowInteractor->SetInteractorStyle(style);
// Render and start interactor
renderWindowInteractor->SetRenderWindow(renderWindow);
renderWindowInteractor->Initialize();
renderWindowInteractor->Start();
return EXIT_SUCCESS;
}
3 图像彩色映射
图像彩色映射的原理是:先生成一个颜色查找表,然后根据图像像素的一个标量值在颜色查找表中查找对应的颜色,并用新颜色的值代替原来的像素值。
VTK以vtkImageMapToColor实现图像彩色映射,以vtkLookUpTable生成颜色查找表。
///****************************************************/
///* Examples/Chap05/5.3_Gray2ColorImageExample.cpp */
///****************************************************/
#include <vtkSmartPointer.h>
#include <vtkJPEGReader.h>
#include <vtkLookupTable.h>
#include <vtkImageMapToColors.h>
#include <vtkImageData.h>
#include <vtkImageActor.h>
#include <vtkRenderer.h>
#include <vtkRenderWindow.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkInteractorStyleImage.h>
int main(int argn, char* argv[]) {
// 读入灰度图像
vtkSmartPointer<vtkJPEGReader> reader =
vtkSmartPointer<vtkJPEGReader>::New();
reader->SetFileName("D://1.jpg");
reader->Update();
vtkSmartPointer<vtkLookupTable> colorTable =
vtkSmartPointer<vtkLookupTable>::New(); // 生成颜色查找表
colorTable->SetRange(0.0, 255.0); // 设置要映射的标量数据的范围
colorTable->SetHueRange(0.1, 0.5); // 设置HSV颜色空间的Hue值范围,最大范围「0 1」
colorTable->SetHueRange(0.6, 1.0); // 设置HSV颜色空间的value值范围,最大范围「0 1」
colorTable->Build(); // 生成颜色查找表
vtkSmartPointer<vtkImageMapToColors> colorMap =
vtkSmartPointer<vtkImageMapToColors>::New();
colorMap->SetInputConnection(reader->GetOutputPort());
colorMap->SetLookupTable(colorTable);
colorMap->Update();
// Create actors
vtkSmartPointer<vtkImageActor> originalActor =
vtkSmartPointer<vtkImageActor>::New();
originalActor->SetInputData(reader->GetOutput());
vtkSmartPointer<vtkImageActor> shiftscaleActor =
vtkSmartPointer<vtkImageActor>::New();
shiftscaleActor->SetInputData(colorMap->GetOutput());
double originalViewport[4] = { 0.0, 0.0, 0.5, 1.0 };
double shiftscaleViewport[4] = { 0.5, 0.0,1.0, 1.0 };
vtkSmartPointer<vtkRenderer> inputRenderer =
vtkSmartPointer<vtkRenderer>::New();
inputRenderer->SetViewport(originalViewport);
inputRenderer->AddActor(originalActor);
inputRenderer->ResetCamera();
inputRenderer->SetBackground(1.0, 1.0, 1.0);
vtkSmartPointer<vtkRenderer> redRenderer =
vtkSmartPointer<vtkRenderer>::New();
redRenderer->SetViewport(shiftscaleViewport);
redRenderer->AddActor(shiftscaleActor);
redRenderer->ResetCamera();
redRenderer->SetBackground(1.0, 1.0, 1.0);
vtkSmartPointer<vtkRenderWindow> renderWindow =
vtkSmartPointer<vtkRenderWindow>::New();
renderWindow->AddRenderer(inputRenderer);
renderWindow->AddRenderer(redRenderer);
renderWindow->SetSize(900, 320);
renderWindow->Render();
// Setup render window interactor
vtkSmartPointer<vtkRenderWindowInteractor> renderWindowInteractor =
vtkSmartPointer<vtkRenderWindowInteractor>::New();
vtkSmartPointer<vtkInteractorStyleImage> style =
vtkSmartPointer<vtkInteractorStyleImage>::New();
renderWindowInteractor->SetInteractorStyle(style);
// Render and start interactor
renderWindowInteractor->SetRenderWindow(renderWindow);
renderWindowInteractor->Initialize();
renderWindowInteractor->Start();
return EXIT_SUCCESS;
}
4 颜色合成
///****************************************************/
///* Examples/Chap05/5.3_ImageAppendComponentsExample.cpp */
///****************************************************/
#include <vtkSmartPointer.h>
#include <vtkImageCanvasSource2D.h>
#include <vtkImageAppendComponents.h>
#include <vtkImageData.h>
#include <vtkImageActor.h>
#include <vtkRenderer.h>
#include <vtkRenderWindow.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkInteractorStyleImage.h>
int main(int argn, char* argv[]) {
vtkSmartPointer<vtkImageCanvasSource2D> red =
vtkSmartPointer<vtkImageCanvasSource2D>::New();
red->SetScalarTypeToUnsignedChar();
red->SetNumberOfScalarComponents(1);
red->SetExtent(0, 100, 0, 100, 0, 0);
red->SetDrawColor(0,0,0,0);
red->FillBox(0, 100, 0, 100);
red->SetDrawColor(255, 0, 0, 0);
red->FillBox(20, 40, 20, 40);
red->Update();
vtkSmartPointer<vtkImageCanvasSource2D> green =
vtkSmartPointer<vtkImageCanvasSource2D>::New();
green->SetScalarTypeToUnsignedChar();
green->SetNumberOfScalarComponents(1);
green->SetExtent(0, 100, 0, 100, 0, 0);
green->SetDrawColor(0, 0, 0, 0);
green->FillBox(0, 100, 0, 100);
green->SetDrawColor(255, 0, 0, 0);
green->FillBox(30, 50, 30, 50);
green->Update();
vtkSmartPointer<vtkImageCanvasSource2D> blue =
vtkSmartPointer<vtkImageCanvasSource2D>::New();
blue->SetScalarTypeToUnsignedChar();
blue->SetNumberOfScalarComponents(1);
blue->SetExtent(0, 100, 0, 100, 0, 0);
blue->SetDrawColor(0, 0, 0, 0);
blue->FillBox(0, 100, 0, 100);
blue->SetDrawColor(255, 0, 0, 0);
blue->FillBox(40, 60, 40,60);
blue->Update();
vtkSmartPointer<vtkImageAppendComponents> appendFilter =
vtkSmartPointer<vtkImageAppendComponents>::New();
appendFilter->SetInputConnection(red->GetOutputPort());
appendFilter->AddInputConnection(green->GetOutputPort());
appendFilter->AddInputConnection(blue->GetOutputPort());
appendFilter->Update();
// Create actors
vtkSmartPointer<vtkImageActor> redActor =
vtkSmartPointer<vtkImageActor>::New();
redActor->SetInputData(red->GetOutput());
vtkSmartPointer<vtkImageActor> greenActor =
vtkSmartPointer<vtkImageActor>::New();
greenActor->SetInputData(green->GetOutput());
vtkSmartPointer<vtkImageActor> blueActor =
vtkSmartPointer<vtkImageActor>::New();
blueActor->SetInputData(blue->GetOutput());
vtkSmartPointer<vtkImageActor> combinedActor =
vtkSmartPointer<vtkImageActor>::New();
combinedActor->SetInputData(appendFilter->GetOutput());
// Define viewport ranges
// (xmin, ymin, xmax, ymax)
double redViewport[4] = { 0.0, 0.0, 0.25, 1.0 };
double greenViewport[4] = { 0.25, 0.0, 0.5, 1.0 };
double blueViewport[4] = { 0.5, 0.0, 0.75, 1.0 };
double combinedViewport[4] = { 0.75, 0.0, 1.0, 1.0 };
// Setup renderers
vtkSmartPointer<vtkRenderer> redRenderer =
vtkSmartPointer<vtkRenderer>::New();
redRenderer->SetViewport(redViewport);
redRenderer->AddActor(redActor);
redRenderer->ResetCamera();
redRenderer->SetBackground(1.0, 1.0, 1.0);
vtkSmartPointer<vtkRenderer> greenRenderer =
vtkSmartPointer<vtkRenderer>::New();
greenRenderer->SetViewport(greenViewport);
greenRenderer->AddActor(greenActor);
greenRenderer->ResetCamera();
greenRenderer->SetBackground(1.0, 1.0, 1.0);
vtkSmartPointer<vtkRenderer> blueRenderer =
vtkSmartPointer<vtkRenderer>::New();
blueRenderer->SetViewport(blueViewport);
blueRenderer->AddActor(blueActor);
blueRenderer->ResetCamera();
blueRenderer->SetBackground(1.0, 1.0, 1.0);
vtkSmartPointer<vtkRenderer> combinedRenderer =
vtkSmartPointer<vtkRenderer>::New();
combinedRenderer->SetViewport(combinedViewport);
combinedRenderer->AddActor(combinedActor);
combinedRenderer->ResetCamera();
combinedRenderer->SetBackground(1.0, 1.0, 1.0);
vtkSmartPointer<vtkRenderWindow> renderWindow =
vtkSmartPointer<vtkRenderWindow>::New();
renderWindow->AddRenderer(redRenderer);
renderWindow->AddRenderer(greenRenderer);
renderWindow->AddRenderer(blueRenderer);
renderWindow->AddRenderer(combinedRenderer);
renderWindow->SetSize(1200, 300);
renderWindow->Render();
// Setup render window interactor
vtkSmartPointer<vtkRenderWindowInteractor> renderWindowInteractor =
vtkSmartPointer<vtkRenderWindowInteractor>::New();
vtkSmartPointer<vtkInteractorStyleImage> style =
vtkSmartPointer<vtkInteractorStyleImage>::New();
renderWindowInteractor->SetInteractorStyle(style);
// Render and start interactor
renderWindowInteractor->SetRenderWindow(renderWindow);
renderWindowInteractor->Initialize();
renderWindowInteractor->Start();
return EXIT_SUCCESS;
}
5.3.5 区域提取
1 提取感兴趣区域
感兴趣区域(Volume of Interest,VOI)是图像内部的一块子区域。在VTK中,vtkRxtractVOI类可根据用户指定的区域范围提取子图像。
///****************************************************/
///* Examples/Chap05/5.3_ExtractVOIExample.cpp */
///****************************************************/
#include <vtkSmartPointer.h>
#include <vtkJPEGReader.h>
#include <vtkExtractVOI.h>
#include <vtkImageData.h>
#include <vtkImageActor.h>
#include <vtkRenderer.h>
#include <vtkRenderWindow.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkInteractorStyleImage.h>
int main(int argn, char* argv[]) {
// 读入灰度图像
vtkSmartPointer<vtkJPEGReader> reader =
vtkSmartPointer<vtkJPEGReader>::New();
reader->SetFileName("D://1.jpg");
reader->Update();
int dims[3];
reader->GetOutput()->GetDimensions(dims);
vtkSmartPointer<vtkExtractVOI> extractVOI =
vtkSmartPointer<vtkExtractVOI>::New();
extractVOI->SetInputConnection(reader->GetOutputPort());
extractVOI->SetVOI(dims[0]/4.,3.*dims[0]/4., dims[1] / 4., 3.*dims[1] / 4.,0,0);
extractVOI->Update();
// Create actors
vtkSmartPointer<vtkImageActor> originalActor =
vtkSmartPointer<vtkImageActor>::New();
originalActor->SetInputData(reader->GetOutput());
vtkSmartPointer<vtkImageActor> voiActor =
vtkSmartPointer<vtkImageActor>::New();
voiActor->SetInputData(extractVOI->GetOutput());
double originalViewport[4] = { 0.0, 0.0, 0.5, 1.0 };
double shiftscaleViewport[4] = { 0.5, 0.0,1.0, 1.0 };
vtkSmartPointer<vtkRenderer> inputRenderer =
vtkSmartPointer<vtkRenderer>::New();
inputRenderer->SetViewport(originalViewport);
inputRenderer->AddActor(originalActor);
inputRenderer->ResetCamera();
inputRenderer->SetBackground(1.0, 1.0, 1.0);
vtkSmartPointer<vtkRenderer> redRenderer =
vtkSmartPointer<vtkRenderer>::New();
redRenderer->SetViewport(shiftscaleViewport);
redRenderer->AddActor(voiActor);
redRenderer->ResetCamera();
redRenderer->SetBackground(1.0, 1.0, 1.0);
vtkSmartPointer<vtkRenderWindow> renderWindow =
vtkSmartPointer<vtkRenderWindow>::New();
renderWindow->AddRenderer(inputRenderer);
renderWindow->AddRenderer(redRenderer);
renderWindow->SetSize(900, 320);
renderWindow->Render();
// Setup render window interactor
vtkSmartPointer<vtkRenderWindowInteractor> renderWindowInteractor =
vtkSmartPointer<vtkRenderWindowInteractor>::New();
vtkSmartPointer<vtkInteractorStyleImage> style =
vtkSmartPointer<vtkInteractorStyleImage>::New();
renderWindowInteractor->SetInteractorStyle(style);
// Render and start interactor
renderWindowInteractor->SetRenderWindow(renderWindow);
renderWindowInteractor->Initialize();
renderWindowInteractor->Start();
return EXIT_SUCCESS;
}
2 三维图像截面提取
VTK中vtkImageReslice类可实现图像切面的提取。
///****************************************************/
///* Examples/Chap05/5.3_ImageResliceExample.cpp */
///****************************************************/
#include <vtkSmartPointer.h>
#include <vtkJPEGReader.h>
#include <vtkMatrix4x4.h>
#include <vtkImageReslice.h>
#include <vtkLookupTable.h>
#include <vtkImageMapToColors.h>
#include <vtkImageData.h>
#include <vtkImageActor.h>
#include <vtkRenderer.h>
#include <vtkRenderWindow.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkInteractorStyleImage.h>
int main(int argn, char* argv[]) {
// 读入灰度图像
vtkSmartPointer<vtkJPEGReader> reader =
vtkSmartPointer<vtkJPEGReader>::New();
reader->SetFileName("D://1.jpg");
reader->Update();
int extent[6];
double spacing[3];
double origin[3];
reader->GetOutput()->GetDimensions(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());
// Create actors
vtkSmartPointer<vtkImageActor> originalActor =
vtkSmartPointer<vtkImageActor>::New();
originalActor->SetInputData(reader->GetOutput());
vtkSmartPointer<vtkImageActor> resliceActor =
vtkSmartPointer<vtkImageActor>::New();
resliceActor->SetInputData(colorMap->GetOutput());
double originalViewport[4] = { 0.0, 0.0, 0.5, 1.0 };
double shiftscaleViewport[4] = { 0.5, 0.0,1.0, 1.0 };
vtkSmartPointer<vtkRenderer> inputRenderer =
vtkSmartPointer<vtkRenderer>::New();
inputRenderer->SetViewport(originalViewport);
inputRenderer->AddActor(originalActor);
inputRenderer->ResetCamera();
inputRenderer->SetBackground(1.0, 1.0, 1.0);
vtkSmartPointer<vtkRenderer> redRenderer =
vtkSmartPointer<vtkRenderer>::New();
redRenderer->SetViewport(shiftscaleViewport);
redRenderer->AddActor(resliceActor);
redRenderer->ResetCamera();
redRenderer->SetBackground(1.0, 1.0, 1.0);
vtkSmartPointer<vtkRenderWindow> renderWindow =
vtkSmartPointer<vtkRenderWindow>::New();
renderWindow->AddRenderer(inputRenderer);
renderWindow->AddRenderer(redRenderer);
renderWindow->SetSize(900, 320);
renderWindow->Render();
// Setup render window interactor
vtkSmartPointer<vtkRenderWindowInteractor> renderWindowInteractor =
vtkSmartPointer<vtkRenderWindowInteractor>::New();
vtkSmartPointer<vtkInteractorStyleImage> style =
vtkSmartPointer<vtkInteractorStyleImage>::New();
renderWindowInteractor->SetInteractorStyle(style);
// Render and start interactor
renderWindowInteractor->SetRenderWindow(renderWindow);
renderWindowInteractor->Initialize();
renderWindowInteractor->Start();
return EXIT_SUCCESS;
}
3 扩展-滑动鼠标切换三维图像切面
/**********************************************************************
文件名: 5.3_ImageResliceExample2.cpp
Copyright (c) 张晓东, 罗火灵. All rights reserved.
更多信息请访问:
http://www.vtkchina.org (VTK中国)
http://blog.csdn.net/www_doling_net (东灵工作室)
**********************************************************************/
#include <vtkSmartPointer.h>
#include <vtkImageReader2.h>
#include <vtkMatrix4x4.h>
#include <vtkImageReslice.h>
#include <vtkLookupTable.h>
#include <vtkImageMapToColors.h>
#include <vtkImageActor.h>
#include <vtkRenderer.h>
#include <vtkRenderWindow.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkInteractorStyleImage.h>
#include <vtkCommand.h>
#include <vtkImageData.h>
#include <vtkMetaImageReader.h>
#include <vtkImageCast.h>
class vtkImageInteractionCallback:public vtkCommand
{
public:
static vtkImageInteractionCallback *New()
{
return new vtkImageInteractionCallback;
}
vtkImageInteractionCallback()
{
this->Slicing = 0;
this->ImageReslice = 0;
this->Interactor = 0;
}
void SetImageReslice(vtkImageReslice *reslice) {
this->ImageReslice = reslice;
}
vtkImageReslice * GetImageReslice() {
return this->ImageReslice;
}
void SetInteractor(vtkRenderWindowInteractor *interactor) {
this->Interactor = interactor;
}
vtkRenderWindowInteractor * GetInteractor() {
return this->Interactor;
}
virtual void Execute(vtkObject*, unsigned long event, void*) {
vtkRenderWindowInteractor *interactor = this->GetInteractor();
int lastPos[2];
interactor->GetLastEventPosition(lastPos);
int currPos[2];
interactor->GetEventPosition(currPos);
if (event == vtkCommand::LeftButtonPressEvent)
{
this->Slicing = 1;
}
else if (event == vtkCommand::LeftButtonReleaseEvent)
{
this->Slicing = 0;
}
else if (event == vtkCommand::MouseMoveEvent)
{
if (this->Slicing)
{
vtkImageReslice *reslice = this->ImageReslice;
// Increment slice position by deltaY of mouse
int deltaY = lastPos[1] - currPos[1];
reslice->Update();
double sliceSpacing = reslice->GetOutput()->GetSpacing()[2];
vtkMatrix4x4 *matrix = reslice->GetResliceAxes();
// move the center point that we are slicing through
double point[4];
double center[4];
point[0] = 0.0;
point[1] = 0.0;
point[2] = sliceSpacing * deltaY;
point[3] = 1.0;
matrix->MultiplyPoint(point, center);
matrix->SetElement(0, 3, center[0]);
matrix->SetElement(1, 3, center[1]);
matrix->SetElement(2, 3, center[2]);
//printf("%f %f %f\n", center[0], center[1], center[2]);
interactor->Render();
}
else
{
vtkInteractorStyle *style = vtkInteractorStyle::SafeDownCast(
interactor->GetInteractorStyle());
if (style)
{
style->OnMouseMove();
}
}
}
}
private:
int Slicing;
vtkImageReslice *ImageReslice;
vtkRenderWindowInteractor *Interactor;
};
int main()
{
vtkSmartPointer<vtkMetaImageReader> reader =
vtkSmartPointer<vtkMetaImageReader>::New();
reader->SetFileName("..\\data\\brain.mhd");
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->SetInputData(colorMap->GetOutput());
vtkSmartPointer<vtkRenderer> renderer =
vtkSmartPointer<vtkRenderer>::New();
renderer->AddActor(imgActor);
renderer->SetBackground(.4, .5, .6);
vtkSmartPointer<vtkRenderWindow> renderWindow =
vtkSmartPointer<vtkRenderWindow>::New();
renderWindow->SetSize(500, 500);
renderWindow->AddRenderer(renderer);
vtkSmartPointer<vtkRenderWindowInteractor> renderWindowInteractor =
vtkSmartPointer<vtkRenderWindowInteractor>::New();
vtkSmartPointer<vtkInteractorStyleImage> imagestyle =
vtkSmartPointer<vtkInteractorStyleImage>::New();
renderWindowInteractor->SetInteractorStyle(imagestyle);
renderWindowInteractor->SetRenderWindow(renderWindow);
renderWindowInteractor->Initialize();
vtkSmartPointer<vtkImageInteractionCallback> callback =
vtkSmartPointer<vtkImageInteractionCallback>::New();
callback->SetImageReslice(reslice);
callback->SetInteractor(renderWindowInteractor);
imagestyle->AddObserver(vtkCommand::MouseMoveEvent, callback);
imagestyle->AddObserver(vtkCommand::LeftButtonPressEvent, callback);
imagestyle->AddObserver(vtkCommand::LeftButtonReleaseEvent, callback);
renderWindowInteractor->Start();
return EXIT_SUCCESS;
}
5.3.6 直方图统计
1 灰度图像直方图
VTK中的vtkImageAccumulate类用于实现直方图的统计功能。
///****************************************************/
///* Examples/Chap05/5.3_ImageAccumulateExample.cpp */
///****************************************************/
#include <vtkSmartPointer.h>
#include <vtkJPEGReader.h>
#include <vtkImageAccumulate.h>
#include <vtkIntArray.h>
#include <vtkFieldData.h>
#include <vtkProperty2D.h>
#include <vtkLegendBoxActor.h>
#include <vtkBarChartActor.h>
#include <vtkImageData.h>
#include <vtkImageActor.h>
#include <vtkRenderer.h>
#include <vtkRenderWindow.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkInteractorStyleImage.h>
int main(int argn, char* argv[]) {
// 读入灰度图像
vtkSmartPointer<vtkJPEGReader> reader =
vtkSmartPointer<vtkJPEGReader>::New();
reader->SetFileName("D://1.jpg");
reader->Update();
int bins = 16; // 灰度直方图的间隔数目
int comps = 1;
vtkSmartPointer<vtkImageAccumulate> histogram =
vtkSmartPointer<vtkImageAccumulate>::New();
histogram->SetInputData(reader->GetOutput());
histogram->SetComponentExtent(0,bins-1,0,0,0,0);
histogram->SetComponentOrigin(0,0,0);
histogram->SetComponentSpacing(256.0/bins,0,0);
histogram->Update();
int* output = static_cast<int*>(histogram->GetOutput()->GetScalarPointer());
vtkSmartPointer<vtkIntArray> frequencies =
vtkSmartPointer<vtkIntArray>::New();
frequencies->SetNumberOfComponents(1);
for (int j = 0; j < bins; ++j)
{
for (int i = 0; i < comps; i++)
{
frequencies->InsertNextTuple1(*output++);
}
}
vtkSmartPointer<vtkDataObject> dataObject =
vtkSmartPointer<vtkDataObject>::New();
dataObject->GetFieldData()->AddArray(frequencies);
vtkSmartPointer<vtkBarChartActor> barChart =
vtkSmartPointer<vtkBarChartActor>::New();
barChart->SetInput(dataObject);
barChart->SetTitle("Histogram");
barChart->GetPositionCoordinate()->SetValue(0.05, 0.05, 0.0);
barChart->GetPosition2Coordinate()->SetValue(0.95, 0.95, 0.0);
barChart->GetProperty()->SetColor(1, 1, 1);
barChart->GetLegendActor()->SetNumberOfEntries(
dataObject->GetFieldData()->GetArray(0)->GetNumberOfTuples()
);
barChart->LegendVisibilityOff();
barChart->LabelVisibilityOff();
double colors[3][3] = {
{1,0,0},
{ 0,1,0 },
{ 0,0,1},
};
int count = 0;
for (int i = 0; i < bins; i++)
{
for (int j = 0; j < comps; j++)
{
barChart->SetBarColor(count++, colors[j]);
}
}
vtkSmartPointer<vtkRenderer> inputRenderer =
vtkSmartPointer<vtkRenderer>::New();
inputRenderer->AddActor(barChart);
inputRenderer->ResetCamera();
inputRenderer->SetBackground(1.0, 1.0, 1.0);
vtkSmartPointer<vtkRenderWindow> renderWindow =
vtkSmartPointer<vtkRenderWindow>::New();
renderWindow->AddRenderer(inputRenderer);
renderWindow->SetSize(600, 320);
renderWindow->Render();
// Setup render window interactor
vtkSmartPointer<vtkRenderWindowInteractor> renderWindowInteractor =
vtkSmartPointer<vtkRenderWindowInteractor>::New();
vtkSmartPointer<vtkInteractorStyleImage> style =
vtkSmartPointer<vtkInteractorStyleImage>::New();
renderWindowInteractor->SetInteractorStyle(style);
// Render and start interactor
renderWindowInteractor->SetRenderWindow(renderWindow);
renderWindowInteractor->Initialize();
renderWindowInteractor->Start();
return EXIT_SUCCESS;
}
2 彩色图像直方图
彩色图像有三个颜色通道,需要提取RGB三个通道数据分别计算直方图。每个通道计算直方图的方法与灰度直方图的计算方法一致。
///****************************************************/
///* Examples/Chap05/5.3_ImageAccumulateExample2.cpp */
///****************************************************/
#include <vtkSmartPointer.h>
#include <vtkActor.h>
#include <vtkImageAccumulate.h>
#include <vtkImageData.h>
#include <vtkImageExtractComponents.h>
#include <vtkJPEGReader.h>
#include <vtkRenderWindow.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkRenderer.h>
#include <vtkXYPlotActor.h>
#include <vtkAxisActor2D.h>
#include <vtkProperty2D.h>
#include <vtkTextProperty.h>
int main(int argc, char* argv[])
{
vtkSmartPointer<vtkJPEGReader> reader =
vtkSmartPointer<vtkJPEGReader>::New();
reader->SetFileName("D://1.jpg");
reader->Update();
int numComponents = reader->GetOutput()->GetNumberOfScalarComponents();
vtkSmartPointer<vtkXYPlotActor> plot =
vtkSmartPointer<vtkXYPlotActor>::New();
plot->ExchangeAxesOff();
plot->SetLabelFormat("%g");
plot->SetXTitle("Intensity");
plot->SetYTitle("Frequency");
plot->SetXValuesToValue();
plot->GetProperty()->SetColor(0.0, 0.0, 0.0);
plot->GetAxisLabelTextProperty()->SetColor(0.0, 0.0, 0.0);
plot->GetAxisTitleTextProperty()->SetColor(0.0, 0.0, 0.0);
double colors[3][3] = {
{ 1, 0, 0 },
{ 0, 1, 0 },
{ 0, 0, 1 }
};
const char* labels[3] = { "Red", "Green", "Blue" };
int xmax = 0;
int ymax = 0;
for (int i = 0; i < numComponents; ++i)
{
vtkSmartPointer<vtkImageExtractComponents> extract =
vtkSmartPointer<vtkImageExtractComponents>::New();
extract->SetInputConnection(reader->GetOutputPort());
extract->SetComponents(i);
extract->Update();
double range[2];
extract->GetOutput()->GetScalarRange(range);
int extent = static_cast<int>(range[1]) - static_cast<int>(range[0]) - 1;
vtkSmartPointer<vtkImageAccumulate> histogram =
vtkSmartPointer<vtkImageAccumulate>::New();
histogram->SetInputConnection(extract->GetOutputPort());
histogram->SetComponentExtent(0, extent, 0, 0, 0, 0);
histogram->SetComponentOrigin(range[0], 0, 0);
histogram->SetComponentSpacing(1, 0, 0);
histogram->SetIgnoreZero(1);
histogram->Update();
if (range[1] > xmax)
{
xmax = range[1];
}
if (histogram->GetOutput()->GetScalarRange()[1] > ymax)
{
ymax = histogram->GetOutput()->GetScalarRange()[1];
}
plot->AddDataSetInput(histogram->GetOutput());
plot->SetPlotColor(i, colors[i]);
plot->SetPlotLabel(i, labels[i]);
plot->LegendOn();
}
plot->SetXRange(0, xmax);
plot->SetYRange(0, ymax);
vtkSmartPointer<vtkRenderer> renderer =
vtkSmartPointer<vtkRenderer>::New();
renderer->AddActor(plot);
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("ImageAccumulateExample2");
vtkSmartPointer<vtkRenderWindowInteractor> interactor =
vtkSmartPointer<vtkRenderWindowInteractor>::New();
interactor->SetRenderWindow(renderWindow);
interactor->Initialize();
interactor->Start();
return EXIT_SUCCESS;
}
5.3.7 图像重采样
未补充...
5.3.8 图像运算
1 数学运算
vtkImageMathematics提供了基本的一元和二元数学操作。
2 逻辑运算
5.3.9 图像二值化