OpenCV官方教程中文版 —— 傅里叶变换

这篇具有很好参考价值的文章主要介绍了OpenCV官方教程中文版 —— 傅里叶变换。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

前言

本小节我们将要学习:

使用 OpenCV 对图像进行傅里叶变换

使用 Numpy 中 FFT(快速傅里叶变换)函数

傅里叶变换的一些用处

我们将要学习的函数有:cv2.dft(),cv2.idft() 等

一、原理

傅里叶变换经常被用来分析不同滤波器的频率特性。我们可以使用 2D 离散傅里叶变换 (DFT) 分析图像的频域特性。实现 DFT 的一个快速算法被称为快速傅里叶变换(FFT)。关于傅里叶变换的细节知识可以在任意一本图像处理或信号处理的书中找到。请查看本小节中更多资源部分。

对于一个正弦信号:x (t) = A sin (2πft), 它的频率为 f,如果把这个信号转到它的频域表示,我们会在频率 f 中看到一个峰值。如果我们的信号是由采样产生的离散信号好组成,我们会得到类似的频谱图,只不过前面是连续的,现在是离散。你可以把图像想象成沿着两个方向采集的信号。所以对图像同时进行 X 方向和 Y 方向的傅里叶变换,我们就会得到这幅图像的频域表示(频谱图)。

更直观一点,对于一个正弦信号,如果它的幅度变化非常快,我们可以说他是高频信号,如果变化非常慢,我们称之为低频信号。你可以把这种想法应用到图像中,图像那里的幅度变化非常大呢?边界点或者噪声。所以我们说边界和噪声是图像中的高频分量(注意这里的高频是指变化非常快,而非出现的次数多)。如果没有如此大的幅度变化我们称之为低频分量。

现在我们看看怎样进行傅里叶变换。

二、Numpy 中的傅里叶变换

首先我们看看如何使用 Numpy 进行傅里叶变换。Numpy 中的 FFT 包可以帮助我们实现快速傅里叶变换。函数 np.fft.fft2() 可以对信号进行频率转换,输出结果是一个复杂的数组。本函数的第一个参数是输入图像,要求是灰度格式。第二个参数是可选的, 决定输出数组的大小。输出数组的大小和输入图像大小一样。如果输出结果比输入图像大,输入图像就需要在进行 FFT 前补0。如果输出结果比输入图像小的话,输入图像就会被切割。

现在我们得到了结果,频率为 0 的部分(直流分量)在输出图像的左上角。如果想让它(直流分量)在输出图像的中心,我们还需要将结果沿两个方向平移 N/2 。函数 np.fft.fftshift() 可以帮助我们实现这一步。(这样更容易分析)。进行完频率变换之后,我们就可以构建振幅谱了。

# -*- coding: utf-8 -*-
import cv2
import numpy as np
from matplotlib import pyplot as plt
img = cv2.imread('ball.png', 0)
f = np.fft.fft2(img)
fshift = np.fft.fftshift(f)
magnitude_spectrum = 20 * np.log(np.abs(fshift))
plt.subplot(121), plt.imshow(img, cmap='gray')
plt.title('Input Image'), plt.xticks([]), plt.yticks([])
plt.subplot(122), plt.imshow(magnitude_spectrum, cmap='gray')
plt.title('Magnitude Spectrum'), plt.xticks([]), plt.yticks([])
plt.show()

结果如下:

OpenCV官方教程中文版 —— 傅里叶变换,opencv,人工智能,计算机视觉
我们可以看到输出结果的中心部分更白(亮),这说明低频分量更多。

现在我们可以进行频域变换了,我们就可以在频域对图像进行一些操作了,例如高通滤波和重建图像(DFT 的逆变换)。比如我们可以使用一个60x60 的矩形窗口对图像进行掩模操作从而去除低频分量。然后再使用函数np.fft.ifftshift() 进行逆平移操作,所以现在直流分量又回到左上角了,左后使用函数 np.ifft2() 进行 FFT 逆变换。同样又得到一堆复杂的数字,我们可以对他们取绝对值:

rows, cols = img.shape
crow, ccol = int(rows / 2), int(cols / 2)
fshift[crow - 30:crow + 30, ccol - 30:ccol + 30] = 0
f_ishift = np.fft.ifftshift(fshift)
img_back = np.fft.ifft2(f_ishift)
# 取绝对值
img_back = np.abs(img_back)
plt.figure()
plt.subplot(131), plt.imshow(img, cmap='gray')
plt.title('Input Image'), plt.xticks([]), plt.yticks([])
plt.subplot(132), plt.imshow(img_back, cmap='gray')
plt.title('Image after HPF'), plt.xticks([]), plt.yticks([])
plt.subplot(133), plt.imshow(img_back)
plt.title('Result in JET'), plt.xticks([]), plt.yticks([])
plt.show()

结果如下:
OpenCV官方教程中文版 —— 傅里叶变换,opencv,人工智能,计算机视觉
上图的结果显示高通滤波其实是一种边界检测操作。这就是我们在前面图像梯度那一章看到的。同时我们还发现图像中的大部分数据集中在频谱图的低频区域。我们现在已经知道如何使用 Numpy 进行 DFT 和 IDFT 了,接着我们来看看如何使用 OpenCV 进行这些操作。

如果你观察仔细的话,尤其是最后一章 JET 颜色的图像,你会看到一些不自然的东西(如我用红色箭头标出的区域)。看上图那里有些条带装的结构,这被成为振铃效应。这是由于我们使用矩形窗口做掩模造成的。这个掩模被转换成正弦形状时就会出现这个问题。所以一般我们不适用矩形窗口滤波。最好的选择是高斯窗口。

三、OpenCV 中的傅里叶变换

OpenCV 中相应的函数是 cv2.dft()cv2.idft()。和前面输出的结果一样,但是是双通道的。第一个通道是结果的实数部分,第二个通道是结果的虚数部分。输入图像要首先转换成 np.float32 格式。我们来看看如何操作。

plt.figure()
dft = cv2.dft(np.float32(img), flags=cv2.DFT_COMPLEX_OUTPUT)
dft_shift = np.fft.fftshift(dft)
magnitude_spectrum = 20 * np.log(cv2.magnitude(dft_shift[:, :, 0], dft_shift[:, :, 1]))
plt.subplot(121), plt.imshow(img, cmap='gray')
plt.title('Input Image'), plt.xticks([]), plt.yticks([])
plt.subplot(122), plt.imshow(magnitude_spectrum, cmap='gray')
plt.title('Magnitude Spectrum'), plt.xticks([]), plt.yticks([])
plt.show()

OpenCV官方教程中文版 —— 傅里叶变换,opencv,人工智能,计算机视觉
现在我们来做逆 DFT。在前面的部分我们实现了一个 HPF(高通滤波),现在我们来做 LPF(低通滤波)将高频部分去除。其实就是对图像进行模糊操作。首先我们需要构建一个掩模,与低频区域对应的地方设置为 1, 与高频区域对应的地方设置为 0。

rows, cols = img.shape
crow, ccol = int(rows / 2), int(cols / 2)
# create a mask first, center square is 1, remaining all zeros
mask = np.zeros((rows,cols,2),np.uint8)
mask[crow-30:crow+30, ccol-30:ccol+30] = 1
# apply mask and inverse DFT
fshift = dft_shift*mask
f_ishift = np.fft.ifftshift(fshift)
img_back = cv2.idft(f_ishift)
img_back = cv2.magnitude(img_back[:,:,0],img_back[:,:,1])
plt.figure()
plt.subplot(121),plt.imshow(img, cmap = 'gray')
plt.title('Input Image'), plt.xticks([]), plt.yticks([])
plt.subplot(122),plt.imshow(img_back, cmap = 'gray')
plt.title('Magnitude Spectrum'), plt.xticks([]), plt.yticks([])
plt.show()

OpenCV官方教程中文版 —— 傅里叶变换,opencv,人工智能,计算机视觉

四、为什么拉普拉斯算子是高通滤波器?

我在论坛中遇到了一个类似的问题。为什么拉普拉斯算子是高通滤波器?为什么 Sobel 是 HPF?等等。对于第一个问题的答案我们以傅里叶变换的形式给出。我们一起来对不同的算子进行傅里叶变换并分析它们:

# -*- coding: utf-8 -*-
import cv2
import numpy as np
from matplotlib import pyplot as plt

mean_filter = np.ones((3, 3))  # simple averaging filter without scaling parameter
x = cv2.getGaussianKernel(5, 10)  # creating a guassian filter
gaussian = x * x.T  # x.T 为矩阵转置
# different edge detecting filters
scharr = np.array([[-3, 0, 3],
                   [-10, 0, 10],
                   [-3, 0, 3]])  # scharr in x-direction
sobel_x = np.array([[-1, 0, 1],
                   [-2, 0, 2],
                    [-1, 0, 1]])  # sobel in x direction
sobel_y = np.array([[-1, -2, -1],
                   [0, 0, 0],
                    [1, 2, 1]])  # sobel in y direction
laplacian = np.array([[0, 1, 0],
                      [1, -4, 1],
                      [0, 1, 0]])  # laplacian
filters = [mean_filter, gaussian, laplacian, sobel_x, sobel_y, scharr]
filter_name = ['mean_filter', 'gaussian', 'laplacian', 'sobel_x', 'sobel_y', 'scharr_x']
fft_filters = [np.fft.fft2(x) for x in filters]
fft_shift = [np.fft.fftshift(y) for y in fft_filters]
mag_spectrum = [20 * np.log(np.abs(z) + 1) for z in fft_shift]
for i in range(6):
    plt.subplot(2, 3, i + 1), plt.imshow(mag_spectrum[i], cmap='gray')
    plt.title(filter_name[i]), plt.xticks([]), plt.yticks([])
plt.show()

OpenCV官方教程中文版 —— 傅里叶变换,opencv,人工智能,计算机视觉
从图像中我们就可以看出每一个算子允许通过那些信号。从这些信息中我们就可以知道那些是 HPF 那是 LPF。文章来源地址https://www.toymoban.com/news/detail-715466.html

到了这里,关于OpenCV官方教程中文版 —— 傅里叶变换的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • OpenCV官方教程中文版 —— 直方图均衡化

    本小节我们要学习直方图均衡化的概念,以及如何使用它来改善图片的对比。 想象一下如果一副图像中的大多是像素点的像素值都集中在一个像素值范围之内会怎样呢?例如,如果一幅图片整体很亮,那所有的像素值应该都会很高。但是一副高质量的图像的像素值分布应该很

    2024年02月06日
    浏览(39)
  • OpenCV官方教程中文版 —— 直方图的计算,绘制与分析

    • 使用 OpenCV 或 Numpy 函数计算直方图 • 使用 Opencv 或者 Matplotlib 函数绘制直方图 • 将要学习的函数有:cv2.calcHist(),np.histogram() 什么是直方图呢?通过直方图你可以对整幅图像的灰度分布有一个整体的了解。直方图的 x 轴是灰度值(0 到 255),y 轴是图片中具有同一个灰度

    2024年02月06日
    浏览(34)
  • BeeWare官方教程中文版

    BeeWare官方教程 中文文档下载地址 以下内容为按照教程在windows平台测试。 如果你使用Windows系统,可以从python官网获取官方安装包。可以使用3.7之后的任何稳定版本的Python。建议避免使用阿尔法,贝塔和其他已经发布的候选版本。 在Windows系统上构建BeeWare 需要: Git,一种分

    2024年02月05日
    浏览(39)
  • Midjourney中文版到底是官方还是李鬼?

    AI绘画大神Midjourney为何选择QQ频道进军中国市场? Midjourney中文版到底是官方还是李鬼?看这篇文章就知道了! 今天我想和大家聊聊一个最近很火的话题,那就是AI绘画神器Midjourney(简称MJ)来中国了,QQ频道内测火爆开启。这对于喜欢AI绘画的创作者来说,无疑是一个福音,

    2024年02月12日
    浏览(34)
  • 快速傅里叶变换-FFTW库的使用-参考和翻译官方文档

    Plan:为实现意外结果的最佳方法而烦恼。 [Ambrose Bierce, The Enlarged Devil’s Dictionary。] FFTW 计算大小为 N 的一维 DFT 的基本用法很简单,它通常看起来像这样的代码: 您必须将此代码与 fftw3 库链接。 在 Unix 系统上,使用 -lfftw3 -lm 链接。 示例代码首先分配输入和输出数组。 您可

    2023年04月08日
    浏览(75)
  • opencv4 傅里叶变换

    ① 高频:变化剧烈的灰度分量,例如边界礁石。 ② 低频:变化缓慢的灰度分量,例如一片大海。 ③ 高通滤波器:只保留高频,会使得图像细节增强。高频边界锐化了,增强了,细节更明显了。 ④ 低通滤波器:只保留低频,会使得图像模糊。低频信息保留下来了,高频信息

    2024年02月08日
    浏览(32)
  • 《巧克甜恋》官方中文版全解锁存档分享

    因为之前修复更新英文版后补丁失效的问题一不小心把存档删了,遂意识到了存档的重要性,也特此分享给需要的朋友。 全解锁存档下载

    2024年02月12日
    浏览(27)
  • 002 OpenCV dft 傅里叶变换

    目录 一、傅里叶变换 1.1 傅里叶变换概念 1.2 opencv中傅里叶变换 二、实验代码 本文使用环境为: Windows10 Python 3.9.17 opencv-python 4.8.0.74 傅里叶变换(Fourier Transform)是一种在数学、物理和工程领域广泛应用的算法,用于分析信号或数据的频率成分。它是由法国数学家约瑟夫·傅

    2024年02月05日
    浏览(33)
  • 爆肝一周,我开源了ChatGPT 中文版接口,官方1:1镜像支持全部 官方接口

    这里实现我之前文章承诺承接上文 人人实现ChatGPT自由,手把手教你零撸部署自己聊天私服 现在 ChatGPT 提供了 api 接口 可以让我自己对接去实现我们自己想要gpt应用,但是由于一些原因,国内也不开放接口,所以我就1:1 自己对接了官方所有接口。 大家可以通过我的接口轻松

    2024年02月04日
    浏览(37)
  • OpenCV图像处理之傅里叶变换

    傅里叶变换: 目的就是得到图像的低频和高频,然后针对低频和高频进行不同的处理。处理完之后,在通过逆变换恢复到图像,这时候对低频和高频的处理就会反映到图像上。 频率 高频:变化剧烈的灰度分量,例如边界。 低频:变化缓慢的灰度分量,例如一天蓝天(相似的

    2024年02月06日
    浏览(49)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包