第4章 Python 数字图像处理(DIP) - 频率域滤波1 - 傅里叶级数和变换简史

本章主要讲解频域域滤波的技术,主要技术用到是大家熟悉的傅里叶变换与傅里叶反变换。这里有比较多的篇幅讲解的傅里叶的推导进程,用到Numpy傅里叶变换。本章理论基础比较多,需要更多的耐心来阅读,有发现有错误,可以与我联系。谢谢!

import sys
import numpy as np
import cv2
import matplotlib 
import matplotlib.pyplot as plt
import PIL
from PIL import Image

print(f"Python version: {sys.version}")
print(f"Numpy version: {np.__version__}")
print(f"Opencv version: {cv2.__version__}")
print(f"Matplotlib version: {matplotlib.__version__}")
print(f"Pillow version: {PIL.__version__}")
Python version: 3.6.12 |Anaconda, Inc.| (default, Sep  9 2020, 00:29:25) [MSC v.1916 64 bit (AMD64)]
Numpy version: 1.16.6
Opencv version: 3.4.1
Matplotlib version: 3.3.2
Pillow version: 8.0.1
def normalize(mask):
    return (mask - mask.min()) / (mask.max() - mask.min() + 1e-8)

背景

傅里叶级数和变换简史

内容比较多,请自行看书,我就实现一维的傅里叶变换先。

卷积用大小为 m × n m\times n m×n元素的核对大小为 M × N M\times N M×N的图像进行滤波时,需要运算次数为 M N m n MNmn MNmn。如果核是可分享的,那么运算次数为 M N ( m + N ) MN(m + N) MN(m+N),而在频率域执行等交的滤波所需要的运算次数为 2 M N log 2 M N 2MN\text{log}_2MN 2MNlog2MN,2表示计算一次正FFT和一次反FFT。

C n ( m ) = M 2 m 2 2 M 2 log 2 M 2 = m 2 4 log 2 M (4.1) C_n(m) = \frac{M^2 m^2}{2M^2 \text{log}_2}M^2 = \frac{m^2}{4 \text{log}_2 M}\tag{4.1} Cn(m)=2M2log2M2m2M2=4log2Mm2(4.1)

如果是可分离核,则变为

C s ( m ) = M 2 m 2 2 M 2 log 2 M 2 = m 2 log 2 M (4.2) C_s(m) = \frac{M^2 m^2}{2M^2 \text{log}_2 M^2} = \frac{m}{2 \text{log}_2 M} \tag{4.2} Cs(m)=2M2log2M2M2m2=2log2Mm(4.2)

C ( m ) > 1 C(m) > 1 C(m)>1时,FFT的方法计算优势更大;而 C ( m ) ≤ 1 C(m) \leq 1 C(m)1时,空间滤波的优势更大

# FFT 计算的优势
M = 2048
m = np.arange(0, 1024, 1)
c_n = m**2 / (4 * np.log2(M))
c_s = m / (2 * np.log2(M))
fig = plt.figure(figsize=(10, 5))
ax_1 = fig.add_subplot(1, 2, 1)
ax_1.plot(c_n)
ax_1.set_xlim([0, 1024])
ax_1.set_xticks([3, 255, 511, 767, 1023])
ax_1.set_ylim([0, 25*1e3])
ax_1.set_yticks([0, 5*1e3, 10*1e3, 15*1e3, 20*1e3, 25*1e3])
ax_2 = fig.add_subplot(1, 2, 2)
ax_2.plot(c_s)
ax_2.set_xlim([0, 1024])
ax_2.set_xticks([3, 255, 511, 767, 1023])
ax_2.set_ylim([0, 5])
ax_2.set_yticks([0, 10, 20, 30, 40, 50])
plt.show()

在这里插入图片描述

def set_spines_invisible(ax):
    ax.spines['left'].set_color('none')
    ax.spines['right'].set_color('none')
    ax.spines['top'].set_color('none')
    ax.spines['bottom'].set_color('none')
# 不同频率的叠加
x = np.linspace(0, 1, 500)

t = 50
A = 1
y_1 = A * np.sin(t * 2 * np.pi * x)

t = 20
A = 2.5
y_2 = A * np.sin(t * 2 * np.pi * x)

t = 5
A = 3
y_3 = A * np.sin(t * 2 * np.pi * x)

t = 2
A = 20
y_4 = A * np.sin(t * 2 * np.pi * x)

y_5 = y_1 + y_2 + y_3 + y_4

fig = plt.figure(figsize=(8, 8))

ax_1 = fig.add_subplot(5, 1, 1)
plt.plot(x, y_1), plt.xticks([]), plt.yticks([])
set_spines_invisible(ax_1)

ax_2 = fig.add_subplot(5, 1, 2)
plt.plot(x, y_2), plt.xticks([]), plt.yticks([])
set_spines_invisible(ax_2)

ax_3 = fig.add_subplot(5, 1, 3)
plt.plot(x, y_3), plt.xticks([]), plt.yticks([])
set_spines_invisible(ax_3)

ax_4 = fig.add_subplot(5, 1, 4)
plt.plot(x, y_4), plt.xticks([]), plt.yticks([])
set_spines_invisible(ax_4)

ax_5 = fig.add_subplot(5, 1, 5)
plt.plot(x, y_5), plt.xticks([]), plt.yticks([])
set_spines_invisible(ax_5)

plt.tight_layout()
plt.show()

在这里插入图片描述

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

jasneik

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

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

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

打赏作者

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

抵扣说明:

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

余额充值