数字图像的傅里叶变换(Fourier Transform)及其展示: 频率中心化

本文通过理论和MATLAB实际例子验证如下结论:

1. 大部分图片的有效信息集中在低频部分;

2. 图像傅里叶变换后低频在四周、高频在中心;

3. 图像经过傅里叶变换、频率中心化后能够容易地复原;

从而进一步说明图像通常需要进行频率中心化操作以方便处理

 

1. 大部分图片的有效信息集中在低频部分

图片的高频部分主要是边缘等细节,主要内容大部分是低频部分。因此,大部分图片的有效信息集中在低频部分。从图3中我们可以看出,在去除图片中频率最低的一小部分后,图像出现了明显的锐化;而反过来,当只保留图像中频率最低的一小部分后,明显有更多的信息得到了保留。

 

2. 图像傅里叶变换后低频在四周、高频在中心

理论解释下面这个链接很到位:

图像经过傅里叶变换以后,得到的频谱图为啥是对称的?又为啥在未频谱居中时,四周代表是低频,中间是高频? - DBinary的回答 - 知乎

总结起来就是:

二维傅里叶变换是对图像每行做一次一维傅里叶变换,再对其每列做一次一维傅里叶变换,依据从左到右频率增高的原则,最后不就变成了中间是高频,四个角是低频了么.当然为了观察方便常常用fftshift方法将低频移到中心。

Note:一维傅里叶变换本身也是高频在中间,低频在两端,经过fftshift才是低频在中间的样子,可以通过如下MATLAB代码验证:

x=1:0.1:100;
z=0.1*sin(2*pi*x)+1*sin(4*pi*x);
Z = fft(z);
plot(abs(Z));

图形如下:

 

3. 图像经过傅里叶变换、频率中心化后能够容易地复原

傅里叶变换具有可逆性,这也是它能够得到广泛应用的原因之一。而MATLAB中的fft2与ifft2; fftshift与ifftshift则使我们可以很方便地完成这些操作。

 

下图表示出图形的傅里叶变换和频率中心化的结果:

下图是由中心化的频域图复原得到的空间域图,表现了傅里叶变换的可逆性

 

下图是将一小部分低频置零后的结果:

下图则是将除了一小部分低频,其他大部分频域分量均置零后的结果,很好地说明了这个图像的信息大量集中在低频部分。

MATLAB代码如下:

image = imread('camera.png');
image=rgb2gray(image);
image=im2double(image);
F_image = fft2(image);

figure(1)
subplot(221)
imshow(image);
title('original image')
subplot(222)
imshow(abs(F_image))
title('magnitude of Frequency image')
subplot(223)
imshow(angle(F_image))
title('phase of Frequency image')
subplot(224)
imshow(fftshift(abs(F_image)))
title('central')

F_imageAfterCentral = fftshift(F_image);
figure(2)
subplot(311)
originalRecoverImage = ifft2(ifftshift(F_imageAfterCentral));
imshow(originalRecoverImage)
title('IFT of the original spectrogram')
% 将四边取0(即将中心化后的中心点取0)
subplot(312)
F_imageAfterCentral_m = F_imageAfterCentral;
F_imageAfterCentral_m(280:300,280:300) = 0;
imshow(ifft2(ifftshift(F_imageAfterCentral_m)))
title('setting the small central area(low frequency) to 0')
subplot(313)
F_imageAfterCentral_m1 = F_imageAfterCentral;
F_imageAfterCentral_m2 = F_imageAfterCentral;
F_imageAfterCentral_m1(280:300,280:300) = 0;
F_difference = F_imageAfterCentral_m2 - F_imageAfterCentral_m1;
imshow(ifft2(ifftshift(F_difference)))
title('setting all area to 0 except the small central area(low frequency)')

 

### 回答1: 下面是一个在C++中实现傅里叶变换的示例代码: ```cpp #include <opencv2/opencv.hpp> #include <iostream> using namespace cv; using namespace std; int main() { // 读取图像并转换为灰度图像 Mat img = imread("input.png", IMREAD_GRAYSCALE); // 对图像进行傅里叶变换 Mat planes[] = { Mat_<float>(img), Mat::zeros(img.size(), CV_32F) }; Mat complexImg; merge(planes, 2, complexImg); dft(complexImg, complexImg); // 可视化傅里叶变换结果 split(complexImg, planes); magnitude(planes[0], planes[1], planes[0]); Mat magImg = planes[0]; magImg += Scalar::all(1); log(magImg, magImg); normalize(magImg, magImg, 0, 255, NORM_MINMAX); magImg.convertTo(magImg, CV_8UC1); imshow("magnitude spectrum", magImg); waitKey(0); destroyAllWindows(); return 0; } ``` 在上述代码中,首先读取了一张图像并转换为灰度图像。然后对该图像进行傅里叶变换,并通过split函数将变换结果拆分为实部和虚部。接着,通过magnitude函数计算幅度谱,并将其进行对数变换和归一化。最后,通过imshow函数将幅度谱可视化。 需要注意的是,在进行傅里叶变换时,需要将输入图像转换为浮点型数据,并将其分成两个通道,一个通道用于存储实部,另一个通道用于存储虚部。同时,傅里叶变换后得到的频谱图像是对称的,在可视化时需要将零频率分量中心位置,以便观察。 ### 回答2: 在使用OpenCV的C++实现傅里叶变换Fourier Transform)时,首先需要导入相关的头文件: ``` #include <opencv2/opencv.hpp> #include <opencv2/highgui/highgui.hpp> ``` 接下来,我们需要读取一张图像并将其转化为灰度图像: ``` cv::Mat img = cv::imread("image.jpg", cv::IMREAD_GRAYSCALE); ``` 然后,我们可以对图像进行傅里叶变换: ``` cv::Mat fourierImg; cv::dft(img, fourierImg, cv::DFT_SCALE | cv::DFT_COMPLEX_OUTPUT); ``` 在进行傅里叶变换之后,得到的是一个复数矩阵。如果需要进行傅里叶变换,可以使用下面的代码: ``` cv::Mat invertedImg; cv::idft(fourierImg, invertedImg, cv::DFT_SCALE | cv::DFT_REAL_OUTPUT); ``` 最后,我们可以将变换后的图像进行可视化展示: ``` cv::imshow("Original Image", img); cv::imshow("Fourier Image", fourierImg); cv::imshow("Inverted Image", invertedImg); cv::waitKey(0); ``` 通过以上代码,我们就可以使用OpenCV的C++实现傅里叶变换了。需要注意的是,傅里叶变换函数`cv::dft()`和逆傅里叶变换函数`cv::idft()`参数中的`DFT_SCALE`用于缩放变换后的结果。 ### 回答3: OpenCV是一个开源的计算机视觉库,其中包括了许多常用的图像处理和计算机视觉算法。OpenCV中提供了傅里叶变换Fourier Transform)的C++实现。 傅里叶变换是图像处理中常用的数学工具,可以将一个信号或图像从时域变换到频域。在OpenCV中,可以通过使用dft函数来进行傅里叶变换。 要使用OpenCV进行傅里叶变换,首先需要包含相应的头文件: ``` #include <opencv2/opencv.hpp> ``` 接下来,可以使用dft函数来进行傅里叶变换。该函数的参数包括输入图像、输出图像和变换标志等。以下是一个简单示例: ``` cv::Mat image = cv::imread("input.jpg", cv::IMREAD_GRAYSCALE); //进行傅里叶变换 cv::Mat fourier_image; cv::dft(image, fourier_image, cv::DFT_COMPLEX_OUTPUT); //显示结果 cv::imshow("Fourier Transform", fourier_image); cv::waitKey(0); ``` 在上述示例中,首先使用imread函数加载输入图像。然后,将加载的图像转换为灰度图像(IMREAD_GRAYSCALE)。接下来,通过dft函数进行傅里叶变换,其中将输出图像指定为fourier_image,并将变换的标志设置为DFT_COMPLEX_OUTPUT表示输出是复数形式。 最后,可以使用imshow函数显示傅里叶变换后的图像,并使用waitKey函数等待用户按下按键以退出程序。 总结起来,OpenCV中提供了简单易用的傅里叶变换函数dft,通过该函数可以将图像从时域变换到频域,方便进行图像处理和分析。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

R.X. NLOS

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值