03 数字图像技术——频域滤波实验结果与分析——python

04 数字图像技术——图像特征提取之实验结果与分析
03 数字图像技术——频域滤波实验结果与分析
02 数字图像技术——颜色空间转换与颜色空间分割实验结果与分析
01 数字图像基本操作——图像采样、量化、算术运算、点运算实验结果及分析

一、实验目的

1.了解图像变换的意义和手段;
2.熟悉傅里叶变换的基本性质;
3.熟练掌握FFT变换方法及应用;
4.通过实验了解二维频谱的分布特点;
5.通过本实验掌握利用python编程实现数字图像的傅里叶变换。

二、实验内容

1. 实现数字图像的FFT变换。
2. 掌握图像FFT变换的性质。
3. 图像FFT变换的性质体现规律和特点分析。
4. 实现低通滤波器。

三、实验设备/仪器

电脑、编程语言(Matlab或Python)、图像数据和存储器。

四、实验原理

1.应用傅里叶变换进行图像处理
  傅里叶变换是线性系统分析的一个有力工具,它能够定量地分析诸如数字化系统、采样点、电子放大器、卷积滤波器、噪音和显示点等的作用。通过实验培养这项技能,将有助于解决大多数图像处理问题。对任何想在工作中有效应用数字图像处理技术的人来说,把时间用在学习和掌握博里叶变换上是很有必要的。
2.傅里叶(Fourier)变换的定义
对于二维信号,二维Fourier变换定义为:
在这里插入图片描述

逆变换:
在这里插入图片描述

二维离散傅里叶变换为:
在这里插入图片描述

逆变换:
在这里插入图片描述

  图像的傅立叶变换与一维信号的傅立叶变换变换一样,有快速算法,具体参见参考书目,有关傅立叶变换的快速算法的程序不难找到。实际上,现在有实现傅立叶变换的芯片,可以实时实现傅立叶变换。

五、实验步骤与要求

  1. 编写python代码,实现一维信号的傅里叶变换;
  2. 编写python代码,实现图像的二维傅里叶变换;
  3. 编写python代码,实现理想低通滤波器;
  4. 编写python代码,实现巴特沃斯低通滤波器。
  5. 记录和整理实验报告。

六、各实验流程图、结果及分析

1. 编写python代码,实现一维信号的傅里叶变换;
03 数字图像技术——频域滤波实验结果与分析——python_第1张图片

图 1 基于傅里叶变换的数字图像频域处理过程

03 数字图像技术——频域滤波实验结果与分析——python_第2张图片

图 2 一维信号的傅里叶变换流程图

代码如下:

import matplotlib.pyplot as plt
import numpy as np
"""中文显示工具函数"""
def set_ch():
    from pylab import mpl
    mpl.rcParams['font.sans-serif']=['FangSong']
    mpl.rcParams['axes.unicode_minus']=False
set_ch()
def show(ori_func, ft, sampling_period = 5):
    n = len(ori_func)
    interval = sampling_period / n
    # 绘制原始函数
    plt.subplot(2, 1, 1)
    plt.plot(np.arange(0, sampling_period, interval), ori_func, 'black')
    plt.xlabel('时间'), plt.ylabel('振幅')
    plt.title('原始信号')
    # 绘制变换后的函数
    plt.subplot(2,1,2)
    frequency = np.arange(n / 2) / (n * interval)
    nfft = abs(ft[range(int(n / 2))] / n )
    plt.plot(frequency, nfft, 'red')
    plt.xlabel('频率 (Hz)'), plt.ylabel('频率谱')
    plt.title('傅里叶变换结果')
    plt.show()

#生成频率为 1(角速度为 2 * pi)的正弦波
time = np.arange(0, 5, .005)
x = np.sin(2 * np.pi * 1 * time)
y = np.fft.fft(x)
show(x, y)
x2 = np.sin(2 * np.pi * 10 * time)
x3 = np.sin(2 * np.pi * 40 * time)
x+=x2+x3
y = np.fft.fft(x)
show(x, y)
 

03 数字图像技术——频域滤波实验结果与分析——python_第3张图片

图 3 单一正弦波傅里叶变换结果

03 数字图像技术——频域滤波实验结果与分析——python_第4张图片

图 4 3个正弦波形叠加的傅里叶变换结果

  从图中可以看出,这三个正弦波形进行叠加得出的图像都具备了各自波形的特点,当进行傅里叶变化时,每个基函数都是一个单频率谐波。

2. 编写python代码,实现图像的二维傅里叶变换;
03 数字图像技术——频域滤波实验结果与分析——python_第5张图片

图 5 二维傅里叶变换流程图

代码如下:

from skimage import data,io,color
import numpy as np
from matplotlib import pyplot as plt
import cv2 as cv
"""中文显示工具函数"""
def set_ch():
    from pylab import mpl
    mpl.rcParams['font.sans-serif']=['FangSong']
    mpl.rcParams['axes.unicode_minus']=False
set_ch()
# img = data.camera()
#img = io.imread('D:\shuzi_image\cat.jpg')
img = cv.imread('D:\shuzi_image\cat.jpg')
img=color.rgb2gray(img)
f = np.fft.fft2(img) # 快速傅里叶变换算法得到频率分布
fshift = np.fft.fftshift(f) # 默认结果中心点位置是在左上角,转移到中间位置
fimg = np.log(np.abs(fshift)) # fft 结果是复数,求绝对值结果才是振幅
# 展示结果
plt.subplot(121), plt.imshow(img, 'gray'), plt.title('原始图像')
#plt.subplot(122), plt.imshow(fimg, 'gray'), plt.title('傅里叶频谱')
plt.subplot(122)
fimg=fimg.astype(np.uint8)
cv.namedWindow('image')
cv.imshow("image",fimg*23)
cv.waitKey()
plt.show()

当默认结果中心点位置是在左上角时,结果如下:
03 数字图像技术——频域滤波实验结果与分析——python_第6张图片

图 6 图像的二维傅里叶变换结果

默认结果中心点位置是在左上角,转移到中间位置时的结果如下:
03 数字图像技术——频域滤波实验结果与分析——python_第7张图片

图 7 图像的二维傅里叶变换结果

  可得到:变换之后的图像在原点平移之前四角是低频,最亮,平移之后中间部分是低频,最亮,亮度大说明低频的能量大。
棋盘图像对应的傅里叶变换代码如下:
from skimage import data
import numpy as np
from matplotlib import pyplot as plt
"""中文显示工具函数"""
def set_ch():
    from pylab import mpl
    mpl.rcParams['font.sans-serif']=['FangSong']
    mpl.rcParams['axes.unicode_minus']=False
set_ch()

img = data.checkerboard()
f = np.fft.fft2(img) # 快速傅里叶变换算法得到频率分布
fshift = np.fft.fftshift(f) # 默认结果中心点位置是在左上角,转移到中间位置
fimg = np.log(np.abs(fshift)) # fft 结果是复数,求绝对值结果才是振幅
# 展示结果
plt.subplot(121), plt.imshow(img, 'gray'), plt.title('原始图像')
plt.subplot(122), plt.imshow(fimg, 'gray'), plt.title('傅里叶频谱')
plt.show()

03 数字图像技术——频域滤波实验结果与分析——python_第8张图片

图 8 棋盘图像的傅里叶变换结果

使用两次一维傅里叶变换代替二维傅里叶变换的代码如下:

from matplotlib import pyplot as plt
import numpy as np
from skimage import data, color,io
import cv2 as cv

# 中文显示工具函数
def set_ch():
    from pylab import mpl
    mpl.rcParams['font.sans-serif'] = ['FangSong']
    mpl.rcParams['axes.unicode_minus'] = False

set_ch()
img1 = io.imread('D:\shuzi_image\cat.jpg')
img = color.rgb2gray(img1)
# 在X方向实现傅里叶变换
m, n = img.shape
fx = img
for x in range(n):
    fx[:, x] = np.fft.fft(img[:, x])
for y in range(m):
    fx[y, :] = np.fft.fft(img[y, :])
# 默认结果中心点位于左上角,转移到中间位置
fshift = np.fft.fftshift(fx)
# fft结果是复数,求绝对值结果才是振幅
fimg = np.log(np.abs(fshift))

# 展示结果
plt.subplot(121), plt.imshow(img1, 'gray'), plt.title('原始图像')
plt.subplot(122), plt.imshow(fimg, 'gray'), plt.title('两次一维傅里叶变换的图像')
plt.show()

03 数字图像技术——频域滤波实验结果与分析——python_第9张图片

图 9 使用两次一维傅里叶变换代替二维傅里叶变换的结果

  分析:图像经傅里叶变换后,直流分量与图像均值成正比,高频分量则表明了图像中目标边缘的强度及方向。二维离散傅里叶变换,可视为由沿着x、y方向的两个一维傅里叶变换所构成。这一性质可有效降低二维傅里叶变换的计算复杂性,而且得到效果和一般图像的二维傅里叶变换结果一样。

3. 编写python代码,实现理想低通滤波器;
03 数字图像技术——频域滤波实验结果与分析——python_第10张图片

图 10 实现理想低通滤波器流程图

代码如下:

#导入相关库
from skimage import data,color,io
import numpy as np
import matplotlib.pyplot as plt
import cv2 as cv
"""中文显示工具函数"""
def set_ch():
    from pylab import mpl
    mpl.rcParams['font.sans-serif']=['FangSong']
    mpl.rcParams['axes.unicode_minus']=False
set_ch()

D=10
#读入图片
#new_img=data.coffee()

new_img = io.imread('D:\shuzi_image\cat.jpg')
new_img=color.rgb2gray(new_img)

#numpy中的傅里叶变化
f1=np.fft.fft2(new_img)
f1_shift=np.fft.fftshift(f1)
#np.fft.fftshift()函数来实现平移,让直流分量在输出图像的重心

#实现理想低通滤波器
rows,cols=new_img.shape
crow,ccol=int(rows/2),int(cols/2) #计算频谱中心
mask=np.zeros((rows,cols),np.uint8) #生成rows行cols的矩阵,数据格式为uint8
for i in range(rows):
    for j in range(cols):
        if np.sqrt(i*i+j*j)<=D:
            # 将距离频谱中心小于D的部分低通信息 设置为1,属于低通滤波
            mask[crow - D:crow + D, ccol - D:ccol + D] = 1

# img = np.zeros((200, 200), dtype = np.uint8)  #创建黑色空白图像
# img[50:150, 50:150] = 255   # 图像中央放置白色方块

f1_shift=f1_shift*mask
cv.imshow("mask",mask*255)
cv.waitKey(0)
#傅里叶逆变换
f_ishift=np.fft.ifftshift(f1_shift)
img_back=np.fft.ifft2(f_ishift)
img_back=np.abs(img_back)
img_back=(img_back-np.amin(img_back))/(np.amax(img_back)-np.amin(img_back))

#plt.figure(figsize=(15,8))
plt.figure()
plt.subplot(121),plt.imshow(new_img,cmap='gray'),plt.title('原始图像')
plt.subplot(122),plt.imshow(img_back,cmap='gray'),plt.title('滤波后图像')
plt.show()

当截断频率D设置为100时:

03 数字图像技术——频域滤波实验结果与分析——python_第11张图片
03 数字图像技术——频域滤波实验结果与分析——python_第12张图片

图 11 截断频率为100时的理想低通滤波器结果

当截断频率D设置为10时:

03 数字图像技术——频域滤波实验结果与分析——python_第13张图片
03 数字图像技术——频域滤波实验结果与分析——python_第14张图片

图 12 截断频率为10时的理想低通滤波器结果

  从实验可以看出当截断频率D设置得越大时,中心频谱的范围越大,即更多的频率分量可以完全无损的通过,图像越清晰。当D设置得越小时,滤波后的图像越模糊。

4. 编写python代码,实现巴特沃斯低通滤波器。
03 数字图像技术——频域滤波实验结果与分析——python_第15张图片

图 13 实现巴特沃斯低通滤波器流程图

代码如下:

import numpy as np
import matplotlib.pyplot as plt
import numpy as np
from skimage import data,color,io

if __name__ == "__main__":
    #img = data.coffee()
    img = io.imread('D:\shuzi_image\cat.jpg')
    img=color.rgb2gray(img)#直接读为灰度图像
    f = np.fft.fft2(img)
    fshift = np.fft.fftshift(f)

    #取绝对值:将复数变化成实数
    #取对数的目的为了将数据变化到0-255
    s1 = np.log(np.abs(fshift))
    """
    巴特沃斯低通滤波器
    """
    def butterworthPassFilter(image, d, n):
        f = np.fft.fft2(image)
        fshift = np.fft.fftshift(f)

        def make_transform_matrix(d):
            transfor_matrix = np.zeros(image.shape)
            center_point = tuple(map(lambda x: (x - 1) / 2, s1.shape))
            for i in range(transfor_matrix.shape[0]):
                for j in range(transfor_matrix.shape[1]):
                    def cal_distance(pa, pb):
                        from math import sqrt
                        dis = sqrt((pa[0] - pb[0]) ** 2 + (pa[1] - pb[1]) ** 2)
                        return dis

                    dis = cal_distance(center_point, (i, j))
                    transfor_matrix[i, j] = 1 / (1 + (dis / d) ** (2*n))
            return transfor_matrix
        d_matrix = make_transform_matrix(d)
        new_img = np.abs(np.fft.ifft2(np.fft.ifftshift(fshift * d_matrix)))
        return new_img

    plt.subplot(221)
    plt.axis("off")
    plt.title('Original')
    plt.imshow(img,cmap='gray')

    plt.subplot(222)
    plt.axis('off')
    plt.title('Butter D=100 n=1')
    butter_100_1=butterworthPassFilter(img,100,1)
    plt.imshow(butter_100_1,cmap='gray')
    plt.subplot(223)
    plt.axis('off')
    plt.title('Butter D=40 n=1')
    butter_30_1=butterworthPassFilter(img,40,3)
    plt.imshow(butter_30_1,cmap='gray')
    plt.subplot(224)
    plt.axis('off')
    plt.title('Butter D=40 n=5')
    butter_30_5=butterworthPassFilter(img,40,5)
    plt.imshow(butter_30_5,cmap='gray')
plt.show()

当设置不同的截断频率D,和不同的函数的阶n时,图像的结果如下:
03 数字图像技术——频域滤波实验结果与分析——python_第16张图片
03 数字图像技术——频域滤波实验结果与分析——python_第17张图片

图 14 二维图像的巴特沃斯低通滤波结果

  从实验中可以看出,用此滤波后的输出图像振铃现象不明显。n=1时,过渡最平滑,即尾部包含有大量的高频成分,所以一阶低通滤波器没有振铃现象;但随着n的增加,振铃现象会越来越明显,而且当截止频率D设置得越小时,滤波后的图像越模糊。

七、实验总结

  •   (1)傅里叶变换是一种正交数学变换,可以将一维信号或函数分解为具有不同频率、不同幅度的正弦信号或余弦信号的组合。几乎“所有”信号或函数都可以分解成简单的正弦波和余弦波之和。
  •   (2)二维傅里叶变换本质是将一维变换向二维进行拓展。图像经傅里叶变换后,直流分量与图像均值成正比,高频分量则表明了图像中目标边缘的强度及方向。二维离散傅里叶变换,可视为由沿着x、y方向的两个一维傅里叶变换所构成。这一性质可有效降低二维傅里叶变换的计算复杂性,而且得到效果和一般图像的二维傅里叶变换结果一样。
  •   (3)理想低通滤波器的含小于D的频率,即以D为半径的圆内的有频率分量可以完全无损地通过,而圆外的频率,即大于D的频率分量则完全被除掉。理想低通滤波器的平滑作用非常明显,当截断频率D设置得越大时,中心频谱的范围越大,即更多的频率分量可以完全无损的通过,图像越清晰。当D设置得越小时,出现了明显的振铃现象,滤波后的图像越模糊。
  •   (4)与理想低通滤波器相比,高低频之间过渡较为平滑,用此滤波后的输出图像振铃现象不明显。n=1时,过渡最平滑,即尾部包含有大量的高频成分,所以一阶Butterworth低通滤波器没有振铃现象;但随着n的增加,振铃现象会越来越明显。

你可能感兴趣的:(数字图像,python,图像处理)