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时,为完全不透明。