数字图像处理个人练习03--频域增强

本文介绍了频域变换的概念,区分了傅里叶级数和傅里叶变换,并详细探讨了频域处理在图像平滑(理想低通、巴特沃斯低通、高斯滤波)和锐化(理想高通)中的应用。使用Python库cv2、numpy和matplotlib实现并展示了三种滤波算法的实例,包括ILPF、BLPF和GLPF。

1. 什么是频域变换?

定义:频域也称为频率域,将复杂的时间信号或空间信号变换成以频率成分表示的结构形式就是频域变换。是描述信号的频率结构与信号幅度的关系。将复杂的时间信号或空间信号变换成以频率成分表示的结构形式就是频域变换。

2. 傅里叶级数与傅里叶变换的区别。

傅里叶级数是周期变换,傅里叶变换是一种非周期变换

傅里叶级数用于对周期信号转换,傅里叶变换用于对非周期信号转换。

傅里叶级数是以三角函数为基对周期信号的无穷级数展开,如果把周期函数的周期取作无穷大,对傅里叶级数取极限即得到傅里叶变换。

傅里叶变换是从傅里叶级数推演而来的,傅里叶级数是所有周期函数都可以分解成一系列的正交三角函数,这样,周期函数对应的傅里叶级数即是它的频谱函数。

傅里叶级数是周期信号的另一种时域的表达方式,也就是正交级数,它不同频率的波形的叠加,而傅里叶变换就是完全的频域分析。

傅里叶级数仅适用于周期信号,傅里叶变换可以视作傅里叶级数的延伸,可以用于分析非周期信号的频谱特性。事实上,引入冲击函数后,周期信号也可以进行傅里叶变换。

3. 与空域变换相比,频域变换的优缺点。

空间域(spatial domain)也叫空域,即所说的像素域,在空域的处理就是在像素级的处理,如在像素级的图像叠加。通过傅立叶变换后,得到的是图像的频谱。表示图像的能量梯度。

频域(频率域)——自变量是频率,即横轴是频率,纵轴是该频率信号的幅度,也就是通常说的频谱图。频谱图描述了信号的频率结构及频率与该频率信号幅度的关系。

一些在空间域难以表述的任务,在频率域中变得简单直接。 滤波在频率域更为直观,它可以解释空间域滤波的某 些性质。

4. 调用函数库,实现2种频域平滑算法 + 5. 调用函数库,实现2种频域锐化算法

环境搭配:

python3.9

调用库

cv2
numpy
matplotlib

理想高通和理想低通

(增强高通,平滑低通)

函数说明

def ILPF(alpha, image):

此处的alpha指代距离中心的距离

核心代码

for i in range(mat.shape[0]):
    for j in range(mat.shape[1]):
        dis = np.sqrt((center[0] - i)**2 + (center[1]-j)**2)
        if dis <= alpha:
            mat[i,j] = 1
            mat1[i,j]= 0
        else:
            mat[i,j] = 0
            mat1[i,j]= 1
new_img = np.abs(np.fft.ifft2(np.fft.ifftshift(fshift * mat)))

当传入alpha=15时候
在这里插入图片描述

当传入alpha=30时候
在这里插入图片描述
当传入alpha=45时候
在这里插入图片描述

巴特沃斯高通和低通

高通函数变化
H(u,v)=11+[D0/D(u,v)]2nH(u,v)=\frac{1}{1+[D_0/D(u,v)]^{2n}}H(u,v)=1+[D0/D(u,v)]2n1
低通
H(u,v)=11+[D(u,v)/D0]2nH(u,v)=\frac{1}{1+[D(u,v)/D_0]^{2n}}H(u,v)=1+[D(u,v)/D0]2n1

函数说明

def BLPF(alpha, beta, image):

alpha为D0,beta为指数n

核心代码

for i in range(mat.shape[0]):
    for j in range(mat.shape[1]):
        dis = np.sqrt((center[0] - i)**2 + (center[1]-j)**2)
        mat[i,j] = 1/ (1 + ((dis / alpha) ** (2*beta)))
        mat1[i,j]= 1/(1+((alpha/dis) **(2*beta)))

new_img = np.abs(np.fft.ifft2(np.fft.ifftshift(fshift * mat)))

alpha = 5, beta = 3
在这里插入图片描述
alpha = 15, beta = 3
在这里插入图片描述
alpha = 5, beta = 6
在这里插入图片描述

高斯

高通函数变化
H(u,v)=1−e−D2(u,v)/2σ2H(u,v)=1-e^{-D^2(u,v)/2\sigma^2}H(u,v)=1eD2(u,v)/2σ2
低通
H(u,v)=e−D2(u,v)/2σ2H(u,v)=e^{-D^2(u,v)/2\sigma^2}H(u,v)=eD2(u,v)/2σ2

函数说明

def GLPF(alpha, image):

alpha为sigma

核心代码

for i in range(mat.shape[0]):
    for j in range(mat.shape[1]):
        dis = np.sqrt((center[0] - i)**2 + (center[1]-j)**2)
        mat[i,j] = np.exp(-(dis**2)/(2*alpha**2))
        
    
        mat1[i,j] = 1 - np.exp(-(dis ** 2) / (2 * (alpha ** 2)))
new_img = np.abs(np.fft.ifft2(np.fft.ifftshift(fshift * mat)))

σ\sigmaσ = 40的情况
在这里插入图片描述

实现汇总


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

class frequency_domain_smoothing_filter():
    def ILPF(alpha, image):
        #此处ILPF和IHPF都实现了
        #用mat和mat1装两个不同的矩阵变换
        #cv2.imshow("",image)
        gray = cv2.cvtColor(image, cv2.COLOR_RGB2GRAY)
        cv2.imshow("",gray)
        fft2 = np.fft.fft2(gray)
        fshift = np.fft.fftshift(fft2)
        s1 = np.log(np.abs(fshift))

        mat = np.zeros(fshift.shape)
        mat1 = np.zeros(fshift.shape)
        center = tuple(map(lambda x:(x-1)/2, s1.shape))
        for i in range(mat.shape[0]):
            for j in range(mat.shape[1]):
                dis = np.sqrt((center[0] - i)**2 + (center[1]-j)**2)
                if dis <= alpha:
                    mat[i,j] = 1
                    mat1[i,j]= 0
                else:
                    mat[i,j] = 0
                    mat1[i,j]= 1

        cv2.imshow("mat", mat)
        
        #频率域经过ILPF变换后再进行逆变换还原到时域图像
        new_img = np.abs(np.fft.ifft2(np.fft.ifftshift(fshift * mat)))
        #带1为H变换
        new_img1 = np.abs(np.fft.ifft2(np.fft.ifftshift(fshift * mat1)))
        #数据为浮点数,所以用plt进行显示
        # plt.subplot(221)
        # plt.imshow(new_img)
        # plt.axis('off')
        # plt.subplot(222)
        # plt.imshow(new_img1)
        # plt.axis('off')

        plt.subplot(121)
        plt.imshow(new_img,cmap = 'gray')
        plt.axis('off')
        plt.title("I low")

        plt.subplot(122)
        plt.imshow(new_img1,cmap = 'gray')
        plt.axis('off')
        plt.title("I high")
        plt.show()
        cv2.waitKey(0)

    def BLPF(alpha, beta, image):
        #cv2.imshow("",image)
        gray = cv2.cvtColor(image, cv2.COLOR_RGB2GRAY)
        cv2.imshow("",gray)
        fft2 = np.fft.fft2(gray)
        fshift = np.fft.fftshift(fft2)
        s1 = np.log(np.abs(fshift))

        mat = np.zeros(gray.shape)
        mat1 = np.zeros(gray.shape)
        
        center = tuple(map(lambda x:(x-1)/2, s1.shape))
        for i in range(mat.shape[0]):
            for j in range(mat.shape[1]):
                dis = np.sqrt((center[0] - i)**2 + (center[1]-j)**2)
                mat[i,j] = 1/ (1 + ((dis / alpha) ** (2*beta)))
                mat1[i,j]= 1/(1+((alpha/dis) **(2*beta)))

        new_img = np.abs(np.fft.ifft2(np.fft.ifftshift(fshift * mat)))
        new_img1 = np.abs(np.fft.ifft2(np.fft.ifftshift(fshift * mat1)))

        # plt.subplot(221)
        # plt.imshow(new_img)
        # plt.axis('off')
        # plt.subplot(222)
        # plt.imshow(new_img1)
        # plt.axis('off')

        plt.subplot(121)
        plt.imshow(new_img,cmap = 'gray')
        plt.axis('off')
        plt.title("B low")

        plt.subplot(122)
        plt.imshow(new_img1,cmap = 'gray')
        plt.axis('off')
        plt.title("B high")
        plt.show()
        cv2.waitKey(0)
    
    def GLPF(alpha, image):
        #cv2.imshow("",image)
        gray = cv2.cvtColor(image, cv2.COLOR_RGB2GRAY)
        fft2 = np.fft.fft2(gray)
        fshift = np.fft.fftshift(fft2)
        s1 = np.log(np.abs(fshift))

        mat = np.zeros(fshift.shape)
        mat1 = np.zeros(fshift.shape)
        center = tuple(map(lambda x:(x-1)/2, s1.shape))
        for i in range(mat.shape[0]):
            for j in range(mat.shape[1]):
                dis = np.sqrt((center[0] - i)**2 + (center[1]-j)**2)
                mat[i,j] = np.exp(-(dis**2)/(2*alpha**2))
                #mat[i,j] = 0.5+0.75*(1-np.exp(-(dis**2)/(2*(alpha**2))))
            
                mat1[i,j] = 1 - np.exp(-(dis ** 2) / (2 * (alpha ** 2)))
        new_img = np.abs(np.fft.ifft2(np.fft.ifftshift(fshift * mat)))
        new_img1 = np.abs(np.fft.ifft2(np.fft.ifftshift(fshift * mat1)))
        
        # plt.subplot(221)
        # plt.axis('off')
        # plt.imshow(new_img)
        # plt.subplot(222)
        # plt.axis('off')
        # plt.imshow(new_img1)


        plt.subplot(121)
        plt.axis('off')
        plt.title("G low")
        plt.imshow(new_img,cmap = 'gray')
        plt.subplot(122)
        plt.axis('off')
        plt.title("G high")
        plt.imshow(new_img1,cmap = 'gray')
        cv2.imshow("",gray)
        plt.show()
        cv2.waitKey(0)
def test():
    image = cv2.imread('pic4.png')
    #print(image)
    #frequency_domain_smoothing_filter.ILPF(15,image)
    #frequency_domain_smoothing_filter.ILPF(30,image)
    #frequency_domain_smoothing_filter.ILPF(50,image)

    #frequency_domain_smoothing_filter.BLPF(5, 3, image)
    #frequency_domain_smoothing_filter.BLPF(15, 3, image)
    #frequency_domain_smoothing_filter.BLPF(5, 6, image)
    
    frequency_domain_smoothing_filter.GLPF(40,image)
    

if __name__ == '__main__':
    
    test()

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值