1. 程式人生 > >5.6.3 高通濾波(理想高通濾波+巴特沃斯高通濾波)

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