欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 房产 > 建筑 > VTK随笔七:VTK图像处理(图像基本操作)

VTK随笔七:VTK图像处理(图像基本操作)

2024/10/26 15:33:17 来源:https://blog.csdn.net/u012959478/article/details/141568742  浏览:    关键词:VTK随笔七:VTK图像处理(图像基本操作)

VTK图像基本操作

一、图像信息的访问与修改
1、利用 vtkImageData 的方法 
    vtkSmartPointer<vtkBMPReader> reader = vtkSmartPointer<vtkBMPReader>::New();reader->SetFileName ("D:/data/lena.bmp");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;
 2、利用类vtkChangeImageInformation
    vtkSmartPointer<vtkBMPReader> reader = vtkSmartPointer<vtkBMPReader>::New();reader->SetFileName ("D:/data/lena.bmp");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;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;
二、图像像素值的访问与修改
 1、直接访问vtkImageData的数据数组
    vtkSmartPointer<vtkBMPReader> reader = vtkSmartPointer<vtkBMPReader>::New();reader->SetFileName("D:/data/lena.bmp");reader->Update();int dims[3];reader->GetOutput()->GetDimensions(dims);int nbOfComp;nbOfComp = reader->GetOutput()->GetNumberOfScalarComponents();for(int k=0; k<dims[2]; k++){for(int j=0; j<dims[1]; j++){for(int i=0; i<dims[0]; i++){if(i<100 && j<100){unsigned char * pixel = (unsigned char *) ( reader->GetOutput()->GetScalarPointer(i, j, k) );*pixel = 0;*(pixel+1) = 0;*(pixel+2) = 0;}}}}
2、用 vtkImagelterator 类实现迭代器方法访问图像像素
    vtkSmartPointer<vtkBMPReader> reader = vtkSmartPointer<vtkBMPReader>::New();reader->SetFileName ("D:/data/lena.bmp");reader->Update();int subRegion[6] = {0,300, 0, 300, 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){*inSI = 255-*inSI;++inSI;}it.NextSpan();}
三、图像类型转换
1、vtkImageCast

        图像数据类型转换在数字图像处理中会频繁用到。一些常用的图像算子(例如梯度算子)在计算时出于精度的考虑,会将结果存储为oat或double类型,但在图像显示时,一般要求图像为 unsigned char 类型,这时就需要对数据类型进行转换。

    vtkSmartPointer<vtkImageCast> imageCast = vtkSmartPointer<vtkImageCast>::New();imageCast->SetInputData((vtkDataObject *)reader->GetOutput());imageCast->SetOutputScalarTypeToFloat();imageCast->Update();
 2、vtkImageShiftScale

        vtkImageShifScale 可以指定偏移和比例参数来对输入图像数据进行操作,例如一幅double 类型的图像,其数值范围为[-1,1],如果将其转换为 unsigned char 类型,需要设置 shif值为+1,比例系数设置为 127.5,那么输入数据-1映射为(-1+1)X127.5=0,而+1则会映射为(+1+1)x127.5=255。

    vtkSmartPointer<vtkImageShiftScale> imageShiftScale = vtkSmartPointer<vtkImageShiftScale>::New();imageShiftScale->SetInputConnection(reader->GetOutputPort());imageShiftScale->SetOutputScalarTypeToFloat();imageShiftScale->SetShift(1);imageShiftScale->SetScale(127.5);imageShiftScale->Update();
四、图像颜色映射
1、图像灰度映射 

        vtkImageLuminance 负责将一个RGB 彩色图像转换为一个单组分的灰度图像。映射公式为Luminance=0.3xR+0.59xG+0.11xB 

#include <QApplication>
#include <vtkSmartPointer.h>
#include <vtkImageData.h>
#include <vtkRenderer.h>
#include <vtkImageLuminance.h>
#include <vtkImageActor.h>
#include <vtkGenericOpenGLRenderWindow.h>
#include <QVTKOpenGLNativeWidget.h>
#include <vtkBMPReader.h>int main(int argc, char *argv[])
{QApplication a(argc, argv);vtkSmartPointer<vtkBMPReader> reader = vtkSmartPointer<vtkBMPReader>::New();reader->SetFileName ("D:/data/lena.bmp");reader->Update();vtkSmartPointer<vtkImageLuminance> luminanceFilter = vtkSmartPointer<vtkImageLuminance>::New();luminanceFilter->SetInputData(reader->GetOutput());luminanceFilter->Update();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};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);vtkSmartPointer<vtkGenericOpenGLRenderWindow> renderWindow = vtkSmartPointer<vtkGenericOpenGLRenderWindow>::New();renderWindow->AddRenderer(originalRenderer);renderWindow->AddRenderer(shiftscaleRenderer);QVTKOpenGLNativeWidget w;w.resize(640,320);w.setRenderWindow(renderWindow);w.setWindowTitle("Color2GrayImageExample");w.show();return a.exec();
}

 运行效果:

2、提取颜色组分

         VTK 中利用 vtkImageExtractComponents 可以方便地提取彩色图像的各个颜色组分。 

#include <QApplication>
#include <vtkSmartPointer.h>
#include <vtkImageData.h>
#include <vtkRenderer.h>
#include <vtkImageActor.h>
#include <vtkGenericOpenGLRenderWindow.h>
#include <QVTKOpenGLNativeWidget.h>
#include <vtkBMPReader.h>
#include <vtkImageExtractComponents.h>int main(int argc, char *argv[])
{QApplication a(argc, argv);vtkSmartPointer<vtkBMPReader> reader = vtkSmartPointer<vtkBMPReader>::New();reader->SetFileName ("D:/data/lena.bmp");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 actorsvtkSmartPointer<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<vtkGenericOpenGLRenderWindow> renderWindow = vtkSmartPointer<vtkGenericOpenGLRenderWindow>::New();renderWindow->AddRenderer(inputRenderer);renderWindow->AddRenderer(redRenderer);renderWindow->AddRenderer(greenRenderer);renderWindow->AddRenderer(blueRenderer);QVTKOpenGLNativeWidget w;w.resize(1200,300);w.setRenderWindow(renderWindow);w.setWindowTitle("ImageExtractComponentsExample");w.show();return a.exec();
}

运行效果:

3、图像彩色映射 

        图像彩色映射的原理是:先生成一个颜色查找表,然后根据图像像素的一个标量值在颜色查找表中查找对应的颜色,并用新颜色值替代原来的像素值。VTK中以vkmageMapToColors 实现图像彩色映射,以 vtkLookUpTable 生成颜色查找表。

#include <QApplication>
#include <vtkSmartPointer.h>
#include <vtkImageData.h>
#include <vtkRenderer.h>
#include <vtkImageActor.h>
#include <vtkGenericOpenGLRenderWindow.h>
#include <QVTKOpenGLNativeWidget.h>
#include <vtkJPEGReader.h>
#include <vtkLookupTable.h>
#include <vtkImageMapToColors.h>int main(int argc, char *argv[])
{QApplication a(argc, argv);vtkSmartPointer<vtkJPEGReader> reader = vtkSmartPointer<vtkJPEGReader>::New();reader->SetFileName ( "D:/data/lena-gray.jpg" );reader->Update();vtkSmartPointer<vtkLookupTable> colorTable = vtkSmartPointer<vtkLookupTable>::New();colorTable->SetRange( 0.0, 255.0 );colorTable->SetHueRange( 0.1, 0.5 );colorTable->SetValueRange( 0.6, 1.0 );colorTable->Build();vtkSmartPointer<vtkImageMapToColors> colorMap = vtkSmartPointer<vtkImageMapToColors>::New();colorMap->SetInputConnection( reader->GetOutputPort() );colorMap->SetLookupTable( colorTable );colorMap->Update();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> 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, 0.8);vtkSmartPointer<vtkGenericOpenGLRenderWindow> renderWindow = vtkSmartPointer<vtkGenericOpenGLRenderWindow>::New();renderWindow->AddRenderer(originalRenderer);renderWindow->AddRenderer(shiftscaleRenderer);QVTKOpenGLNativeWidget w;w.resize(900,300);w.setRenderWindow(renderWindow);w.setWindowTitle("Gray2ColorImageExample");w.show();return a.exec();
}

运行效果:

        该示例先读取了一幅灰度图像,然后生成 vtkLookUpTable 颜色查找表。构造颜色查找表有两种方法:一种是直接添加颜色;另一种是设置HSV颜色空间变化范围,然后自动生成颜色表。这里采用的是第二种方法。

4、颜色合成
#include <QApplication>
#include <vtkSmartPointer.h>
#include <vtkImageData.h>
#include <vtkRenderer.h>
#include <vtkImageActor.h>
#include <vtkGenericOpenGLRenderWindow.h>
#include <QVTKOpenGLNativeWidget.h>
#include <vtkImageAppendComponents.h>
#include <vtkImageCanvasSource2D.h>int main(int argc, char *argv[])
{QApplication a(argc, 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(0, red->GetOutputPort());appendFilter->AddInputConnection(0, green->GetOutputPort());appendFilter->AddInputConnection(0, blue->GetOutputPort());appendFilter->Update();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 renderersvtkSmartPointer<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<vtkGenericOpenGLRenderWindow> renderWindow = vtkSmartPointer<vtkGenericOpenGLRenderWindow>::New();renderWindow->AddRenderer(redRenderer);renderWindow->AddRenderer(greenRenderer);renderWindow->AddRenderer(blueRenderer);renderWindow->AddRenderer(combinedRenderer);QVTKOpenGLNativeWidget w;w.resize(1200,300);w.setRenderWindow(renderWindow);w.setWindowTitle("ImageAppendComponentsExample");w.show();return a.exec();
}

 运行效果:

五、区域提取 
1、提取指定区域范围
#include <QApplication>
#include <vtkSmartPointer.h>
#include <vtkImageData.h>
#include <vtkRenderer.h>
#include <vtkImageActor.h>
#include <vtkGenericOpenGLRenderWindow.h>
#include <QVTKOpenGLNativeWidget.h>
#include <vtkBMPReader.h>
#include <vtkExtractVOI.h>int main(int argc, char *argv[])
{QApplication a(argc, argv);vtkSmartPointer<vtkBMPReader> reader = vtkSmartPointer<vtkBMPReader>::New();reader->SetFileName ("D:/data/lena.bmp");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();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 voiviewport[4] = {0.5, 0.0, 1.0, 1.0};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(voiviewport);shiftscaleRenderer->AddActor(voiActor);shiftscaleRenderer->ResetCamera();shiftscaleRenderer->SetBackground(1.0, 1.0, 1.0);vtkSmartPointer<vtkGenericOpenGLRenderWindow> renderWindow = vtkSmartPointer<vtkGenericOpenGLRenderWindow>::New();renderWindow->AddRenderer(originalRenderer);renderWindow->AddRenderer(shiftscaleRenderer);QVTKOpenGLNativeWidget w;w.resize(900,300);w.setRenderWindow(renderWindow);w.setWindowTitle("ImageAppendComponentsExample");w.show();return a.exec();
}

运行效果: 

 

2、三维图像切面提取

#include <QApplication>
#include <vtkSmartPointer.h>
#include <vtkImageData.h>
#include <vtkRenderer.h>
#include <vtkImageActor.h>
#include <vtkGenericOpenGLRenderWindow.h>
#include <QVTKOpenGLNativeWidget.h>
#include <vtkMatrix4x4.h>
#include <vtkMetaImageReader.h>
#include <vtkImageReslice.h>
#include <vtkLookupTable.h>
#include <vtkImageMapToColors.h>int main(int argc, char *argv[])
{QApplication a(argc, argv);vtkSmartPointer<vtkMetaImageReader> reader = vtkSmartPointer<vtkMetaImageReader>::New();reader->SetFileName("D:/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());colorMap->Update();vtkSmartPointer<vtkImageActor> imgActor = vtkSmartPointer<vtkImageActor>::New();imgActor->SetInputData(colorMap->GetOutput());vtkSmartPointer<vtkRenderer> renderer = vtkSmartPointer<vtkRenderer>::New();renderer->AddActor(imgActor);renderer->SetBackground(1.0, 1.0, 1.0);vtkSmartPointer<vtkGenericOpenGLRenderWindow> renderWindow = vtkSmartPointer<vtkGenericOpenGLRenderWindow>::New();renderWindow->AddRenderer(renderer);QVTKOpenGLNativeWidget w;w.resize(640,480);w.setRenderWindow(renderWindow);w.setWindowTitle("ImageResliceExample");w.show();return a.exec();
}

运行效果:

六、直方图统计
1、灰度图像直方图 
#include <QApplication>
#include <vtkSmartPointer.h>
#include <vtkImageData.h>
#include <vtkRenderer.h>
#include <vtkImageActor.h>
#include <vtkGenericOpenGLRenderWindow.h>
#include <QVTKOpenGLNativeWidget.h>
#include <vtkJPEGReader.h>
#include <vtkImageAccumulate.h>
#include <vtkIntArray.h>
#include <vtkBarChartActor.h>
#include <vtkFieldData.h>
#include <vtkTextProperty.h>
#include <vtkLegendBoxActor.h>
#include <vtkProperty2D.h>int main(int argc, char *argv[])
{QApplication a(argc, argv);//读取一副灰度图像 灰度范围0-255vtkSmartPointer<vtkJPEGReader> reader = vtkSmartPointer<vtkJPEGReader>::New();reader->SetFileName ( "D:/data/lena-gray.jpg" );reader->Update();int bins   = 16; //灰度直方图的间隔数目int comps  = 1;  //一个组分vtkSmartPointer<vtkImageAccumulate> histogram = vtkSmartPointer<vtkImageAccumulate>::New();histogram->SetInputData(reader->GetOutput());//灰度图像只有一个组分,第二和第三个组分设置为0;第一组分直方图维数为bins,其最小和最大范围为0和bins-1histogram->SetComponentExtent(0, bins-1, 0, 0, 0, 0);//设置统计每个组分直方图时的起始灰度值,这里设置为0,表示灰度从0开始统计直方图.//如果图像灰度范围为[1000,2000],其起始灰度应设置为1000histogram->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);//将直方图数组存储到vtkIntArray数组frequencies中for(int j = 0; j < bins; ++j){for(int i=0; i<comps; i++){frequencies->InsertNextTuple1(*output++);}}//将vtkImageData类型的直方图数据转换为vtkDataObject类型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.1,0.1,0.0);//设置窗口中显示图表的所在矩形的左下角点坐标,注意:VTK的坐标系原点位于左下角点barChart->GetPosition2Coordinate()->SetValue(0.9,0.9,0.0);//设置窗口中显示图表的所在矩形的右上角点坐标barChart->GetProperty()->SetColor(0,0,0);barChart->GetTitleTextProperty()->SetColor(0,0,0);barChart->GetLabelTextProperty()->SetColor(0,0,0);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> renderer = vtkSmartPointer<vtkRenderer>::New();renderer->AddActor(barChart);renderer->SetBackground(1.0, 1.0, 1.0);vtkSmartPointer<vtkGenericOpenGLRenderWindow> renderWindow = vtkSmartPointer<vtkGenericOpenGLRenderWindow>::New();renderWindow->AddRenderer(renderer);QVTKOpenGLNativeWidget w;w.resize(640,480);w.setRenderWindow(renderWindow);w.setWindowTitle("ImageAccumulateExample");w.show();return a.exec();
}

运行结果:

2、彩色图像直方图 
#include <QApplication>
#include <vtkSmartPointer.h>
#include <vtkImageData.h>
#include <vtkRenderer.h>
#include <vtkImageActor.h>
#include <vtkGenericOpenGLRenderWindow.h>
#include <QVTKOpenGLNativeWidget.h>
#include <vtkJPEGReader.h>
#include <vtkImageAccumulate.h>
#include <vtkXYPlotActor.h>
#include <vtkImageExtractComponents.h>
#include <vtkFieldData.h>
#include <vtkTextProperty.h>
#include <vtkLegendBoxActor.h>
#include <vtkProperty2D.h>int main(int argc, char *argv[])
{QApplication a(argc, argv);vtkSmartPointer<vtkJPEGReader> reader = vtkSmartPointer<vtkJPEGReader>::New();reader->SetFileName ( "D:/data/lena.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<vtkGenericOpenGLRenderWindow> renderWindow = vtkSmartPointer<vtkGenericOpenGLRenderWindow>::New();renderWindow->AddRenderer(renderer);QVTKOpenGLNativeWidget w;w.resize(640,480);w.setRenderWindow(renderWindow);w.setWindowTitle("ImageAccumulateExample");w.show();return a.exec();
}

 运行结果:

七、图像重采样

        图像重采样是指对数字图像按所需的像素位置或像素间距重新采样,以构成几何变换后的新图像。

        重采样后图像的维数会发生改变。当重采样图像维数小于原图像时,称为降采样;当重采样图像维数大于原图像时,称为升采样。在VTK中,vtklmageShrink3D 类可用于实现图像降采样, vklmageMagnify 类可用于实现图像的升采样。

#include <QApplication>
#include <vtkSmartPointer.h>
#include <vtkImageData.h>
#include <vtkRenderer.h>
#include <vtkImageActor.h>
#include <vtkGenericOpenGLRenderWindow.h>
#include <QVTKOpenGLNativeWidget.h>
#include <vtkJPEGReader.h>
#include <vtkImageShrink3D.h>
#include <vtkImageMagnify.h>
#include <QDebug>int main(int argc, char *argv[])
{QApplication a(argc, argv);vtkSmartPointer<vtkJPEGReader> reader = vtkSmartPointer<vtkJPEGReader>::New();reader->SetFileName ( "D:/data/lena.jpg" );reader->Update();vtkSmartPointer<vtkImageShrink3D> shrinkFilter =vtkSmartPointer<vtkImageShrink3D>::New();shrinkFilter->SetInputConnection(reader->GetOutputPort());shrinkFilter->SetShrinkFactors(16,16,1);shrinkFilter->Update();vtkSmartPointer<vtkImageMagnify> magnifyFilter = vtkSmartPointer<vtkImageMagnify>::New();magnifyFilter->SetInputConnection(reader->GetOutputPort());magnifyFilter->SetMagnificationFactors(10,10,1);magnifyFilter->Update();int originalDims[3];reader->GetOutput()->GetDimensions(originalDims);double originalSpace[3];reader->GetOutput()->GetSpacing(originalSpace);int shrinkDims[3];shrinkFilter->GetOutput()->GetDimensions(shrinkDims);double shrinkSpace[3];shrinkFilter->GetOutput()->GetSpacing(shrinkSpace);int magnifyDims[3];magnifyFilter->GetOutput()->GetDimensions(magnifyDims);double magnifySpace[3];magnifyFilter->GetOutput()->GetSpacing(magnifySpace);qDebug()<<"原图图像维数      :"<<originalDims[0] << " "<<originalDims[1]<<" "<<originalDims[2];qDebug()<<"原图图像像素间隔  :"<<originalSpace[0] << " "<<originalSpace[1]<<" "<<originalSpace[2];qDebug()<<"降采样图像维数    :"<<shrinkDims[0] << " "<<shrinkDims[1]<<" "<<shrinkDims[2];qDebug()<<"降采样图像像素间隔:"<<shrinkSpace[0] << " "<<shrinkSpace[1]<<" "<<shrinkSpace[2];qDebug()<<"升采样图像维数    :"<<magnifyDims[0] << " "<<magnifyDims[1]<<" "<<magnifyDims[2];qDebug()<<"升采样图像像素间隔:"<<magnifySpace[0] << " "<<magnifySpace[1]<<" "<<magnifySpace[2];vtkSmartPointer<vtkImageActor> originalActor = vtkSmartPointer<vtkImageActor>::New();originalActor->SetInputData(reader->GetOutput());vtkSmartPointer<vtkImageActor> shrinkActor = vtkSmartPointer<vtkImageActor>::New();shrinkActor->SetInputData(shrinkFilter->GetOutput());vtkSmartPointer<vtkImageActor> magnifyActor = vtkSmartPointer<vtkImageActor>::New();magnifyActor->SetInputData(magnifyFilter->GetOutput());double originalViewport[4] = {0.0, 0.0, 0.33, 1.0};double shrinkViewport[4] = {0.33, 0.0, 0.66, 1.0};double magnifyViewport[4] = {0.66, 0.0, 1.0, 1.0};vtkSmartPointer<vtkRenderer> originalRenderer = vtkSmartPointer<vtkRenderer>::New();originalRenderer->SetViewport(originalViewport);originalRenderer->AddActor(originalActor);originalRenderer->ResetCamera();originalRenderer->SetBackground(1.0, 1.0, 1.0);vtkSmartPointer<vtkRenderer> shrinkRenderer = vtkSmartPointer<vtkRenderer>::New();shrinkRenderer->SetViewport(shrinkViewport);shrinkRenderer->AddActor(shrinkActor);shrinkRenderer->ResetCamera();shrinkRenderer->SetBackground(1.0, 1.0, 1.0);vtkSmartPointer<vtkRenderer> magnifyRenderer = vtkSmartPointer<vtkRenderer>::New();magnifyRenderer->SetViewport(magnifyViewport);magnifyRenderer->AddActor(magnifyActor);magnifyRenderer->ResetCamera();magnifyRenderer->SetBackground(1.0, 1.0, 1.0);vtkSmartPointer<vtkGenericOpenGLRenderWindow> renderWindow = vtkSmartPointer<vtkGenericOpenGLRenderWindow>::New();renderWindow->AddRenderer(originalRenderer);renderWindow->AddRenderer(shrinkRenderer);renderWindow->AddRenderer(magnifyRenderer);QVTKOpenGLNativeWidget w;w.resize(640,320);w.setRenderWindow(renderWindow);w.setWindowTitle("ImageShrinkMagnifyExample");w.show();return a.exec();
}

 运行效果:

八、图像运算
1、 数字运算

 vtklmageMathematics 提供了基本的一元和二元数学操作。

vtkImageMathematics 中支持的二元数学操作如下:

SetOperationToAdd:两个图像对应像素加法运算。
SetOperationToSubtract:两个图像对应像素减法运算。
SetOperationToMultiply:两个图像对应像素相乘运算。
SetOperationToDivide:两个图像对应像素相除运算。
SetOperationToConjugate:将两个标量图像对应像素组合为共轭复数。
SetOperationToComplexMultiply:两个图像对应像素复数乘法运算。
SetOperationToMin:取两个图像对应像素中的较小值。
SetOperationToMax:取两个图像对应像素中的较大值。

vtkImageMathematics中支持的一元操作如下:

SetOperationTolnvert:图像像素值取倒数运算。
SetOperationToSin:图像像素值正弦运算。
SetOperationToCos:图像像素值余弦运算。
SetOperationToExp:图像像素值自然指数运算。
SetOperationToLog:图像像素值自然对数运算,
SetOperationToAbsoluteValue:图像像素值取绝对值。
SetOperationToSquare:图像像素值平方运算。
SetOperationToSquareRoot:图像像素值平方根运算。
SetOperationTOATAN:图像像素值反正切运算。
SetOperationTOATAN2:图像像素值二元反正切运算SetOperationToMultiplyByK:图像像素值乘以常数K,需要先调用 SetConstantK设置K值。
SetOperationToAddConstant:图像像素值加上常数K,需要先调用 SetConstantK()设置K值。
SetOperationToReplaceCByK:将图像中像素为C的像素值替换为K,需要先调用SetConstantK()和SetConstantC 设置K和C值。
2、逻辑运算

vtkImageLogic 设置逻辑运算的函数如下:
SetOperationToAnd():逻辑与。
SetOperationToOr():逻辑或。
SetOperationToXor():逻辑异或。
SetOperationToNand():逻辑与非。
SetOperationToNor():逻辑或非。
SetOperationToNot():逻辑非。 

 示例代码:

#include <QApplication>
#include <vtkSmartPointer.h>
#include <vtkImageData.h>
#include <vtkRenderer.h>
#include <vtkImageActor.h>
#include <vtkGenericOpenGLRenderWindow.h>
#include <QVTKOpenGLNativeWidget.h>
#include <vtkImageCanvasSource2D.h>
#include <vtkImageLogic.h>int main(int argc, char *argv[])
{QApplication a(argc, argv);vtkSmartPointer<vtkImageCanvasSource2D> imageSource1 = vtkSmartPointer<vtkImageCanvasSource2D>::New();imageSource1->SetScalarTypeToUnsignedChar();imageSource1->SetNumberOfScalarComponents(1);imageSource1->SetExtent(0, 100, 0, 100, 0, 0);imageSource1->SetDrawColor(0.0);imageSource1->FillBox(0,100,0,100);imageSource1->SetDrawColor(255);imageSource1->FillBox(20,60,20,60);imageSource1->Update();vtkSmartPointer<vtkImageCanvasSource2D> imageSource2 = vtkSmartPointer<vtkImageCanvasSource2D>::New();imageSource2->SetNumberOfScalarComponents(1);imageSource2->SetScalarTypeToUnsignedChar();imageSource2->SetExtent(0, 100, 0, 100, 0, 0);imageSource2->SetDrawColor(0.0);imageSource2->FillBox(0,100,0,100);imageSource2->SetDrawColor(255.0);imageSource2->FillBox(40,80,40,80);imageSource2->Update();vtkSmartPointer<vtkImageLogic> imageLogic = vtkSmartPointer<vtkImageLogic>::New();imageLogic->SetInput1Data(imageSource1->GetOutput());imageLogic->SetInput2Data(imageSource2->GetOutput());imageLogic->SetOperationToXor();imageLogic->SetOutputTrueValue(128);imageLogic->Update();vtkSmartPointer<vtkImageActor> originalActor1 = vtkSmartPointer<vtkImageActor>::New();originalActor1->SetInputData(imageSource1->GetOutput());vtkSmartPointer<vtkImageActor> originalActor2 = vtkSmartPointer<vtkImageActor>::New();originalActor2->SetInputData(imageSource2->GetOutput());vtkSmartPointer<vtkImageActor> logicActor = vtkSmartPointer<vtkImageActor>::New();logicActor->SetInputData(imageLogic->GetOutput());double leftViewport[4] = {0.0, 0.0, 0.33, 1.0};double midViewport[4] = {0.33, 0.0, 0.66, 1.0};double rightViewport[4] = {0.66, 0.0, 1.0, 1.0};vtkSmartPointer<vtkRenderer> originalRenderer1 = vtkSmartPointer<vtkRenderer>::New();originalRenderer1->SetViewport(leftViewport);originalRenderer1->AddActor(originalActor1);originalRenderer1->ResetCamera();originalRenderer1->SetBackground(1.0, 1.0, 1.0);vtkSmartPointer<vtkRenderer> originalRenderer2 = vtkSmartPointer<vtkRenderer>::New();originalRenderer2->SetViewport(midViewport);originalRenderer2->AddActor(originalActor2);originalRenderer2->ResetCamera();originalRenderer2->SetBackground(0.8, 0.8, 0.8);vtkSmartPointer<vtkRenderer> logicRenderer = vtkSmartPointer<vtkRenderer>::New();logicRenderer->SetViewport(rightViewport);logicRenderer->AddActor(logicActor);logicRenderer->ResetCamera();logicRenderer->SetBackground(0.6, 0.6, 0.6);vtkSmartPointer<vtkGenericOpenGLRenderWindow> renderWindow = vtkSmartPointer<vtkGenericOpenGLRenderWindow>::New();renderWindow->AddRenderer(originalRenderer1);renderWindow->AddRenderer(originalRenderer2);renderWindow->AddRenderer(logicRenderer);QVTKOpenGLNativeWidget w;w.resize(640,320);w.setRenderWindow(renderWindow);w.setWindowTitle("ImageLogicExample");w.show();return a.exec();
}

运行结果:

九、图像二值化 

        vtkImageThreshold 类可实现图像的阈值化处理,但其功能不仅仅是生成二值图像。        

        vtklmageThreshold 类中定义了两个阈值,即 UpperThreshold 和LowerThreshold,这两个值将图像的值域划分为三部分:大于UpperThreshold、小于LowerThreshold 以及位于LowerThreshold和UpperThreshold 之间的三段。 函数 ThresholdByUpper()设置为取大于UpperThreshold 的灰度范围为有效范围,并通过函数 SetinValue()来设置该范围内的输出值,SetOutValue0)设置范围外的输出值,以下实例取大于 100的所有像素输出值为 255,而小于100的像素输出值为0。

#include <QApplication>
#include <vtkSmartPointer.h>
#include <vtkImageData.h>
#include <vtkRenderer.h>
#include <vtkImageActor.h>
#include <vtkGenericOpenGLRenderWindow.h>
#include <QVTKOpenGLNativeWidget.h>
#include <vtkJPEGReader.h>
#include <vtkImageThreshold.h>int main(int argc, char *argv[])
{QApplication a(argc, argv);vtkSmartPointer<vtkJPEGReader> reader = vtkSmartPointer<vtkJPEGReader>::New();reader->SetFileName("D:/data/lena-gray.jpg");reader->Update();vtkSmartPointer<vtkImageThreshold> thresholdFilter = vtkSmartPointer<vtkImageThreshold>::New();thresholdFilter->SetInputConnection(reader->GetOutputPort());thresholdFilter->ThresholdByUpper(100);thresholdFilter->SetInValue(255);thresholdFilter->SetOutValue(0);thresholdFilter->Update();vtkSmartPointer<vtkImageActor> originalActor = vtkSmartPointer<vtkImageActor>::New();originalActor->SetInputData(reader->GetOutput());vtkSmartPointer<vtkImageActor> binaryActor = vtkSmartPointer<vtkImageActor>::New();binaryActor->SetInputData(thresholdFilter->GetOutput());double originalViewport[4] = {0.0, 0.0, 0.5, 1.0};double binaryviewport[4] = {0.5, 0.0, 1.0, 1.0};vtkSmartPointer<vtkRenderer> originalRenderer = vtkSmartPointer<vtkRenderer>::New();originalRenderer->SetViewport(originalViewport);originalRenderer->AddActor(originalActor);originalRenderer->ResetCamera();originalRenderer->SetBackground(1.0, 1.0, 1.0);vtkSmartPointer<vtkRenderer> binaryRenderer = vtkSmartPointer<vtkRenderer>::New();binaryRenderer->SetViewport(binaryviewport);binaryRenderer->AddActor(binaryActor);binaryRenderer->ResetCamera();binaryRenderer->SetBackground(1.0, 1.0, 1.0);vtkSmartPointer<vtkGenericOpenGLRenderWindow> renderWindow = vtkSmartPointer<vtkGenericOpenGLRenderWindow>::New();renderWindow->AddRenderer(originalRenderer);renderWindow->AddRenderer(binaryRenderer);QVTKOpenGLNativeWidget w;w.resize(640,320);w.setRenderWindow(renderWindow);w.setWindowTitle("ImageBinaryExample");w.show();return a.exec();
}

 运行效果:

        vtkImageThreshold 类还有另外两种阈值处理方式:ThresholdByLower()取小于 LowerThreshold的范围为有效范围;ThresholdBetween()取LowerThreshold和UpperThreshold 之间的部分为有效范围。如果 SetInValueO)和 SetOutValue0)不作设置,图像会按原图输出。 

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com