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時,為完全不透明。
