【千律】OpenCV基础:离散傅里叶变换

环境:Python3.8 和 OpenCV

内容:一维离散傅里叶变换和二维离散傅里叶变换

傅里叶变换和傅里叶反变换:

一维傅里叶变换后,除去初始点,其余各点满足:

(1)实部的点对称

(2)虚部的点反对称

(3)幅值(模长)的点对称

因此,可以得到F(u) 和 F(M - u) 两点共轭。

一维离散傅里叶变换:

实现方式1:

import cv2 as cv
import numpy as np
import matplotlib.pyplot as plt


if __name__ == '__main__':

    # 绘制方波信号
    M = 100            # 信号长度
    fx = np.zeros(M)   #
    fx[30: 70] = 1     # 方波信号

    # 傅里叶变换
    x = np.arange(0, M)
    Fu = np.zeros(M, np.complex128)
    for u in range(M):
        Re = np.sum(fx * np.cos(-2 * np.pi * u * x / M))
        Im = np.sum(fx * np.sin(-2 * np.pi * u * x / M))
        Fu[u] = Re + 1j * Im

    # 傅里叶反变换
    u = np.arange(0, M)
    Fx = np.zeros(M, np.complex128)
    for x in range(M):
        Re = np.sum(Fu * np.cos(2 * np.pi * u * x / M))
        Im = np.sum(Fu * np.sin(2 * np.pi * u * x / M))
        Fx[x] = Re + 1j * Im

    # 解决中文乱码
    plt.rcParams['font.sans-serif'] = ['SimHei']
    plt.rcParams['axes.unicode_minus'] = False

    # 绘制结果
    plt.plot(fx, 'r-', label='原始信号')
    plt.plot(np.real(Fu), 'b-', label='傅里叶变换实部')
    plt.plot(np.real(Fx), 'k-', label='反傅里叶变换实部')
    plt.legend()
    plt.xlim([0, 100])
    plt.show()

实现方式2:

import cv2 as cv
import numpy as np
import matplotlib.pyplot as plt


if __name__ == '__main__':

    # 绘制方波信号
    M = 100            # 信号长度
    fx = np.zeros(M)   #
    fx[30: 70] = 1     # 方波信号

    # 傅里叶变换
    x = np.arange(0, M)
    Fu = np.zeros(M, np.complex128)
    for u in range(M):
        Fu[u] = np.sum(fx * np.exp(-2j * np.pi * u * x / M))

    # 傅里叶反变换
    u = np.arange(0, M)
    Fx = np.zeros(M, np.complex128)
    for x in range(M):
        Fx[x] = np.sum(Fu * np.exp(2j * np.pi * u * x / M))

    # 解决中文乱码
    plt.rcParams['font.sans-serif'] = ['SimHei']
    plt.rcParams['axes.unicode_minus'] = False

    # 绘制结果
    plt.plot(fx, 'r-', label='原始信号')
    plt.plot(np.real(Fu), 'b-', label='傅里叶变换实部')
    plt.plot(np.real(Fx), 'k-', label='反傅里叶变换实部')
    plt.legend()
    plt.xlim([0, 100])
    plt.show()

二维离散傅里叶变换:

import cv2 as cv
import numpy as np
import matplotlib.pyplot as plt


if __name__ == '__main__':

    # 读取灰度图片
    img_lenna = cv.imread('lenna.png', 0)

    # 二维离散傅里叶变换
    img_fft = np.fft.fft2(img_lenna)

    # 傅里叶变换的平移
    img_ffts = np.fft.fftshift(img_fft)

    # 获取变换后的振幅谱和相位谱
    Amp = np.abs(img_ffts)
    Ang = np.angle(img_ffts)

    # 显示振幅谱和相位谱
    plt.figure()
    plt.subplot(121)
    plt.imshow(np.log(Amp + 1), cmap='jet')
    plt.subplot(122)
    plt.imshow(Ang, cmap='jet')
    plt.show()

    # 恢复成原图像
    img_lenna_re1 = np.abs(np.fft.ifft2(img_fft))
    img_lenna_re2 = np.abs(np.fft.ifft2(img_ffts))

    # 显示恢复结果
    plt.figure()
    plt.subplot(121)
    plt.imshow(img_lenna_re1, cmap='gray')
    plt.subplot(122)
    plt.imshow(img_lenna_re2, cmap='gray')
    plt.show()

基于傅里叶变换的图像融合 :

import cv2 as cv
import numpy as np
import matplotlib.pyplot as plt


# 封装图片显示函数
def image_show(image):
    if image.ndim == 2:
        plt.imshow(image, cmap='gray')
    else:
        image = cv.cvtColor(image, cv.COLOR_BGR2RGB)
        plt.imshow(image)
    plt.show()


if __name__ == '__main__':

    # 读取图像
    img_desk = cv.imread('desk.png', 0)
    img_lenna = cv.imread('lenna.png', 0)

    # 图像裁剪
    img_desk_crap = img_desk[:500, :500]

    # 二维离散傅里叶变换
    desk_fft = np.fft.fft2(img_desk_crap)
    lenna_fft = np.fft.fft2(img_lenna)

    # 获取幅值谱和相位谱
    Desk_Amp, Desk_Ang = np.abs(desk_fft), np.angle(desk_fft)
    Lenna_Amp, Lenna_Ang = np.abs(lenna_fft), np.angle(lenna_fft)

    # 图像融合
    Fu_A = Desk_Amp * np.cos(Lenna_Ang) + Desk_Amp * np.sin(Lenna_Ang)
    Fu_B = Lenna_Amp * np.cos(Desk_Ang) + Lenna_Amp * np.sin(Desk_Ang)

    # 傅里叶反变换
    img_desk_rec = np.fft.ifft2(Fu_A)
    img_Lenna_rec = np.fft.ifft2(Fu_B)

    # 显示结果
    image_show(np.abs(img_desk_rec))
    image_show(np.abs(img_Lenna_rec))

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

阿飞_Y

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

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

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

打赏作者

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

抵扣说明:

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

余额充值