VTK图形图像开发进阶-学习笔记 05(02) VTK图像处理

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 图像二值化

 

 

 

 

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值