1.理想高通滤波器
高通滤波与低通滤波正好相反,是频域图像的高频部分通过而抑制低频部分。在图像中图像的边缘对应高频分量,因此高通滤波的效果是图像锐化。同样最简单的高通滤波器是理想高通滤波器。通过设置一个频率阈值,将高于该阈值的频率部分通过,而低于阈值的低频部分设置为0。
VTK中理想高通滤波的实例如下:
1 #include <vtkAutoInit.h> 2 VTK_MODULE_INIT(vtkRenderingOpenGL); 3 4 #include <vtkSmartPointer.h> 5 #include <vtkJPEGReader.h> 6 #include <vtkImageFFT.h> 7 #include <vtkImageIdealHighPass.h> 8 #include <vtkImageRFFT.h> 9 #include <vtkImageCast.h> 10 #include <vtkImageExtractComponents.h> 11 #include <vtkRenderer.h> 12 #include <vtkImageActor.h> 13 #include <vtkRenderWindow.h> 14 #include <vtkRenderWindowInteractor.h> 15 #include <vtkInteractorStyleImage.h> 16 17 int main(int argc, char* argv[]) 18 { 19 vtkSmartPointer<vtkJPEGReader> reader = 20 vtkSmartPointer<vtkJPEGReader>::New(); 21 reader->SetFileName("lena.jpg"); 22 reader->Update(); 23 24 vtkSmartPointer<vtkImageFFT> fftFilter = 25 vtkSmartPointer<vtkImageFFT>::New(); 26 fftFilter->SetInputConnection(reader->GetOutputPort()); 27 fftFilter->Update(); 28 29 vtkSmartPointer<vtkImageIdealHighPass> highPassFilter = 30 vtkSmartPointer<vtkImageIdealHighPass>::New(); 31 highPassFilter->SetInputConnection(fftFilter->GetOutputPort()); 32 highPassFilter->SetXCutOff(0.1); 33 highPassFilter->SetYCutOff(0.1); 34 highPassFilter->Update(); 35 36 vtkSmartPointer<vtkImageRFFT> rfftFilter = 37 vtkSmartPointer<vtkImageRFFT>::New(); 38 rfftFilter->SetInputConnection(highPassFilter->GetOutputPort()); 39 rfftFilter->Update(); 40 41 vtkSmartPointer<vtkImageExtractComponents> ifftExtractReal = 42 vtkSmartPointer<vtkImageExtractComponents>::New(); 43 ifftExtractReal->SetInputConnection(rfftFilter->GetOutputPort()); 44 ifftExtractReal->SetComponents(0); 45 46 vtkSmartPointer<vtkImageCast> castFilter = 47 vtkSmartPointer<vtkImageCast>::New(); 48 castFilter->SetInputConnection(ifftExtractReal->GetOutputPort()); 49 castFilter->SetOutputScalarTypeToUnsignedChar(); 50 castFilter->Update(); 51 / 52 vtkSmartPointer<vtkImageActor> originalActor = 53 vtkSmartPointer<vtkImageActor>::New(); 54 originalActor->SetInputData(reader->GetOutput()); 55 56 vtkSmartPointer<vtkImageActor> erodedActor = 57 vtkSmartPointer<vtkImageActor>::New(); 58 erodedActor->SetInputData(castFilter->GetOutput()); 59 / 60 double leftViewport[4] = { 0.0, 0.0, 0.5, 1.0 }; 61 double rightViewport[4] = { 0.5, 0.0, 1.0, 1.0 }; 62 vtkSmartPointer<vtkRenderer> leftRenderer = 63 vtkSmartPointer<vtkRenderer>::New(); 64 leftRenderer->AddActor(originalActor); 65 leftRenderer->SetViewport(leftViewport); 66 leftRenderer->SetBackground(1.0, 1.0, 1.0); 67 leftRenderer->ResetCamera(); 68 vtkSmartPointer<vtkRenderer> rightRenderer = 69 vtkSmartPointer<vtkRenderer>::New(); 70 rightRenderer->AddActor(erodedActor); 71 rightRenderer->SetViewport(rightViewport); 72 rightRenderer->SetBackground(1.0, 1.0, 1.0); 73 rightRenderer->ResetCamera(); 74 / 75 vtkSmartPointer<vtkRenderWindow> rw = 76 vtkSmartPointer<vtkRenderWindow>::New(); 77 rw->SetSize(640, 320); 78 rw->AddRenderer(leftRenderer); 79 rw->AddRenderer(rightRenderer); 80 rw->SetWindowName("IdealHighPassExample"); 81 82 vtkSmartPointer<vtkRenderWindowInteractor> rwi = 83 vtkSmartPointer<vtkRenderWindowInteractor>::New(); 84 vtkSmartPointer<vtkInteractorStyleImage> style = 85 vtkSmartPointer<vtkInteractorStyleImage>::New(); 86 rwi->SetInteractorStyle(style); 87 rwi->SetRenderWindow(rw); 88 rwi->Start(); 89 90 return 0; 91 }
同低通滤波一样,首先将读入图像通过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对图像进行高通滤波:
1 #include <vtkAutoInit.h> 2 VTK_MODULE_INIT(vtkRenderingOpenGL); 3 4 #include <vtkSmartPointer.h> 5 #include <vtkJPEGReader.h> 6 #include <vtkImageFFT.h> 7 #include <vtkImageButterworthHighPass.h> 8 #include <vtkImageRFFT.h> 9 #include <vtkImageExtractComponents.h> 10 #include <vtkImageCast.h> 11 #include <vtkRenderer.h> 12 #include <vtkImageActor.h> 13 #include <vtkRenderWindow.h> 14 #include <vtkRenderWindowInteractor.h> 15 #include <vtkInteractorStyleImage.h> 16 17 int main(int argc, char* argv[]) 18 { 19 vtkSmartPointer<vtkJPEGReader> reader = 20 vtkSmartPointer<vtkJPEGReader>::New(); 21 reader->SetFileName("lena.jpg"); 22 reader->Update(); 23 24 vtkSmartPointer<vtkImageFFT> fftFilter = 25 vtkSmartPointer<vtkImageFFT>::New(); 26 fftFilter->SetInputConnection(reader->GetOutputPort()); 27 fftFilter->Update(); 28 29 vtkSmartPointer<vtkImageButterworthHighPass> highPassFilter = 30 vtkSmartPointer<vtkImageButterworthHighPass>::New(); 31 highPassFilter->SetInputConnection(fftFilter->GetOutputPort()); 32 highPassFilter->SetXCutOff(0.1); 33 highPassFilter->SetYCutOff(0.1); 34 highPassFilter->Update(); 35 36 vtkSmartPointer<vtkImageRFFT> rfftFilter = 37 vtkSmartPointer<vtkImageRFFT>::New(); 38 rfftFilter->SetInputConnection(highPassFilter->GetOutputPort()); 39 rfftFilter->Update(); 40 41 vtkSmartPointer<vtkImageExtractComponents> ifftExtractReal = 42 vtkSmartPointer<vtkImageExtractComponents>::New(); 43 ifftExtractReal->SetInputConnection(rfftFilter->GetOutputPort()); 44 ifftExtractReal->SetComponents(0); 45 46 vtkSmartPointer<vtkImageCast> castFilter = 47 vtkSmartPointer<vtkImageCast>::New(); 48 castFilter->SetInputConnection(ifftExtractReal->GetOutputPort()); 49 castFilter->SetOutputScalarTypeToUnsignedChar(); 50 castFilter->Update(); 51 52 vtkSmartPointer<vtkImageActor> originalActor = 53 vtkSmartPointer<vtkImageActor>::New(); 54 originalActor->SetInputData(reader->GetOutput()); 55 56 vtkSmartPointer<vtkImageActor> erodedActor = 57 vtkSmartPointer<vtkImageActor>::New(); 58 erodedActor->SetInputData(castFilter->GetOutput()); 59 // 60 double leftViewport[4] = { 0.0, 0.0, 0.5, 1.0 }; 61 double rightViewport[4] = { 0.5, 0.0, 1.0, 1.0 }; 62 vtkSmartPointer<vtkRenderer> leftRenderer = 63 vtkSmartPointer<vtkRenderer>::New(); 64 leftRenderer->AddActor(originalActor); 65 leftRenderer->ResetCamera(); 66 leftRenderer->SetViewport(leftViewport); 67 leftRenderer->SetBackground(1.0, 1.0, 1.0); 68 69 vtkSmartPointer<vtkRenderer> rightRenderer = 70 vtkSmartPointer<vtkRenderer>::New(); 71 rightRenderer->AddActor(erodedActor); 72 rightRenderer->SetViewport(rightViewport); 73 rightRenderer->SetBackground(1.0, 1.0, 1.0); 74 rightRenderer->ResetCamera(); 75 76 vtkSmartPointer<vtkRenderWindow> rw = 77 vtkSmartPointer<vtkRenderWindow>::New(); 78 rw->AddRenderer(leftRenderer); 79 rw->AddRenderer(rightRenderer); 80 rw->SetSize(640, 320); 81 rw->Render(); 82 rw->SetWindowName("Frequency_ButterworthHighPass"); 83 / 84 vtkSmartPointer<vtkRenderWindowInteractor> rwi = 85 vtkSmartPointer<vtkRenderWindowInteractor>::New(); 86 vtkSmartPointer<vtkInteractorStyleImage> style = 87 vtkSmartPointer<vtkInteractorStyleImage>::New(); 88 rwi->SetInteractorStyle(style); 89 rwi->SetRenderWindow(rw); 90 rwi->Start(); 91 92 return 0; 93 }
vtkImageButterworthHighPass与理想高通滤波使用方法一致。需要设置X和Y轴的截止频率,为了便于比较,其截止频域与理想高通滤波设置一致。下图是执行结果: