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之间。计算结果如下图所示: