1.图像频域处理的意义

在图像处理和分析中,经常会将图像从图像空间转换到其他空间中,并利用这些空间的特点进行对转换后图像进行分析处理,然后再将处理后的图像转换到图像空间中,这称之为图像变换。
在一些图像处理和分析中通过空间变换往往会取得更有效的结果。图像频域处理是指将图像从图像空间转换到频域空间进行处理的过程。最常用的频域转换是傅里叶变换。
傅里叶变换的计算量较大,人们为了提高速度,提出了快速傅里叶变换,并得到了广泛的应用。本篇博客主要来学习VTK中的快速傅里叶变换。

2. 快速傅里叶变换及其逆变换

快速傅里叶变换(Fast Fourier Transform),简称做FFT。它是根据离散傅氏变换的奇、偶、虚、实等特性,对离散傅立叶变换的算法进行改进获得的。傅里叶变换是可逆的,其逆变换为RFFT。
FFT在数字图像处理中有着广泛的应用,例如数字图像频域滤波,去噪,增强等等。 目前VTK中两变换都已经实现,对应的类分别为vtkImageFFT和vtkImageRFFT。
vtkImageFFT和vtkImageRFFT的输入为实数或者复数数据,输出都为复数数据。因此,vtkImageFFT与vtkImageRFFT的输出结果不能直接显示,因为VTK会将其当做彩色图像显示,需要通过vtkImageExtractComponents提取某一组分图像显示。
VTK频率域的图像处理步骤如下:

下面代码演示了怎样对图像进行傅里叶变换,以及将傅里叶变换结果进行逆变换:

#include <vtkAutoInit.h>
VTK_MODULE_INIT(vtkRenderingOpenGL);#include <vtkSmartPointer.h>
#include <vtkJPEGReader.h>
#include <vtkImageFFT.h>
#include <vtkImageExtractComponents.h>
#include <vtkImageData.h>
#include <vtkImageShiftScale.h>
#include <vtkImageRFFT.h>
#include <vtkImageActor.h>
#include <vtkrenderer.h>
#include <vtkRenderWindow.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkInteractorStyleImage.h>int main()
{vtkSmartPointer<vtkJPEGReader> reader =vtkSmartPointer<vtkJPEGReader>::New();reader->SetFileName("lena.jpg");reader->Update();//FFT//vtkSmartPointer<vtkImageFFT> imgFFT =vtkSmartPointer<vtkImageFFT>::New();imgFFT->SetInputConnection(reader->GetOutputPort());imgFFT->SetDimensionality(2);imgFFT->Update();// the resualts are complex, we shoule extract one component to displayvtkSmartPointer<vtkImageExtractComponents> imgComponent =vtkSmartPointer<vtkImageExtractComponents>::New();imgComponent->SetInputConnection(imgFFT->GetOutputPort());imgComponent->SetComponents(0);// norm image rangedouble Range[2];imgComponent->GetOutput()->GetScalarRange(Range);vtkSmartPointer<vtkImageShiftScale> imgfftShiftScale =vtkSmartPointer<vtkImageShiftScale>::New();imgfftShiftScale->SetOutputScalarTypeToUnsignedChar();imgfftShiftScale->SetScale(255.0 / (Range[1] - Range[0]));imgfftShiftScale->SetShift(-Range[0]);imgfftShiftScale->SetInputConnection(imgComponent->GetOutputPort());imgfftShiftScale->Update();//RFFT/vtkSmartPointer<vtkImageRFFT> imgRFFT =vtkSmartPointer<vtkImageRFFT>::New();imgRFFT->SetInputConnection(imgFFT->GetOutputPort());imgRFFT->SetDimensionality(2);imgRFFT->Update();vtkSmartPointer<vtkImageExtractComponents> imgComponetNew =vtkSmartPointer<vtkImageExtractComponents>::New();imgComponetNew->SetInputConnection(imgRFFT->GetOutputPort());imgComponetNew->SetComponents(0);double RangeNew[2];imgComponetNew->GetOutput()->GetScalarRange(RangeNew);vtkSmartPointer<vtkImageShiftScale> imgrfftShiftScale =vtkSmartPointer<vtkImageShiftScale>::New();imgrfftShiftScale->SetOutputScalarTypeToUnsignedChar();imgrfftShiftScale->SetScale(255.0 / (RangeNew[1] - RangeNew[0]));imgrfftShiftScale->SetInputConnection(imgComponetNew->GetOutputPort());imgrfftShiftScale->Update();/////谨记vtkImageActor仅能够显示UnsignedChar类型数据vtkSmartPointer<vtkImageActor> origActor =vtkSmartPointer<vtkImageActor>::New();origActor->SetInputData(reader->GetOutput());vtkSmartPointer<vtkImageActor> fftActor =vtkSmartPointer<vtkImageActor>::New();fftActor->SetInputData(imgFFT->GetOutput());vtkSmartPointer<vtkImageActor> rfftActor =vtkSmartPointer<vtkImageActor>::New();rfftActor->SetInputData(imgrfftShiftScale->GetOutput());///double origView[4] = { 0, 0, 0.33, 1 };double fftView[4] = { 0.33, 0, 0.66, 1 };double rfftView[4] = { 0.66, 0, 1, 1 };vtkSmartPointer<vtkRenderer> origRender =vtkSmartPointer<vtkRenderer>::New();origRender->SetViewport(origView);origRender->AddActor(origActor);origRender->ResetCamera();origRender->SetBackground(1, 0, 0);vtkSmartPointer<vtkRenderer> fftRender =vtkSmartPointer<vtkRenderer>::New();fftRender->SetViewport(fftView);fftRender->AddActor(fftActor);fftRender->ResetCamera();fftRender->SetBackground(0, 1, 0);vtkSmartPointer<vtkRenderer> rfftRender =vtkSmartPointer<vtkRenderer>::New();rfftRender->SetViewport(rfftView);rfftRender->AddActor(rfftActor);rfftRender->ResetCamera();rfftRender->SetBackground(0, 0, 1);/vtkSmartPointer<vtkRenderWindow> rw =vtkSmartPointer<vtkRenderWindow>::New();rw->AddRenderer(origRender);rw->AddRenderer(fftRender);rw->AddRenderer(rfftRender);rw->SetWindowName("Frequncy_FFT_RFFT");rw->SetSize(960, 320);vtkSmartPointer<vtkRenderWindowInteractor> rwi =vtkSmartPointer<vtkRenderWindowInteractor>::New();vtkSmartPointer<vtkInteractorStyleImage> style =vtkSmartPointer<vtkInteractorStyleImage>::New();rwi->SetInteractorStyle(style);rwi->SetRenderWindow(rw);rwi->Initialize();rwi->Start();return 0;
}

首先建立一个JPEG图像reader来读取一副灰度图像。然后定义一个vtkImageFFT指针,直接接收reader的输出即原图像数据作为输入进行二维快速傅里叶变换。其输出为一个像素类型为复数的vtkImageData数据,即每个像素值为两个组分(Component):复数实部和虚部。因此如果直接显示这个vtkImageData,会发现是一个彩色图像。如果需要显示频域图像,需要通过vtkImageExtractComponents类来提取某一个组分图像来显示。上例中通过定义vtkImageExtractComponents类指针,利用函数SetComponents(0)指定提取实部图像显示;由于vtkImageActor类仅支持unsigned char数据类型的图像,利用vtkImageCast类的SetOutputScalarTypeToUnsignedChar()指定输出类型为unsigned char,将FFT结果图像转换为需要的类型。

对于逆变换的过程也是类似。首先定义vtkImageRFFT指针,并接收输入为vtkImageFFT指针的输出,调用Update执行函数完成快速傅里叶逆变换。vtkImageRFFT的输出同样为一副复数图像,通常不能直接显示或者进行其他操作。对于傅里叶逆变换的图像中虚数部分值为0,实数部分图像即为重建的原始图像。因此再次利用vtkImageExtractComponents提取实数部分图像,并通过SetOutputScalarTypeToUnsignedChar()将图像转换为unsigned char类型进行显示。
下图为计算结果:

VTK_Learning_频域处理_快速傅里叶变换及其反变换相关推荐

  1. VTK修炼之道40:频域处理_快速傅里叶变换及其反变换1

    1.图像频域处理的意义 在图像处理和分析中,经常会将图像从图像空间转换到其他空间中,并利用这些空间的特点进行对转换后图像进行分析处理,然后再将处理后的图像转换到图像空间中,这称之为图像变换. 在一些图 ...

  2. 3.1 Python图像的频域图像增强-图像的傅里叶变换和反变换

    3.1 Python图像的频域图像增强-图像的傅里叶变换和反变换 文章目录 3.1 Python图像的频域图像增强-图像的傅里叶变换和反变换 1 算法原理 2 代码 3 效果 1 算法原理 图像的傅里 ...

  3. java fft 频谱算法_快速傅里叶变换(FFT)算法原理及代码解析

    FFT与DFT关系: 快速傅里叶变换(Fast Fourier Transform)是离散傅里叶(DFT)变换的一种快速算法,简称FFT,通过FFT可以将一个信号从时域变换到频域:FFT(快速傅里叶变 ...

  4. matlab cftool光滑曲线导出为什么就不光滑了_快速傅里叶变换(FFT)中为什么要“补零”?...

    为了大家能够复现各个图中的结果,我附上了所有我编写的MATLAB代码. 创作不易,未经允许,禁止转载. 另外,说明一下,用MATLAB做FFT并不要求数据点个数必须为以2为基数的整数次方.之所以很多资 ...

  5. dft变换的两幅图_快速傅里叶变换FFT计算方法 原理及公式

    在实际的控制系统中能够得到的是连续信号x(t)的离散采样值x(nT).因此需要利用离散信号x(nT)来计算信号x(t)的频谱. 有限长离散信号x(n),n=0,1,-,N-1的DFT定义为: DFT ...

  6. 快速傅里叶变换及其实现

    一.基本原理 长度为N的有限长离散序列的傅里叶变换的定义为: (1) 逆变换: (2) 其中,(3) 用矩阵来表达傅里叶变换为: (4) 逆变换: (5) 因为,则 (6) 因此, (7) 二.N点F ...

  7. 图像算法四:【图像增强--频率域】傅里叶变换、快速傅里叶变换、频域滤波、频域低通滤波、频域高通滤波

    频率域滤波与空间域滤波殊途同归,空间域图像增强与频率域图像增强是两种截然不同的技术,实际上在相当程度上说它们是在不同的领域做相同的事情,只是有些滤波更适合在空间域完成,而有些则更适合在频率域中完成. ...

  8. 在python实现快速傅里叶变换FFT与频域滤波

    参考:https://baike.baidu.com/item/快速傅里叶变换/214957?fr=aladdin https://blog.csdn.net/u012531536/article/d ...

  9. 快速傅里叶变换_计算物理基础:第八章-快速傅里叶变换(FFT)

    参考北京师范大学的<计算物理基础> 第八章-快速傅里叶变换 计算物理基础_中国大学MOOC(慕课)​www.icourse163.org 1.快速傅里叶变换 1.1 离散傅里叶变换及其变换 ...

  10. fft的c语言和matlab对比_傅里叶级数(FS)、傅里叶变换(FT)快速傅里叶变换(FFT)及量子傅里叶变换(QFT)之间推导关系...

    1 引言 傅里叶级数 (Fourier Series, FS) 是<高等数学>中遇到的一个重要的级数,它可以将任意一个满足狄利克雷条件的函数为一系列三角级数的和.最早由法国数学家傅里叶在研 ...

最新文章

  1. html 表格隐藏 显示出来了,如何在html页面打开时隐藏表格
  2. java was started but returned exit code = 1
  3. GDCM:获取dicom文件Sequence的长度的测试程序
  4. oracle锁表语句执行提示无法终止当前对话_Oracle 强制中止正在执行的SQL语句
  5. 报错Cannot determine embedded database driver class for database type NONE解决方法
  6. 【Paper】AAAI 2020 故事生成模型 之 角色一致性
  7. PHP+Swoole实现的网页即时聊天通讯工具:PHPWebIM
  8. steam 加速器_如何在Steam中使用Switch的Pro控制器
  9. webSSH如何安装?如何使用?解决Web端远程连接终端~~运维篇
  10. python 读取TXT文件数据(字符或数值)存放在numpy数组中以及训练集测试集的处理(1)(个人笔记)
  11. 使用c#实现一个简单绘图软件(绘制矩形、多边形,画笔、橡皮擦功能)的完整教程
  12. 分享新作:休闲小游戏『Flying Stone』
  13. 双网卡共享上网的完全解决方案
  14. day4-数字类型和列表基础
  15. 机器学习实战(Machine Learning in Action)学习笔记————02.k-邻近算法(KNN)
  16. Ubuntu上搭建Hadoop环境(单机模式+伪分布模式) - 狂奔的蜗牛 - 博客频道 - CSDN.NET http://blog.csdn.net/hitwengqi/article/detai
  17. 用ArcGIS Server服务Print打印高清大图的关键参数
  18. 图象关于y轴对称是什么意思_关于x轴对称-图象关于y轴对称是什么函数
  19. 宗宁:把企业做成IP,BOSS直聘对标Line
  20. 操作系统:图文详解神秘的”内存映射“

热门文章

  1. 【初学者必知必会】【电子技术:数电 模电 单片机】【基础概念和小知识点】详解
  2. 直观理解图像的分形维数附matlab实现
  3. 大数据Hadoop原理介绍+安装+实战操作(HDFS+YARN+MapReduce)
  4. [规划酱@国土空间] ArcGIS工具| 三调转换之新用地用海分类
  5. 泊松分布和指数分布:通俗易懂
  6. windows域环境搭建上
  7. AcrelEMS-IDC综合能效管理系统 XXX数据中心案例分享
  8. 2012共享文件服务器,win server2012 r2 服务器共享文件夹设置
  9. Spring中AOP的实现原理
  10. Spring中的refresh()