VTK修炼之道42:频域处理_高通滤波(理想+巴特沃兹)

来源:互联网 发布:大数据分析spark 编辑:程序博客网 时间:2024/06/07 03:11

1.理想高通滤波器

高通滤波与低通滤波正好相反,是频域图像的高频部分通过而抑制低频部分。在图像中图像的边缘对应高频分量,因此高通滤波的效果是图像锐化。同样最简单的高通滤波器是理想高通滤波器。通过设置一个频率阈值,将高于该阈值的频率部分通过,而低于阈值的低频部分设置为0。

VTK中理想高通滤波的实例如下:

#include <vtkAutoInit.h>VTK_MODULE_INIT(vtkRenderingOpenGL);#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(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<vtkImageIdealHighPass> highPassFilter =vtkSmartPointer<vtkImageIdealHighPass>::New();highPassFilter->SetInputConnection(fftFilter->GetOutputPort());highPassFilter->SetXCutOff(0.1);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 <vtkAutoInit.h>VTK_MODULE_INIT(vtkRenderingOpenGL);#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);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->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轴的截止频率,为了便于比较,其截止频域与理想高通滤波设置一致。

下图是执行结果:

3.参看资料

1.《C++ primer》
2.《The VTK User’s Guide – 11thEdition》
3.  张晓东, 罗火灵. VTK图形图像开发进阶[M]. 机械工业出版社, 2015.


0 0
原创粉丝点击