1.前言
前面演示的例子都是在一个窗口中显示一个图像。但是在常见的图像处理软件中,经常会遇到在一个窗口中显示多个图像,这就会用到图像融合技术。图像融合利用图像的alpha通道和不透明度来实现。VTK中vtkImageBlend实现图像的融合。
vtkImageBlend可以接收多个图像输入,输出为融合图像。输出图像的像素间隔、原点、范围(extent)以及像素组分个数与第一个图像一致。该类提供了两种融合模式,默认的融合方式是标准模式。
第二种是混合模式(Compound)。该模式下输出结果经过alpha/opacity不透明度的和做过归一化。另外还可以设置一个阈值,当alpha*opacity小于等于该阈值时会忽略该像素。
2.实验代码和结果
1 #include <vtkAutoInit.h> 2 VTK_MODULE_INIT(vtkRenderingOpenGL); 3 4 #include <vtkSmartPointer.h> 5 #include <vtkJPEGReader.h> 6 //#include <vtkImageCast.h> 7 #include <vtkImageData.h> 8 #include <vtkImageCanvasSource2D.h> 9 #include <vtkImageBlend.h> 10 #include <vtkImageActor.h> 11 #include <vtkRenderer.h> 12 #include <vtkRenderWindow.h> 13 #include <vtkRenderWindowInteractor.h> 14 #include <vtkInteractorStyleImage.h> 15 16 int main() 17 { 18 //数据管线 19 vtkSmartPointer<vtkJPEGReader> reader = 20 vtkSmartPointer<vtkJPEGReader>::New(); 21 reader->SetFileName("data/lena-gray.jpg"); 22 reader->Update(); 23 24 vtkSmartPointer<vtkImageCanvasSource2D> source= 25 vtkSmartPointer<vtkImageCanvasSource2D>::New(); 26 source->SetNumberOfScalarComponents(1); 27 source->SetScalarTypeToUnsignedChar(); 28 source->SetExtent(0,512,0,512,0,0); 29 source->SetDrawColor(0,0,0); 30 source->FillBox(0,512,0,512); 31 source->SetDrawColor(255,255,255); 32 source->FillBox(100,400,100,400); 33 source->Update(); 34 35 vtkSmartPointer<vtkImageBlend> blend = 36 vtkSmartPointer<vtkImageBlend>::New(); 37 blend->SetInputData(0,reader->GetOutput()); 38 blend->SetInputData(1,source->GetOutput()); 39 blend->SetOpacity(0,0.4); 40 blend->SetOpacity(1,0.6); 41 blend->Update(); 42 43 //渲染引擎 44 vtkSmartPointer<vtkImageActor> actor1 = 45 vtkSmartPointer<vtkImageActor>::New(); 46 actor1->SetInputData(reader->GetOutput()); 47 48 vtkSmartPointer<vtkImageActor> actor2 = 49 vtkSmartPointer<vtkImageActor>::New(); 50 actor2->SetInputData(source->GetOutput()); 51 52 vtkSmartPointer<vtkImageActor> blend_actor = 53 vtkSmartPointer<vtkImageActor>::New(); 54 blend_actor->SetInputData(blend->GetOutput()); 55 //定义视窗大小(xmin.ymin,xmax,ymax) 56 //按window的尺寸进行比例分割 57 double leftViewport [4] = {0,0,0.33,1}; 58 double midViewport [4] = {0.33,0,0.66,1}; 59 double rightViewport[4] = {0.66,0,1,1}; 60 //render 61 vtkSmartPointer<vtkRenderer> render1 = 62 vtkSmartPointer<vtkRenderer>::New(); 63 render1->SetViewport(leftViewport); 64 render1->AddActor(actor1); 65 render1->ResetCamera(); 66 render1->SetBackground(1,0,0); 67 68 vtkSmartPointer<vtkRenderer> render2 = 69 vtkSmartPointer<vtkRenderer>::New(); 70 render2->SetViewport(midViewport); 71 render2->AddActor(actor2); 72 render2->ResetCamera(); 73 render2->SetBackground(0,1,0); 74 75 vtkSmartPointer<vtkRenderer> render3 = 76 vtkSmartPointer<vtkRenderer>::New(); 77 render3->SetViewport(rightViewport); 78 render3->AddActor(blend_actor); 79 render3->ResetCamera(); 80 render3->SetBackground(0,0,1); 81 //window 82 vtkSmartPointer<vtkRenderWindow> renderwindow = 83 vtkSmartPointer<vtkRenderWindow>::New(); 84 renderwindow->AddRenderer(render1); 85 renderwindow->AddRenderer(render2); 86 renderwindow->AddRenderer(render3); 87 renderwindow->SetSize(640,320); 88 renderwindow->SetWindowName("Image-Fusion"); 89 renderwindow->Render(); 90 //interactor 91 vtkSmartPointer<vtkRenderWindowInteractor> rwi = 92 vtkSmartPointer<vtkRenderWindowInteractor>::New(); 93 vtkSmartPointer<vtkInteractorStyleImage> style = 94 vtkSmartPointer<vtkInteractorStyleImage>::New(); 95 rwi->SetInteractorStyle(style); 96 rwi->SetRenderWindow(renderwindow); 97 rwi->Initialize(); 98 rwi->Start(); 99 100 return 0; 101 }
代码中读入了一副灰度图像,并生成了一个二值图像;然后定义了vtkImageBlend对象,函数SetInput()设置两个图像作为输入。这里设置输入图像时,由于可以输入多个图像,因此需要给定图像的id号来设置输入。SetOpacity()用于设置对应id号的图像不透明度的大小,当不透明度为1.0时,为完全不透明。