图像像素值的访问与修改是最常用的一种操作。
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; }
一些常用的图像算子(如梯度算子)在计算时出于精度考虑,会将结果存储为float或double类型,但在图像显示时,一般要求图像为unsigned char类型,这时需要对数据类型进行转换。最简单的类型转换Filter是vtkImageCast.
vtkImageShiftScale可以指定偏移和比例参数来对输入图像数据进行操作。
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; }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; }图像彩色映射的原理是:先生成一个颜色查找表,然后根据图像像素的一个标量值在颜色查找表中查找对应的颜色,并用新颜色的值代替原来的像素值。
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; }
感兴趣区域(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; }
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; }
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; }
彩色图像有三个颜色通道,需要提取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; }未补充...
vtkImageMathematics提供了基本的一元和二元数学操作。