提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
文章目录
前言
1. 频率域增强的一般过程
频域率增强的一般过程如下:
f
(
x
,
y
)
→
傅里叶变换
D
F
T
F
(
u
,
v
)
→
滤波
H
(
u
,
v
)
F
(
u
,
v
)
H
(
u
,
v
)
→
傅里叶逆变换
I
D
F
T
g
(
x
,
y
)
f(x,y)\xrightarrow[傅里叶变换]{DFT} F(u,v)\xrightarrow[滤波]{H(u,v)}F(u,v)H(u,v)\xrightarrow[傅里叶逆变换]{IDFT}g(x,y)
f(x,y)DFT傅里叶变换F(u,v)H(u,v)滤波F(u,v)H(u,v)IDFT傅里叶逆变换g(x,y)
我用大白话解释就是:先用傅里叶变换将图像变换到频率域(也就是频谱图),然后针对频谱图做图像变换(使用滤波器),使用滤波器进行图像变换后通过傅里叶逆变换将图像变换回空域图(也就是目标图像)。
频域特征与空域特征的对应关系:
- 频普中的低频分量对应了图像中的平滑区域。
- 频谱中的高频分量对应了图像中的边缘和变化剧烈区域。
实在抱歉,由于本人学艺不精,此处就不对傅里叶变换进行讲解,各位观众可以查看其它资料
频谱图的绘制代码和效果如下所示:
import cv2 as cv
import numpy as np
import matplotlib.pyplot as plt
def drawCircleOnImage(image, radiusLst):
"""
Draw multiple concentric circles on an image
:param image: raw image
:param radiusLst: Radii of concentric circles (Here is a list with multiple radii).
:return: Returns an image drawn on concentric circles.
"""
center = (image.shape[0] // 2, image.shape[1] // 2)
color = (0, 0, 0)
thickness = 1
for radius in radiusLst:
cv.circle(image, center, radius, color, thickness)
def generateSpectrumImage(image):
# 对原图像进行傅里叶变换,生成频谱图
dft = cv.dft(np.float32(image), flags=cv.DFT_COMPLEX_OUTPUT)
# 将频谱图上的低频移至中心
f_shift = np.fft.fftshift(dft)
# 生成可以显示的频谱图
f_img = 20 * np.log(cv.magnitude(f_shift[:, :, 0], f_shift[:, :, 1]) + 1)
drawCircleOnImage(f_img, [10, 20, 40, 80, 160, 460])
# 将低频从中心移回原处
i_shift = np.fft.ifftshift(f_shift)
# 进行计算傅里叶逆变换,将频谱图还原回空间域图像
dst = cv.idft(i_shift)
# 计算还原图像的幅度,并进行归一化处理
dst = cv.magnitude(dst[:, :, 0], dst[:, :, 1])
return f_img, dst
if __name__ == '__main__':
img = cv.imread('Image/Fig0601.tif', 0)
img1, img2 = generateSpectrumImage(img)
# 图像显示
plt.rcParams['font.sans-serif'] = ['SimHei']
plt.rcParams['font.size'] = 20
plt.figure(figsize=(20, 10))
imagesLst = [img, img1, img2]
labelLst = ["Original Image", "Radius=10", "Radius=20"]
for i in range(3):
plt.subplot(1, 3, i + 1), plt.title(labelLst[i]), plt.axis('off')
plt.imshow(imagesLst[i], cmap='gray')
plt.tight_layout()
plt.savefig("Image/tmp.png")
plt.show()
如上图所示:我们先将空域图(原始图像)转到频域图,然后将频域图有转为空域图,在经过一次变换后,图像几乎没有发生变化。
2. 低频滤波示例分析
2.1 理想低通滤波
在以原点为中心的一个园内无衰减的通过所有频率,而在这个圆外 “截止” 所有频率的二维低通滤波器,称为 理想低通滤波器(ILPF)。
2.1.1 原理说明
**理想低通滤波器(ILPF)**的传递函数规定如下:
H
(
u
,
v
)
=
{
1
,
D
(
u
,
v
)
≤
D
0
0
,
D
(
u
,
v
)
>
D
0
H(u,v)= \left\{ \begin{aligned} 1, &\quad D(u,v) \leq D_0 \\ 0, &\quad D(u,v) > D_0\\ \end{aligned} \right.
H(u,v)={1,0,D(u,v)≤D0D(u,v)>D0
式中,
D
0
是一个正常数,
D
(
u
,
v
)
是频率域中的点
(
u
,
v
)
到
P
×
Q
频率矩形中心的距离,即:
式中,D_0是一个正常数,D(u,v)是频率域中的点(u,v)到P \times Q频率矩形中心的距离,即:
式中,D0是一个正常数,D(u,v)是频率域中的点(u,v)到P×Q频率矩形中心的距离,即:
D
(
u
,
v
)
=
[
(
u
−
P
2
)
2
+
(
v
−
Q
2
)
2
]
1
2
D(u,v) = \left[ \left(u-\frac{P}{2}\right)^2 + \left(v-\frac{Q}{2}\right)^2 \right]^\frac{1}{2}
D(u,v)=[(u−2P)2+(v−2Q)2]21
式中
P
,
Q
可以理解成滤波器的大小
式中\quad P,Q \quad可以理解成滤波器的大小
式中P,Q可以理解成滤波器的大小
如上图所示:理想一词表示在半径为
D
0
D_0
D0 的圆内,所有频率都会无衰减地通过,而在该圆之外的所有频率则完全被衰减(滤除)。
2.1.2 示例代码
import cv2 as cv
import numpy as np
import matplotlib.pyplot as plt
def genIdealLowpassFilters(radius, shape):
"""
Generate an ideal low pass filter
Those inside the circle are marked 1 and those outside are marker 0.
:param radius: The radius of the circle.
:param shape: The shape of the mask (the mask is also an image)
:return:
"""
mask = np.zeros(shape, np.uint8)
center = np.array([shape[0] // 2, shape[1] // 2])
for i in range(shape[0]):
for j in range(shape[1]):
point = np.array([i, j])
distance = np.linalg.norm(point - center)
if distance <= radius:
# print(distance, radius)
mask[i][j] = 1
return mask
def imageSmoothing(image, radius):
"""
Image smoothing in the frequency domain using low pass filters.
:param image: raw image
:param radius: A parameter used to generate the low pass filters.
:return: smoothed image
"""
# 对原图像进行傅里叶变换,生成频谱图
dft = cv.dft(np.float32(image), flags=cv.DFT_COMPLEX_OUTPUT)
# 将频谱图上的低频移至中心
f_shift = np.fft.fftshift(dft)
# 生成低频滤波器
mask = genIdealLowpassFilters(radius, (image.shape[0], image.shape[1], 2))
f = f_shift * mask # 将掩模与傅里叶变化后的图像相乘,保留四周部分,即保留低频部分
# 将低频从中心移回原处
i_shift = np.fft.ifftshift(f)
# 进行计算傅里叶逆变换,将频谱图还原回空间域图像
dst = cv.idft(i_shift)
# 计算还原图像的幅度,并进行归一化处理
dst = cv.magnitude(dst[:, :, 0], dst[:, :, 1])
return dst
if __name__ == '__main__':
img = cv.imread('Image/Fig0601.tif', 0)
img1 = imageSmoothing(img, 10)
img2 = imageSmoothing(img, 20)
img3 = imageSmoothing(img, 40)
img4 = imageSmoothing(img, 80)
img5 = imageSmoothing(img, 160)
img6 = imageSmoothing(img, 360)
img7 = imageSmoothing(img, 460)
# 图像显示
plt.rcParams['font.sans-serif'] = ['SimHei']
plt.rcParams['font.size'] = 20
plt.figure(figsize=(20, 10))
imagesLst = [img, img1, img2, img3, img4, img5, img6, img7]
labelLst = ["Original Image", "Radius=10", "Radius=20", "Radius=40", "Radius=80",
"Radius=160", "Radius=320", "Radius=460"]
for i in range(8):
plt.subplot(2, 4, i + 1), plt.title(labelLst[i]), plt.axis('off')
plt.imshow(imagesLst[i], cmap='gray')
plt.tight_layout()
plt.savefig("Image/tmp.png")
plt.show()
2.1.3 示例效果
如上图所示:
当半径 Radius=10 的时候,图像的大部分高频部分(即图像的细节)包含在被滤波器去除的那部分中,因此导致图像的模糊非常严重
随着半径增大,也就是可以通过的频率越来越多,图像的模糊也越来越弱
当 Radius=20 和 Radius=40 的时候可以看出图像有很明显的振铃现象,但是随着被滤除的高频内容越来越少,振铃效应也变得越来越弱,当 Radius = 460 时,振铃效应几乎无法觉察
2.2 高斯低通滤波
在以原点为中心的一个圆内以衰减的方式通过所有频率,并且衰减的方式符合高斯分布,而在这个圆外 “截止” 所有频率的二维低通滤波器,称为 高斯低通滤波器。
2.2.1 理论基础
**高斯低通滤波器(GLPF)**低通滤波器的传递函数有如下形式:
H
(
u
,
v
)
=
e
−
D
2
(
u
,
v
)
2
σ
2
令
σ
=
D
0
可得:
H(u,v)=e^{\frac{-D^2(u,v)}{2\sigma^2}} \quad 令\quad\sigma=D_0\quad可得:
H(u,v)=e2σ2−D2(u,v)令σ=D0可得:
H
(
u
,
v
)
=
e
−
D
2
(
u
,
v
)
2
D
0
2
H(u,v)=e^{\frac{-D^2(u,v)}{2D_0^2}}
H(u,v)=e2D02−D2(u,v)
我们先分析下图:
从上图以及推导公式中可以看出,当
D
(
u
,
v
)
=
0
D(u,v)=0
D(u,v)=0 时,
H
(
u
,
v
)
=
1
H(u,v)=1
H(u,v)=1 此时原点处的频率全通过(无需衰减),而随着
D
(
u
,
v
)
D(u,v)
D(u,v) 不断增大,
H
(
u
,
v
)
H(u,v)
H(u,v) 开始减少,但
0
<
H
(
u
,
v
)
<
1
0 < H(u,v) < 1
0<H(u,v)<1,此时的频率以衰减的方式通过,如上图中的
b
b
b 图。
2.2.2 示例代码
import cv2 as cv
import numpy as np
import matplotlib.pyplot as plt
def genGaussianLowpassFilters(sigma, shape):
"""
Generate a gaussian low pass filter
:param sigma: The standard deviation of the gaussian filter.
:param shape: The shape of the mask (the mask is also an image)
:return: Returns a gaussian low pass filter.
"""
mask = np.zeros(shape, np.float32)
rows, cols = shape[0], shape[1]
center_x, center_y = rows // 2, cols // 2
for i in range(rows):
for j in range(cols):
distance = (i - center_x) ** 2 + (j - center_y) ** 2
mask[i][j] = np.exp(-distance / (2 * sigma ** 2))
return mask
def imageSmoothing(image, sigma):
"""
Image smoothing in the frequency domain using the gaussian low pass filters.
:param image: raw image
:param sigma: The standard deviation of the gaussian filter.
:return: smoothed image
"""
# 对原图像进行傅里叶变换,生成频谱图
dft = cv.dft(np.float32(image), flags=cv.DFT_COMPLEX_OUTPUT)
# 将频谱图上的低频移至中心
f_shift = np.fft.fftshift(dft)
# 生成低频滤波器
mask = genGaussianLowpassFilters(sigma, (image.shape[0], image.shape[1], 2))
f = f_shift * mask # 将掩模与傅里叶变化后的图像相乘,保留四周部分,即保留低频部分
# 将低频从中心移回原处
i_shift = np.fft.ifftshift(f)
# 进行计算傅里叶逆变换,将频谱图还原回空间域图像
dst = cv.idft(i_shift)
# 计算还原图像的幅度,并进行归一化处理
dst = cv.magnitude(dst[:, :, 0], dst[:, :, 1])
return dst
if __name__ == '__main__':
img = cv.imread('Image/Fig0603.tif', 0)
img1 = imageSmoothing(img, 10)
img2 = imageSmoothing(img, 20)
img3 = imageSmoothing(img, 40)
img4 = imageSmoothing(img, 80)
img5 = imageSmoothing(img, 160)
img6 = imageSmoothing(img, 320)
img7 = imageSmoothing(img, 460)
# 图像显示
plt.rcParams['font.sans-serif'] = ['SimHei']
plt.rcParams['font.size'] = 20
plt.figure(figsize=(20, 10))
imagesLst = [img, img1, img2, img3, img4, img5, img6, img7]
labelLst = ["Original Image", "Sigma=10", "Sigma=20", "Sigma=40", "Sigma=80",
"Sigma=160", "Sigma=320", "Sigma=460"]
for i in range(8):
plt.subplot(2, 4, i + 1), plt.title(labelLst[i]), plt.axis('off')
plt.imshow(imagesLst[i], cmap='gray')
plt.tight_layout()
plt.savefig("Image/tmp.png")
plt.show()
2.2.3 示例效果
与ILPF相比,GLPF实现的平滑要稍微少一些,但是GLPF不会出现振铃效应。
2.3 巴特沃斯低通滤波
在以原点为中心的一个圆内以衰减的方式通过所有频率,并且衰减的方式符合一定条件的(下面会讲述)分布,而在这个圆外 “截止” 所有频率的二维低通滤波器,称为 巴特沃斯低通滤波器。
2.3.1 理论基础
巴特沃斯低通滤波器的传递函数定义为:
H
(
u
,
v
)
=
1
1
+
[
D
(
u
,
v
)
D
0
]
2
n
H(u,v)=\frac{1}{1+\left[\frac{D(u,v)}{D_0}\right]^{2n}}
H(u,v)=1+[D0D(u,v)]2n1我们先分析下图:
从上图可以看出:
当我们使用较高的
n n n时
, B L P F BLPF BLPF可以逼近
I L P F ILPF ILPF的特性
当我们使用较低的
n n n时
, B L P F BLPF BLPF可以逼近
G L P F GLPF GLPF的特性
2.3.2 示例代码
import cv2 as cv
import numpy as np
import matplotlib.pyplot as plt
def genButterworthLowpassFilters(n, D0, shape):
"""
Generate a butterworth low pass filter
:param n: The param of the transfer function
:param D0: The cut-off frequency of the low pass filter
:param shape: image shape
:return: A butterworth low pass filter
"""
mask = np.zeros(shape, np.float32)
rows, cols = shape[0], shape[1]
center_x, center_y = rows // 2, cols // 2
for i in range(rows):
for j in range(cols):
distance = np.sqrt((i - center_x) ** 2 + (j - center_y) ** 2)
mask[i, j] = 1 / (1 + (distance / D0) ** (2 * n))
return mask
def imageSmoothing(image, n, D0):
"""
Image smoothing in the frequency domain using the butterworth low pass filters.
:param image: raw image
:param n: The param of the transfer function
:param D0: The cut-off frequency of the low pass filter
:return: smoothed image
"""
# 对原图像进行傅里叶变换,生成频谱图
dft = cv.dft(np.float32(image), flags=cv.DFT_COMPLEX_OUTPUT)
# 将频谱图上的低频移至中心
f_shift = np.fft.fftshift(dft)
# 生成低频滤波器
mask = genButterworthLowpassFilters(n, D0, (image.shape[0], image.shape[1], 2))
f = f_shift * mask # 将掩模与傅里叶变化后的图像相乘,保留四周部分,即保留低频部分
# 将低频从中心移回原处
i_shift = np.fft.ifftshift(f)
# 进行计算傅里叶逆变换,将频谱图还原回空间域图像
dst = cv.idft(i_shift)
# 计算还原图像的幅度,并进行归一化处理
dst = cv.magnitude(dst[:, :, 0], dst[:, :, 1])
return dst
if __name__ == '__main__':
img = cv.imread('Image/Fig0603.tif', 0)
img1 = imageSmoothing(img, 1,10)
img2 = imageSmoothing(img, 1,20)
img3 = imageSmoothing(img, 1,40)
img4 = imageSmoothing(img, 1,80)
img5 = imageSmoothing(img, 1,160)
img6 = imageSmoothing(img, 1,320)
img7 = imageSmoothing(img, 1,460)
# 图像显示
plt.rcParams['font.sans-serif'] = ['SimHei']
plt.rcParams['font.size'] = 20
plt.figure(figsize=(20, 10))
imagesLst = [img, img1, img2, img3, img4, img5, img6, img7]
labelLst = ["Original Image", "n=1 D0=10", "n=1 D0=20", "n=1 D0=40", "n=1 D0=80",
"n=1 D0=160", "n=1 D0=320", "n=1 D0=460"]
for i in range(8):
plt.subplot(2, 4, i + 1), plt.title(labelLst[i]), plt.axis('off')
plt.imshow(imagesLst[i], cmap='gray')
plt.tight_layout()
plt.savefig("Image/tmp.png")
plt.show()
2.3.3 示例效果
通过与上面两种低频滤波器对比分析可得:
- 从模糊效果上看, B L P F BLPF BLPF 介于 I L P F ILPF ILPF 和 G L P F GLPF GLPF 之间,小于 I L P F ILPF ILPF ,但大于 G L P F GLPF GLPF
- 从振铃效应上看,当 n = 1 n=1 n=1 时,没有振铃,此时 B L P F BLPF BLPF 逼近 G L P F GLPF GLPF,当 n n n 逐渐增大时,振铃效应也随之强烈,此时 B L P F BLPF BLPF 逼近 I L P F ILPF ILPF
3. 三种低频滤波器的比较分析
滤波类型 | 振铃效应 | 图像模糊 | 噪声 |
---|---|---|---|
ILPF | 严重 | 严重 | 比较好 |
BLPF | 低阶无 | 较轻 | 一般 |
GLPF | 无 | 较轻 | 一般 |