一杯清酒邀明月
天下本无事,庸人扰之而烦耳。

1.拉普拉斯算子

拉普拉斯算子是一个二阶边缘算子,即梯度的散度。拉普拉斯算子的实现也是通过模板实现。常用的拉普拉斯模板定义如下:

拉普拉斯算子计算图像的二阶导数,对于图像噪声比较敏感。拉普拉斯算子的结果为标量,表示边缘的宽度。但是它常产生双像素宽边缘,而且不能提供方向信息,因此较少直接用于边缘检测。在VTK中由vtkImageLaplacian实现。

 1 #include <vtkAutoInit.h>
 2 VTK_MODULE_INIT(vtkRenderingOpenGL);
 3  
 4 #include <vtkSmartPointer.h>
 5 #include <vtkJPEGReader.h>
 6 #include <vtkImageData.h>
 7 #include <vtkImageLaplacian.h>
 8 #include <vtkImageShiftScale.h>
 9 #include <vtkImageActor.h>
10 #include <vtkRenderer.h>
11 #include <vtkRenderWindow.h>
12 #include <vtkRenderWindowInteractor.h>
13 #include <vtkInteractorStyleImage.h>
14  
15 int main(int argc, char* argv[])
16 {
17  
18     vtkSmartPointer<vtkJPEGReader> reader =
19         vtkSmartPointer<vtkJPEGReader>::New();
20     reader->SetFileName("lena.jpg");
21     reader->Update();
22  
23     vtkSmartPointer<vtkImageLaplacian> lapFilter =
24         vtkSmartPointer<vtkImageLaplacian>::New();
25     lapFilter->SetInputConnection(reader->GetOutputPort());
26     lapFilter->SetDimensionality(2);
27  
28     double range[2];
29     lapFilter->GetOutput()->GetScalarRange(range);
30  
31     vtkSmartPointer<vtkImageShiftScale> ShiftScale =
32         vtkSmartPointer<vtkImageShiftScale>::New();
33     ShiftScale->SetOutputScalarTypeToUnsignedChar();
34     ShiftScale->SetScale(255 / (range[1] - range[0]));
35     ShiftScale->SetShift(-range[0]);
36     ShiftScale->SetInputConnection(lapFilter->GetOutputPort());
37     ShiftScale->Update();
38  
39     vtkSmartPointer<vtkImageActor> originalActor =
40         vtkSmartPointer<vtkImageActor>::New();
41     originalActor->SetInputData(reader->GetOutput());
42  
43     vtkSmartPointer<vtkImageActor> gradActor =
44         vtkSmartPointer<vtkImageActor>::New();
45     gradActor->SetInputData(ShiftScale->GetOutput());
46  
47     double originalViewport[4] = { 0.0, 0.0, 0.5, 1.0 };
48     double gradviewport[4] = { 0.5, 0.0, 1.0, 1.0 };
49  
50     vtkSmartPointer<vtkRenderer> originalRenderer =
51         vtkSmartPointer<vtkRenderer>::New();
52     originalRenderer->SetViewport(originalViewport);
53     originalRenderer->AddActor(originalActor);
54     originalRenderer->ResetCamera();
55     originalRenderer->SetBackground(1.0, 1.0, 1.0);
56  
57     vtkSmartPointer<vtkRenderer> gradRenderer =
58         vtkSmartPointer<vtkRenderer>::New();
59     gradRenderer->SetViewport(gradviewport);
60     gradRenderer->AddActor(gradActor);
61     gradRenderer->ResetCamera();
62     gradRenderer->SetBackground(1.0, 1.0, 1.0);
63  
64     vtkSmartPointer<vtkRenderWindow> rw =
65         vtkSmartPointer<vtkRenderWindow>::New();
66     rw->AddRenderer(originalRenderer);
67     rw->AddRenderer(gradRenderer);
68     rw->SetSize(640, 320);
69     rw->Render();
70     rw->SetWindowName("Edge by Laplacian");
71  
72     vtkSmartPointer<vtkRenderWindowInteractor> rwi =
73         vtkSmartPointer<vtkRenderWindowInteractor>::New();
74     vtkSmartPointer<vtkInteractorStyleImage> style =
75         vtkSmartPointer<vtkInteractorStyleImage>::New();
76  
77     rwi->SetInteractorStyle(style);
78     rwi->SetRenderWindow(renderWindow);
79     rwi->Initialize();
80     rwi->Start();
81  
82     return 0;
83 }
tkImageLaplacian输入和输出数据都是vtkImageData,与梯度算子不同,该filter的输出图像像素为标量。函数SetDimensionality用于设置输入图像的维数,默认为2维。计算完毕后,利用vtkImageShiftScale将图像的数据范围变换至0-255之间。

计算结果如下图所示:

 

posted on 2021-01-06 15:36  一杯清酒邀明月  阅读(431)  评论(0编辑  收藏  举报