VTK修炼之道36:图像平滑_均值滤波器
生活随笔
收集整理的這篇文章主要介紹了
VTK修炼之道36:图像平滑_均值滤波器
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
1.圖像平滑
圖像平滑常用于圖像的預處理中,如計算梯度時先對圖像進行平滑處理,可以減少噪聲對梯度的影響。圖像平滑一般是通過模板卷積運算實現。模板可以看做是一個大小為nxn的小圖像,例如3x3,5x5等等,模板的每個像素都對應一個系數值。模板卷積運算的過程是首先將模板中心依次與圖像每個像素重合,通過模板各個系數與圖像對應像素相乘來計算模板對應像素的加權平均值,最后將運算結果賦給圖像中模板中心對應的像素。
2.均值濾波
均值濾波是一種經常用到的平滑方法,其對應的模板各個像素的值為1。在VTK中沒有直接實現均值濾波的類,但是我們可以通過圖像卷積運算來實現。卷積運算通過vtkImageConvolve類實現。通過vtkImageConvolve類,只需要設置相應的卷積模板,便可以實現多種空域圖像濾波。
下面代碼說明了怎樣使用vtkImageConvolve類來實現圖像的均值濾波:
#include <vtkAutoInit.h> VTK_MODULE_INIT(vtkRenderingOpenGL);#include <vtkSmartPointer.h> #include <vtkJPEGReader.h> #include <vtkImageCast.h> //圖像數據類型轉換為計算類型 #include <vtkImageData.h> #include <vtkImageConvolve.h> //圖像卷積運行 #include <vtkImageShiftScale.h> //設置像素值范圍 //#include <vtkImageMandelbrotSource.h> #include <vtkImageActor.h> #include <vtkRenderer.h> #include <vtkImageMandelbrotSource.h> #include <vtkRenderWindow.h> #include <vtkRenderWindowInteractor.h> #include <vtkInteractorStyleImage.h>int main() {vtkSmartPointer<vtkJPEGReader> reader =vtkSmartPointer<vtkJPEGReader>::New();reader->SetFileName("lena.jpg");reader->Update();vtkSmartPointer<vtkImageCast> originalCastFilter =vtkSmartPointer<vtkImageCast>::New();originalCastFilter->SetInputConnection(reader->GetOutputPort()); //建管線originalCastFilter->SetOutputScalarTypeToFloat(); //設置屬性originalCastFilter->Update();vtkSmartPointer<vtkImageConvolve> convolveFilter =vtkSmartPointer<vtkImageConvolve>::New();convolveFilter->SetInputConnection(originalCastFilter->GetOutputPort()); //建管線double kernel[25] = { 0.04, 0.04, 0.04, 0.04, 0.04,0.04, 0.04, 0.04, 0.04, 0.04,0.04, 0.04, 0.04, 0.04, 0.04,0.04, 0.04, 0.04, 0.04, 0.04,0.04, 0.04, 0.04, 0.04, 0.04 };convolveFilter->SetKernel5x5(kernel);convolveFilter->Update();vtkSmartPointer<vtkImageCast> convCastFilter =vtkSmartPointer<vtkImageCast>::New();convCastFilter->SetInputData(convolveFilter->GetOutput());convCastFilter->SetOutputScalarTypeToUnsignedChar(); //轉換為圖像數據convCastFilter->Update();///vtkSmartPointer<vtkImageActor> originalActor =vtkSmartPointer<vtkImageActor>::New();originalActor->SetInputData(reader->GetOutput());vtkSmartPointer<vtkImageActor> convolvedActor =vtkSmartPointer<vtkImageActor>::New();convolvedActor->SetInputData(convCastFilter->GetOutput());double leftViewport[4] = { 0.0, 0.0, 0.5, 1.0 };double rightViewport[4] = { 0.5, 0.0, 1.0, 1.0 };vtkSmartPointer<vtkRenderer> originalRenderer =vtkSmartPointer<vtkRenderer>::New();originalRenderer->SetViewport(leftViewport);originalRenderer->AddActor(originalActor);originalRenderer->SetBackground(1.0, 1.0, 1.0);originalRenderer->ResetCamera();vtkSmartPointer<vtkRenderer> convolvedRenderer =vtkSmartPointer<vtkRenderer>::New();convolvedRenderer->SetViewport(rightViewport);convolvedRenderer->AddActor(convolvedActor);convolvedRenderer->SetBackground(1.0, 1.0, 1.0);convolvedRenderer->ResetCamera();vtkSmartPointer<vtkRenderWindow> rw =vtkSmartPointer<vtkRenderWindow>::New();;rw->AddRenderer(originalRenderer);rw->AddRenderer(convolvedRenderer);rw->SetSize(640, 320);rw->Render();rw->SetWindowName("Smooth by MeanFilter");vtkSmartPointer<vtkRenderWindowInteractor> rwi =vtkSmartPointer<vtkRenderWindowInteractor>::New();vtkSmartPointer<vtkInteractorStyleImage> style =vtkSmartPointer<vtkInteractorStyleImage>::New();rwi->SetInteractorStyle(style);rwi->SetRenderWindow(rw);rwi->Initialize();rwi->Start();return 0; }
首先vtkJPEGReader對象讀取一幅圖像。考慮到進行卷積運算時數據范圍的變化和精度要求,需要先將圖像像素數據類型由unsigned char轉換到float類型,該變換通過vtkImageCast實現,對應的設置函數SetOutputScalarTypeToFloat()。接下來需要定義卷積算子和卷積模板。vtkImageConvolve類實現圖像的卷積運算,它需要兩個輸入。一個是需要進行卷積的圖像,這里為vtkJPEGReader讀取的圖像數據,第二個是卷積模板數組。SetKernel5x5()函數接收一個5x5的卷積模板數組,即本例上定義的kernel數組。執行Update()后即可完成卷積運算。需要注意的是,卷積模板對應的系數之和應該為1,否則需要對計算結果進行歸一化處理。另外該類中還定義了3x3和7x7的卷積模板設置函數,使用過程是一樣的。卷積完成以后,再次通過vtkImageCast將float數據類型轉換為unsigned char進行圖像顯示。
均值濾波的結果如下:
2.參看資料
1.《C++ primer》
2.《The VTK User’s Guide – 11thEdition》
3. ?張曉東, 羅火靈. VTK圖形圖像開發進階[M]. 機械工業出版社, 2015.
總結
以上是生活随笔為你收集整理的VTK修炼之道36:图像平滑_均值滤波器的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 《飞鸽传书2007怎么用》这种即时通讯技
- 下一篇: VTK修炼之道37:图像平滑_高斯滤波器