5.6.3 高通濾波(理想高通濾波+巴特沃斯高通濾波)
1.理想高通濾波器
高通濾波與低通濾波正好相反,是頻域影象的高頻部分通過而抑制低頻部分。在影象中影象的邊緣對應高頻分量,因此高通濾波的效果是影象銳化。同樣最簡單的高通濾波器是理想高通濾波器。通過設定一個頻率閾值,將高於該閾值的頻率部分通過,而低於閾值的低頻部分設定為0。
VTK中理想高通濾波的例項如下:
/* ******理想高通濾波********** */ #include <vtkSmartPointer.h> #include <vtkJPEGReader.h> #include <vtkImageFFT.h> #include <vtkImageIdealHighPass.h> #include <vtkImageRFFT.h> #include <vtkImageCast.h> #include <vtkImageExtractComponents.h> #include <vtkRenderer.h> #include <vtkImageActor.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<vtkImageFFT> fftFilter = vtkSmartPointer<vtkImageFFT>::New();//將影象域轉換到頻域空間 fftFilter->SetInputConnection(reader->GetOutputPort()); fftFilter->Update(); vtkSmartPointer<vtkImageIdealHighPass> highPassFilter = vtkSmartPointer<vtkImageIdealHighPass>::New(); highPassFilter->SetInputConnection(fftFilter->GetOutputPort());//定義影象高通濾波物件 highPassFilter->SetXCutOff(0.1);//設定X和Y方向的截止頻率 highPassFilter->SetYCutOff(0.1); highPassFilter->Update(); vtkSmartPointer<vtkImageRFFT> rfftFilter = vtkSmartPointer<vtkImageRFFT>::New();//將處理後的影象轉換到空域中 rfftFilter->SetInputConnection(highPassFilter->GetOutputPort()); rfftFilter->Update(); vtkSmartPointer<vtkImageExtractComponents> ifftExtractReal = vtkSmartPointer<vtkImageExtractComponents>::New(); ifftExtractReal->SetInputConnection(rfftFilter->GetOutputPort()); ifftExtractReal->SetComponents(0);//提取實部分量 vtkSmartPointer<vtkImageCast> castFilter = vtkSmartPointer<vtkImageCast>::New();//資料型別轉換 castFilter->SetInputConnection(ifftExtractReal->GetOutputPort()); castFilter->SetOutputScalarTypeToUnsignedChar(); castFilter->Update(); ///////////////////////////////////////////////////////// vtkSmartPointer<vtkImageActor> originalActor = vtkSmartPointer<vtkImageActor>::New(); originalActor->SetInputData(reader->GetOutput()); vtkSmartPointer<vtkImageActor> erodedActor = vtkSmartPointer<vtkImageActor>::New(); erodedActor->SetInputData(castFilter->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> leftRenderer = vtkSmartPointer<vtkRenderer>::New(); leftRenderer->AddActor(originalActor); leftRenderer->SetViewport(leftViewport); leftRenderer->SetBackground(1.0, 1.0, 1.0); leftRenderer->ResetCamera(); vtkSmartPointer<vtkRenderer> rightRenderer = vtkSmartPointer<vtkRenderer>::New(); rightRenderer->AddActor(erodedActor); rightRenderer->SetViewport(rightViewport); rightRenderer->SetBackground(1.0, 1.0, 1.0); rightRenderer->ResetCamera(); ///////////////// vtkSmartPointer<vtkRenderWindow> rw = vtkSmartPointer<vtkRenderWindow>::New(); rw->SetSize(640, 320); rw->AddRenderer(leftRenderer); rw->AddRenderer(rightRenderer); rw->SetWindowName("IdealHighPassExample"); vtkSmartPointer<vtkRenderWindowInteractor> rwi = vtkSmartPointer<vtkRenderWindowInteractor>::New(); vtkSmartPointer<vtkInteractorStyleImage> style = vtkSmartPointer<vtkInteractorStyleImage>::New(); rwi->SetInteractorStyle(style); rwi->SetRenderWindow(rw); rwi->Start(); return 0; }
執行結果如下:
低通-濾波;高通-銳化(從結果看出高通濾波後圖像得到銳化處理,影象中僅剩下邊緣。)同低通濾波一樣,首先將讀入影象通過vtkImageFFT轉換到頻域空間,定義vtkImageIdealHighPass物件,並通過SetXCutOff ()和SetYCutOff() 設定X和Y方向的截止頻率。然後通過vtkImageRFFT將處理後的影象轉換到空域中,得到高通濾波影象。為了顯示的需要,還需要提取影象分量和資料型別的轉換。
2.巴特沃茲高通濾波
理想高通濾波器不能通過電子元器件來實現,而且存在振鈴現象。在實際中最常使用的高通濾波器是巴特沃斯高通濾波器。該濾波器的轉移函式是:
D(u,v)表示頻域中點到頻域平面的距離,是截止頻率。當D(u,v)大於時,對應的H(u,v)逐漸接近1,從而使得高頻部分得以通過;而當D(u,v)小於時,H(u,v)逐漸接近0,實現低頻部分過濾。巴特沃斯高通濾波器在VTK中對應vtkImageButterworthHighPass類。
下面程式碼說明了vtkImageButterworthHighPass對影象進行高通濾波:
/*******************巴特沃特高斯高通濾波***********************************/
#include <vtkSmartPointer.h>
#include <vtkJPEGReader.h>
#include <vtkImageFFT.h>
#include <vtkImageButterworthHighPass.h>
#include <vtkImageRFFT.h>
#include <vtkImageExtractComponents.h>
#include <vtkImageCast.h>
#include <vtkRenderer.h>
#include <vtkImageActor.h>
#include <vtkRenderWindow.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkInteractorStyleImage.h>
int main(int argc, char* argv[])
{
vtkSmartPointer<vtkJPEGReader> reader = vtkSmartPointer<vtkJPEGReader>::New();
reader->SetFileName("lena.jpg");
reader->Update();
vtkSmartPointer<vtkImageFFT> fftFilter = vtkSmartPointer<vtkImageFFT>::New();
fftFilter->SetInputConnection(reader->GetOutputPort());
fftFilter->Update();
vtkSmartPointer<vtkImageButterworthHighPass> highPassFilter = vtkSmartPointer<vtkImageButterworthHighPass>::New();
highPassFilter->SetInputConnection(fftFilter->GetOutputPort());
highPassFilter->SetXCutOff(0.1);
highPassFilter->SetYCutOff(0.1);//x\y軸的截止頻率
highPassFilter->Update();
vtkSmartPointer<vtkImageRFFT> rfftFilter = vtkSmartPointer<vtkImageRFFT>::New();// 轉換回空域中
rfftFilter->SetInputConnection(highPassFilter->GetOutputPort());
rfftFilter->Update();
vtkSmartPointer<vtkImageExtractComponents> ifftExtractReal = vtkSmartPointer<vtkImageExtractComponents>::New();
ifftExtractReal->SetInputConnection(rfftFilter->GetOutputPort());
ifftExtractReal->SetComponents(0);//提取複數中的實部
vtkSmartPointer<vtkImageCast> castFilter = vtkSmartPointer<vtkImageCast>::New();//資料轉換為unsigned char型別
castFilter->SetInputConnection(ifftExtractReal->GetOutputPort());
castFilter->SetOutputScalarTypeToUnsignedChar();
castFilter->Update();
////////////////////////////////////////////////////////////////////
vtkSmartPointer<vtkImageActor> originalActor = vtkSmartPointer<vtkImageActor>::New();
originalActor->SetInputData(reader->GetOutput());
vtkSmartPointer<vtkImageActor> erodedActor = vtkSmartPointer<vtkImageActor>::New();
erodedActor->SetInputData(castFilter->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> leftRenderer = vtkSmartPointer<vtkRenderer>::New();
leftRenderer->AddActor(originalActor);
leftRenderer->ResetCamera();
leftRenderer->SetViewport(leftViewport);
leftRenderer->SetBackground(1.0, 1.0, 1.0);
vtkSmartPointer<vtkRenderer> rightRenderer = vtkSmartPointer<vtkRenderer>::New();
rightRenderer->AddActor(erodedActor);
rightRenderer->SetViewport(rightViewport);
rightRenderer->SetBackground(1.0, 1.0, 1.0);
rightRenderer->ResetCamera();
////////////////////////
vtkSmartPointer<vtkRenderWindow> rw = vtkSmartPointer<vtkRenderWindow>::New();
rw->AddRenderer(leftRenderer);
rw->AddRenderer(rightRenderer);
rw->SetSize(640, 320);
rw->Render();
rw->SetWindowName("Frequency_ButterworthHighPass");
/////////////////////
vtkSmartPointer<vtkRenderWindowInteractor> rwi = vtkSmartPointer<vtkRenderWindowInteractor>::New();
vtkSmartPointer<vtkInteractorStyleImage> style = vtkSmartPointer<vtkInteractorStyleImage>::New();
rwi->SetInteractorStyle(style);
rwi->SetRenderWindow(rw);
rwi->Start();
return 0;
}
執行結果如下:
解釋說明:vtkImageButterworthHighPass與理想高通濾波使用方法一致。需要設定X和Y軸的截止頻率,為了便於比較,其截止頻域與理想高通濾波設定一致。
參考資料:
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