【QT+VTK 学习笔记】12:VTK频域处理

前言 “VTK图形图像开发进阶_张晓东_罗火灵”的学习笔记 。
东灵工作室 教程系列导航:http://blog.csdn.net/www_doling_net/article/details/8763686
学习资料 VTK官网学习地址:https://vtk.org/doc/nightly/html/
图像的频域处理 频域处理是指根据一定的图像模型,对图像频谱进行不同程度修改的技术,通常作如下假设:
1.引起图像质量下降的噪声占频谱的高频段.
2.图像边缘占高频段
3.图像主体或灰度缓变区域占低频段.
基于这些假设,可以频谱的各个频段进行有选择性的修改 。
图像频域处理借助空间变换将图像从图像空间转换到频域空间 , 根据频域空间的性质对数据进行处理(如滤波) , 最后通过空间变换将处理后的数 据变换至图像空间 。
最常用的频域转换是傅里叶变换 。
快速傅里叶变换(FFT) FFT是可逆的 , 其逆变换为RFFTo 。FFT 在数字图像处理中有着广泛的应用 , 例如数字图像频域滤波、去噪、增强等 。目前 , 在VTK 中FFT和RFFT这两种变换都已经实现 , 对应的类分别为vtklmageFFT和vtklmageRFFT 。
vtklmageFFT和vtklmageRFFT的输入为实数或复数数据 , 输出均为复数数据 。因此 ,  vtklmageFFT与vtklmageRFFT的输出结果不能直接显示 , 因为VTK会将其当作彩色图像显 示 , 需要通过vtklmageExtractComponents类提取某一组分进行图像显示 。
#include #include VTK_MODULE_INIT(vtkRenderingOpenGL2)VTK_MODULE_INIT(vtkInteractionStyle)VTK_MODULE_INIT(vtkRenderingFreeType)#include #include #include #include #include #include #include #include #include #include #include #include #include #include #include //测试图像:../data/lena-gray.jpgint main(int argc, char* argv[]){vtkSmartPointer reader =vtkSmartPointer::New();reader->SetFileName ("C:/Users/jbyyy/Desktop/work/QTDEMO/jbyyy/VTK/学习资料/VTK图形图像开发进阶+张晓东+PDF+源码/VTK图形图像开发进阶随书代码/VTK图形图像开发进阶随书代码/Examples/Chap05/data/lena-gray.jpg");reader->Update();double range[2];reader->GetOutput()->GetScalarRange(range);float oldRange = range[1] - range[0];std::cout << "Old range: [" < fftFilter =vtkSmartPointer::New();fftFilter->SetInputConnection(reader->GetOutputPort());fftFilter->SetDimensionality(2);fftFilter->Update();//利用函数SetComponents(O)指定提取实部图像显示vtkSmartPointer fftExtractReal =vtkSmartPointer::New();fftExtractReal->SetInputConnection(fftFilter->GetOutputPort());fftExtractReal->SetComponents(0);fftExtractReal->GetOutput()->GetScalarRange(range);//数据转换 to unsigned charvtkSmartPointer ShiftScale =vtkSmartPointer::New();ShiftScale->SetOutputScalarTypeToUnsignedChar();ShiftScale->SetScale( 255.0 / (range[1]-range[0]) );ShiftScale->SetShift(-range[0]);ShiftScale->SetInputConnection(fftExtractReal->GetOutputPort());ShiftScale->Update();//完成快速傅里叶逆变换vtkSmartPointer rfftFilter =vtkSmartPointer::New();rfftFilter->SetInputConnection(fftFilter->GetOutputPort());rfftFilter->SetDimensionality(2);rfftFilter->Update();vtkSmartPointer ifftExtractReal =vtkSmartPointer::New();ifftExtractReal->SetInputConnection(rfftFilter->GetOutputPort());ifftExtractReal->SetComponents(0);vtkSmartPointerrfftCastFilter =vtkSmartPointer::New();rfftCastFilter->SetInputConnection(ifftExtractReal->GetOutputPort());rfftCastFilter->SetOutputScalarTypeToUnsignedChar();rfftCastFilter->Update(); //不知道为啥用这种方式转化数据 显示异常//vtkSmartPointer rfftCastFilter =//vtkSmartPointer::New();//rfftCastFilter->SetOutputScalarTypeToUnsignedChar();//rfftCastFilter->SetScale( 255.0 / (range[1]-range[0]) );//rfftCastFilter->SetShift(-range[0]);//rfftCastFilter->SetInputConnection(ifftExtractReal->GetOutputPort());//rfftCastFilter->Update();rfftCastFilter->GetOutput()->GetScalarRange(range);oldRange = range[1] - range[0];std::cout << "Old range: [" < originalActor =vtkSmartPointer::New();originalActor->SetInputData(reader->GetOutput());vtkSmartPointer fftActor =vtkSmartPointer::New();fftActor->SetInputData(ShiftScale->GetOutput());vtkSmartPointer rfftActor =vtkSmartPointer::New();rfftActor->SetInputData(rfftCastFilter->GetOutput());double originalViewport[4] = {0.0, 0.0, 0.33, 1.0};double fftViewport[4] = {0.33, 0.0, 0.66, 1.0};double rfftViewport[4] = {0.66, 0.0, 1.0, 1.0};vtkSmartPointer originalRenderer =vtkSmartPointer::New();originalRenderer->SetViewport(originalViewport);originalRenderer->AddActor(originalActor);originalRenderer->ResetCamera();originalRenderer->SetBackground(1.0, 1.0, 1.0);vtkSmartPointer fftRenderer =vtkSmartPointer::New();fftRenderer->SetViewport(fftViewport);fftRenderer->AddActor(fftActor);fftRenderer->ResetCamera();fftRenderer->SetBackground(1.0, 1.0, 1.0);vtkSmartPointer rfftRenderer =vtkSmartPointer::New();rfftRenderer->SetViewport(rfftViewport);rfftRenderer->AddActor(rfftActor);rfftRenderer->ResetCamera();rfftRenderer->SetBackground(1.0, 1.0, 1.0);vtkSmartPointer renderWindow =vtkSmartPointer::New();renderWindow->AddRenderer(originalRenderer);renderWindow->AddRenderer(fftRenderer);renderWindow->AddRenderer(rfftRenderer);renderWindow->SetSize(640, 320);renderWindow->Render();renderWindow->SetWindowName("FFTAndRFFTExample");vtkSmartPointer renderWindowInteractor =vtkSmartPointer::New();vtkSmartPointer style =vtkSmartPointer::New();renderWindowInteractor->SetInteractorStyle(style);renderWindowInteractor->SetRenderWindow(renderWindow);renderWindowInteractor->Initialize();renderWindowInteractor->Start();return EXIT_SUCCESS;} 低通滤波 标题理想低通滤波器 低通滤波是将频域图像中的高频部分滤除而保留低频部分 。图像的边缘和噪声对应于频域图像中的高频部分 , 而低通滤波的作用即是减弱这部分的能量 , 从而达到图像平滑去噪的目的 。最简单的低通滤波器是理想低通滤波器 , 其基本思想是给定一个频率阈值 , 将高于该阈值的所有部分设置为0,而低于该频率的部分保持不变 。

从结果看 , 在过滤掉图像的高频部分后 , 图像 变得模糊 , 丢失了许多细节 , 另外还可以看到理想低通滤波后图像会存在一定的振铃效应 ,  这也是理想低通滤波的特点 。
巴特沃斯低通滤波器 在实际应用中 , 经常使用的低通滤波器是巴特沃斯滤波器 。

从结果看 , 巴特沃斯低通滤波器产生的图像更为平滑 , 不会出现振铃现象 。
#include #include VTK_MODULE_INIT(vtkRenderingOpenGL2)VTK_MODULE_INIT(vtkInteractionStyle)VTK_MODULE_INIT(vtkRenderingFreeType)#include #include #include #include #include #include #include #include #include #include #include #include #include #include //测试图像:../data/lena-gray.jpgint main(int argc, char* argv[]){vtkSmartPointer reader =vtkSmartPointer::New();reader->SetFileName("C:/Users/jbyyy/Desktop/work/QTDEMO/jbyyy/VTK/学习资料/VTK图形图像开发进阶+张晓东+PDF+源码/VTK图形图像开发进阶随书代码/VTK图形图像开发进阶随书代码/Examples/Chap05/data/lena-gray.jpg");reader->Update();vtkSmartPointer fftFilter =vtkSmartPointer::New();fftFilter->SetInputConnection(reader->GetOutputPort());fftFilter->Update();//频域图像理想低通滤波//vtkSmartPointer lowPassFilter =//vtkSmartPointer::New();//lowPassFilter->SetInputConnection(fftFilter->GetOutputPort());//lowPassFilter->SetXCutOff(0.05);//用户设置每个方向的截断频率//lowPassFilter->SetYCutOff(0.05);//lowPassFilter->Update();//巴特沃斯低通滤波器vtkSmartPointer lowPassFilter = vtkSmartPointer::New();lowPassFilter->SetInputConnection(fftFilter->GetOutputPort());lowPassFilter->SetXCutOff(0.05);lowPassFilter->SetYCutOff(0.05);lowPassFilter->Update();vtkSmartPointer rfftFilter =vtkSmartPointer::New();rfftFilter->SetInputConnection(lowPassFilter->GetOutputPort());rfftFilter->Update();vtkSmartPointer ifftExtractReal =vtkSmartPointer::New();ifftExtractReal->SetInputConnection(rfftFilter->GetOutputPort());ifftExtractReal->SetComponents(0);vtkSmartPointer castFilter =vtkSmartPointer::New();castFilter->SetInputConnection(ifftExtractReal->GetOutputPort());castFilter->SetOutputScalarTypeToUnsignedChar();castFilter->Update();vtkSmartPointer originalActor =vtkSmartPointer::New();originalActor->SetInputData(reader->GetOutput());vtkSmartPointer erodedActor =vtkSmartPointer::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 renderWindow =vtkSmartPointer::New();renderWindow->SetSize(640, 320);renderWindow->Render();renderWindow->SetWindowName("IdealLowPassExample");vtkSmartPointer interactor =vtkSmartPointer::New();interactor->SetRenderWindow(renderWindow);vtkSmartPointer leftRenderer =vtkSmartPointer::New();renderWindow->AddRenderer(leftRenderer);leftRenderer->SetViewport(leftViewport);leftRenderer->SetBackground(1.0, 1.0, 1.0);vtkSmartPointer rightRenderer =vtkSmartPointer::New();renderWindow->AddRenderer(rightRenderer);rightRenderer->SetViewport(rightViewport);rightRenderer->SetBackground(1.0, 1.0, 1.0);leftRenderer->AddActor(originalActor);rightRenderer->AddActor(erodedActor);leftRenderer->ResetCamera();rightRenderer->ResetCamera();renderWindow->Render();interactor->Start();return EXIT_SUCCESS;} 高通滤波 理想高通滤波器 高通滤波与低通滤波正好相反 , 是让频域图像的高频部分通过而抑制低频部分 。图像的 边缘对应高频分量 , 因此高通滤波的效果是图像锐化 。同样 , 最简单的高通滤波器是理想高通滤波器 。其基本思想是通过设置一个频率阈值 , 让高于该阈值的频率部分通过 , 而低于阈 值的低频部分设置为0 。

从结果可以看出 , 理想高通滤波后图像得到锐化处理 ,  图像仅剩下边缘 。
巴特沃斯高通滤波器 理想高通滤波器不能通过电子元器件来实现 , 而且存在振铃现象 。在实际应用中 , 最常 使用的高通滤波器是巴特沃斯高通滤波器 。

【【QT+VTK 学习笔记】12:VTK频域处理】#include #include VTK_MODULE_INIT(vtkRenderingOpenGL2)VTK_MODULE_INIT(vtkInteractionStyle)VTK_MODULE_INIT(vtkRenderingFreeType)#include #include #include #include #include #include #include #include #include #include #include #include #include #include //测试图像:../data/lena-gray.jpgint main(int argc, char* argv[]){vtkSmartPointer reader =vtkSmartPointer::New();reader->SetFileName("C:/Users/jbyyy/Desktop/work/QTDEMO/jbyyy/VTK/学习资料/VTK图形图像开发进阶+张晓东+PDF+源码/VTK图形图像开发进阶随书代码/VTK图形图像开发进阶随书代码/Examples/Chap05/data/lena-gray.jpg");reader->Update();vtkSmartPointer fftFilter =vtkSmartPointer::New();fftFilter->SetInputConnection(reader->GetOutputPort());fftFilter->Update();////理想高通滤波器//vtkSmartPointer highPassFilter =//vtkSmartPointer::New();//highPassFilter->SetInputConnection(fftFilter->GetOutputPort());//highPassFilter->SetXCutOff(0.05);//设置X和Y方向的截止频率//highPassFilter->SetYCutOff(0.05);//highPassFilter->Update();//巴特沃斯高通滤波器vtkSmartPointer highPassFilter = vtkSmartPointer::New();highPassFilter->SetInputConnection(fftFilter->GetOutputPort());highPassFilter->SetXCutOff(0.05);highPassFilter->SetYCutOff(0.05);highPassFilter->Update();vtkSmartPointer rfftFilter =vtkSmartPointer::New();rfftFilter->SetInputConnection(highPassFilter->GetOutputPort());rfftFilter->Update();vtkSmartPointer ifftExtractReal =vtkSmartPointer::New();ifftExtractReal->SetInputConnection(rfftFilter->GetOutputPort());ifftExtractReal->SetComponents(0);vtkSmartPointer castFilter =vtkSmartPointer::New();castFilter->SetInputConnection(ifftExtractReal->GetOutputPort());castFilter->SetOutputScalarTypeToUnsignedChar();castFilter->Update();vtkSmartPointer originalActor =vtkSmartPointer::New();originalActor->SetInputData(reader->GetOutput());vtkSmartPointer erodedActor =vtkSmartPointer::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 renderWindow =vtkSmartPointer::New();renderWindow->SetSize(640, 320);renderWindow->Render();renderWindow->SetWindowName("IdealHighPassExample");vtkSmartPointer interactor =vtkSmartPointer::New();interactor->SetRenderWindow(renderWindow);vtkSmartPointer leftRenderer =vtkSmartPointer::New();renderWindow->AddRenderer(leftRenderer);leftRenderer->SetViewport(leftViewport);leftRenderer->SetBackground(1.0, 1.0, 1.0);vtkSmartPointer rightRenderer =vtkSmartPointer::New();renderWindow->AddRenderer(rightRenderer);rightRenderer->SetViewport(rightViewport);rightRenderer->SetBackground(1.0, 1.0, 1.0);leftRenderer->AddActor(originalActor);rightRenderer->AddActor(erodedActor);leftRenderer->ResetCamera();rightRenderer->ResetCamera();renderWindow->Render();interactor->Start();return EXIT_SUCCESS;}