5.4.4 邊緣檢測-拉普拉斯運算元
阿新 • • 發佈:2018-11-24
拉普拉斯運算元是一個二階邊緣運算元,即梯度的散度。拉普拉斯運算元的實現也是通過模板實現。常用的拉普拉斯模板定義如下:
拉普拉斯運算元計算影象的二階導數,對於影象噪聲比較敏感。拉普拉斯運算元的結果為標量,表示邊緣的寬度。但是它常產生雙畫素寬邊緣,而且不能提供方向資訊,因此較少直接用於邊緣檢測。在VTK中由vtkImageLaplacian實現。
#include <vtkAutoInit.h> #include <vtkSmartPointer.h> #include <vtkJPEGReader.h> #include <vtkImageData.h> #include <vtkImageLaplacian.h> #include <vtkImageShiftScale.h> #include <vtkImageActor.h> #include <vtkRenderer.h> #include <vtkRenderWindow.h> #include <vtkRenderWindowInteractor.h> #include <vtkInteractorStyleImage.h> int main() { vtkSmartPointer<vtkJPEGReader> reader = vtkSmartPointer<vtkJPEGReader>::New(); reader->SetFileName("data\\lena-gray.jpg"); reader->Update(); vtkSmartPointer<vtkImageLaplacian> lapFilter = vtkSmartPointer<vtkImageLaplacian>::New(); lapFilter->SetInputConnection(reader->GetOutputPort()); lapFilter->SetDimensionality(2); double range[2]; lapFilter->GetOutput()->GetScalarRange(range); //得到灰度的最大值和最小值 vtkSmartPointer<vtkImageShiftScale> ShiftScale = vtkSmartPointer<vtkImageShiftScale>::New(); ShiftScale->SetOutputScalarTypeToUnsignedChar(); ShiftScale->SetScale(255 / (range[1] - range[0])); //SetShift()設定偏移量,SetScale()用於設定放縮值 ShiftScale->SetShift(-range[0]); ShiftScale->SetInputConnection(lapFilter->GetOutputPort()); ShiftScale->Update(); vtkSmartPointer<vtkImageActor> originalActor = vtkSmartPointer<vtkImageActor>::New(); originalActor->SetInputData(reader->GetOutput()); vtkSmartPointer<vtkImageActor> gradActor = vtkSmartPointer<vtkImageActor>::New(); gradActor->SetInputData(ShiftScale->GetOutput()); double originalViewport[4] = { 0.0, 0.0, 0.5, 1.0 }; double gradviewport[4] = { 0.5, 0.0, 1.0, 1.0 }; vtkSmartPointer<vtkRenderer> originalRenderer = vtkSmartPointer<vtkRenderer>::New(); originalRenderer->SetViewport(originalViewport); originalRenderer->AddActor(originalActor); originalRenderer->ResetCamera(); originalRenderer->SetBackground(1.0, 1.0, 1.0); vtkSmartPointer<vtkRenderer> gradRenderer = vtkSmartPointer<vtkRenderer>::New(); gradRenderer->SetViewport(gradviewport); gradRenderer->AddActor(gradActor); gradRenderer->ResetCamera(); gradRenderer->SetBackground(1.0, 1.0, 1.0); vtkSmartPointer<vtkRenderWindow> rw = vtkSmartPointer<vtkRenderWindow>::New(); rw->AddRenderer(originalRenderer); rw->AddRenderer(gradRenderer); rw->SetSize(540, 320); rw->Render(); rw->SetWindowName("Edge by Laplacian"); vtkSmartPointer<vtkRenderWindowInteractor> rwi = vtkSmartPointer<vtkRenderWindowInteractor>::New(); vtkSmartPointer<vtkInteractorStyleImage> style = vtkSmartPointer<vtkInteractorStyleImage>::New(); rwi->SetInteractorStyle(style); rwi->SetRenderWindow(rw); rwi->Initialize(); rwi->Start(); return 0; }
執行結果如下:
vtkImageLaplacian輸入和輸出資料都是vtkImageData,與梯度運算元不同,該filter的輸出影象畫素為標量。函式SetDimensionality用於設定輸入影象的維數,預設為2維。計算完畢後,利用vtkImageShiftScale將影象的資料範圍變換至0-255之間。
參考資料:
1.《The Visualization Toolkit – AnObject-Oriented Approach To 3D Graphics (4th Edition)》
2. 張曉東, 羅火靈. VTK圖形影象開發進階[M]. 機械工業出版社, 2015.
所用軟體:vtk7.0+visual studio 2013
注:此文知識學習筆記,僅記錄完整程式和實現結果,具體原理參見:
https://blog.csdn.net/www_doling_net/article/details/8541534
https://blog.csdn.net/shenziheng1/article/category/6114053/4