5.4.1 邊緣檢測—梯度運算元
影象中不連續的灰度值會產生邊緣,影象的邊緣檢測是基於邊界的影象分割方法,如分水嶺演算法,通常是分割原圖的梯度影象,梯度實際上也是反應的影象邊緣資訊。影象邊緣一般常用影象一階導數和二階導數來檢測。
梯度運算元對應於影象一階導數。影象一階導數計算一般是通過差分運算來近似的。VTK中可以使用vtkImageGradient計算影象梯度。注意影象梯度是一個向量,具有方向和大小。因此vtkImageGradient的計算結果是一個梯度場,也就是每個畫素值都是一個梯度向量。顯示梯度影象時需要計算每個畫素點的梯度大小,即模值。
下面程式碼如何利用VTK怎麼計算影象梯度:
//梯度運算元 #include"vtkSmartPointer.h" #include"vtkJPEGReader.h" #include"vtkImageGradient.h" #include"vtkImageMagnitude.h" #include"vtkImageData.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<vtkImageGradient> imgGradient = vtkSmartPointer<vtkImageGradient>::New();//vtkImageGradient計算影象梯度,是一個向量 imgGradient->SetInputConnection(reader->GetOutputPort()); imgGradient->SetDimensionality(2);//SetDimensionality用於要計算的影象的維數 vtkSmartPointer<vtkImageMagnitude> imgMagnitude = vtkSmartPointer<vtkImageMagnitude>::New();//imgMagnitude用於計算梯度向量的2範數(模),向量不能直接顯示 imgMagnitude->SetInputConnection(imgGradient->GetOutputPort()); imgMagnitude->Update(); double Range[2]; vtkSmartPointer<vtkImageData> getRange = vtkSmartPointer<vtkImageData>::New(); imgMagnitude->GetOutput()->GetScalarRange(Range);//影象灰度範圍最小值、最大值 vtkSmartPointer<vtkImageShiftScale> imgShiftScale = vtkSmartPointer<vtkImageShiftScale>::New();//vtkImageShiftScale調整影象的資料範圍為[0,255] imgShiftScale->SetOutputScalarTypeToUnsignedChar(); //強制型別轉換 0~255 imgShiftScale->SetScale(255 / Range[1]); //灰度對映間距 imgShiftScale->SetInputConnection(imgMagnitude->GetOutputPort()); imgShiftScale->Update(); ///////////////////////////////////////////////////////////////////////////////// vtkSmartPointer<vtkImageActor> origActor = vtkSmartPointer<vtkImageActor>::New(); origActor->SetInputData(reader->GetOutput()); vtkSmartPointer<vtkImageActor> GradientActor = vtkSmartPointer<vtkImageActor>::New(); GradientActor->SetInputData(imgShiftScale->GetOutput()); //////////////////////////////////////////////////////////////////////////////////// double origView[4] = { 0, 0, 0.5, 1 }; double gradientView[4] = { 0.5, 0, 1, 1 }; vtkSmartPointer<vtkRenderer> origRender = vtkSmartPointer<vtkRenderer>::New(); origRender->SetViewport(origView); origRender->AddActor(origActor); origRender->ResetCamera(); origRender->SetBackground(1.0, 1, 1); vtkSmartPointer<vtkRenderer> gradientRender = vtkSmartPointer<vtkRenderer>::New(); gradientRender->SetViewport(gradientView); gradientRender->AddActor(GradientActor); gradientRender->ResetCamera(); gradientRender->SetBackground(1, 1, 1); //////////////////////////////////////////////////////////////////////////////////////// vtkSmartPointer<vtkRenderWindow> rw = vtkSmartPointer<vtkRenderWindow>::New(); rw->AddRenderer(origRender); rw->AddRenderer(gradientRender); rw->SetSize(640, 320); rw->SetWindowName("Image Gradient"); vtkSmartPointer<vtkRenderWindowInteractor> rwi = vtkSmartPointer<vtkRenderWindowInteractor>::New(); vtkSmartPointer<vtkInteractorStyleImage> style = vtkSmartPointer<vtkInteractorStyleImage>::New(); rwi->SetRenderWindow(rw); rwi->SetInteractorStyle(style); rwi->Initialize(); rwi->Start(); return 0; }
執行結果如圖所示:
vtkImageGradient的使用比較簡單,只需要設定輸入影象即可。
計算梯度時,採用的是中間差分法,即畫素在每個方向的差分,都是利用的前後兩個畫素值之差。這樣在影象在邊界處的差分計算需要特殊處理。其內部定義了HandleBoundaries變數,通過函式SetHandleBoundaries()定賦值。當HandleBoundaries為真時運算元會特殊處理計算邊界畫素的梯度;當為假時不計算邊界畫素的梯度值,因此輸出影象大小要小於輸入影象。
另外函式SetDimensionality()用於設定要計算的影象維數,預設為二維,此時梯度向量也為二維。
前面也提到過,梯度是一個向量,不能直接顯示。
因此上面程式碼中定義了vtkImageMagnitude物件來計算梯度向量的2範數,即向量的模。
利用vtkImageShiftScale將影象的資料範圍調整到0-255然後顯示。
另外還可以通過vtkImageExtractComponents來提取每個方向的梯度分量進行顯示。
注意,彩色影象不能直接用來計算梯度,需要先轉換為灰度影象。
參考資料:
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