《数字图像处理-OpenCV/Python》连载:傅里叶变换与频域滤波

news2024/11/14 21:36:04

《数字图像处理-OpenCV/Python》连载:空间滤波之高斯滤波器


本书京东 优惠购书链接 https://item.jd.com/14098452.html
本书CSDN 独家连载专栏 https://blog.csdn.net/youcans/category_12418787.html

在这里插入图片描述


第 11 章 傅里叶变换与频域滤波


空间图像滤波是图像与滤波器核的卷积,而空间卷积的傅里叶变换是频域中相应变换的乘积。因此,频域图像滤波是通过频域滤波器(传递函数)与图像的傅里叶变换相乘得到的。频域中的滤波概念更加直观,滤波器设计也更容易。


本章内容概要

  • 学习二维离散傅里叶变换的实现方法,介绍快速傅里叶变换的原理。
  • 学习频域滤波的基本步骤,以及构造滤波器传递函数的基本方法。
  • 学习常用的频域滤波器,如理想滤波器、高斯滤波器、巴特沃斯滤波器。
  • 介绍低通、高通、带通、带阻滤波器的关系,构造选择性滤波器。
  • 认识和比较空间滤波与频域滤波。

11.3 频域滤波的基本步骤

傅里叶变换的目的是将图像从空间域转换到频域,在频域内进行图像处理。

空间取样和频率间隔是相互对应的,频域中的样本间隔与空间样本间隔及样本数量的乘积成反比。空间滤波器和频域滤波器也是相互对应的,二者能形成如下的傅里叶变换对。

因此,计算两个函数的空间卷积,可以直接在空间域计算,也可以在频域计算。先计算每个函数的傅里叶变换,再将两个变换相乘,最后进行傅里叶逆变换转换回空间域。

频域图像滤波首先要对原始图像 f(x,y)做傅里叶变换 F(u,v) ;然后用滤波器传递函数 H(u,v) 对傅里叶变换的频谱进行处理,做傅里叶逆变换返回空间域,得到滤波图像 g(x,y)。具体变换过程如下。

(1) 对原始图像 f(x,y) 进行傅里叶变换和中心化,得到 F(u,v) 。
(2) 将图像的傅里叶变换 F(u,v) 与滤波器传递函数 H(u,v) 相乘,得到滤波频谱 G(u,v) 。
(3) 对 G(u,v) 进行逆中心化和傅里叶逆变换,得到滤波图像 g(x,y)。

使用尺寸最优扩充的快速傅里叶变换时,还包括变换前的图像扩充和变换后的图像裁剪。


【例程1104】频域图像滤波的基本步骤

本例程以理想低通滤波器为例,示范频域图像滤波的基本步骤。

设计低通滤波器的过程,是构造二维掩模图像的过程。简单地,构造一个中心开窗的遮罩图像,在黑色图像的中心区域设有白色窗口,就构成了一个低通滤波器。


# 【1104】频域图像滤波的基本步骤
import cv2 as cv
import numpy as np
from matplotlib import pyplot as plt

def ideaLPF(height, width, radius=10):  # 理想低通滤波器
    u, v = np.mgrid[-1:1:2.0/height, -1:1:2.0/width]
    Dist = cv.magnitude(u, v)
    D0 = radius/height  # 滤波器半径
    kernel = np.zeros((height, width), np.uint8)
    kernel[Dist <= D0] = 1
    return kernel

if __name__ == '__main__':
    # img = cv.imread("../images/Fig0515a.tif", flags=0)  # 读取为灰度图像
    img = cv.imread("../images/Fig1101.png", flags=0)  # 读取灰度图像
    height, width = img.shape[:2]  # (688,688)

    # (1) 对图像进行傅里叶变换,并将低频分量移动到中心
    imgFloat = img.astype(np.float32)  # 将图像转换成 float32
    dft = cv.dft(imgFloat, flags=cv.DFT_COMPLEX_OUTPUT)  # (512,512,2)
    dftShift = np.fft.fftshift(dft)  # (512,512,2)

    r = [30, 60, 90]  # 低通滤波器的半径
    plt.figure(figsize=(9, 6))
    for i in range(3):
        # (2) 构造低通滤波器
        mask = ideaLPF(height, width, r[i])  # 理想低通滤波器
        maskDual = cv.merge([mask, mask])  # 拼接为两个通道:(h,w,2)
        # maskAmp = cv.magnitude(mask, mask)  # 幅度谱

        # (3) 修改傅里叶变换实现频域图像滤波
        dftMask = dftShift * maskDual  # 两个通道分别为实部和虚部

        # (4) 逆中心化后进行傅里叶逆变换
        iShift = np.fft.ifftshift(dftMask)  # 将低频逆转换回图像四角
        iDft = cv.idft(iShift)  # 傅里叶逆变换
        iDftMag = cv.magnitude(iDft[:,:,0], iDft[:,:,1])  # 重建图像
        imgLPF = np.uint8(cv.normalize(iDftMag, None, 0, 255, cv.NORM_MINMAX))

        plt.subplot(2,3,i+1), plt.title("Mask (r={})".format(r[i]))
        plt.axis('off'), plt.imshow(mask, cmap='gray')
        plt.subplot(2,3,i+4), plt.title("LPF image (r={})".format(r[i]))
        plt.axis('off'), plt.imshow(imgLPF, cmap='gray')

    print(img.shape, dft.shape, maskDual.shape)
    plt.tight_layout()
    plt.show()

运行结果:

程序说明:

(1) OpenCV中的傅里叶变换结果保存为实部和虚部两个通道,dft的形状为(h,w,2)。因此要把单通道滤波器mask拼接为两个通道的maskDual,才能将dft与maskDual相乘。
(2) 傅里叶变换和傅里叶逆变换的结果都包括实部和虚部,使用函数cv.magnitude转换为幅度谱才能得到显示图像。
(3) 函数cv.dft的可选参数较多,在设置转换类型标志时不能省略关键字flags。
(4) 运行结果,频域滤波之理想低通滤波器如图11-2所示。从图中可以发现,低通滤波器的截止频率越小,保留的低频信息越少,滤除的高频信息越多,图像越模糊。这与空间域低通滤波的结果是一致的。
(5) 注意,滤波器传递函数与图像傅里叶变换进行乘法运算时,不能使用函数cv.multiply,因其是饱和运算。


在这里插入图片描述

图11-2 频域滤波之理想低通滤波器


版权声明:
youcans@xupt 原创作品,转载必须标注原文链接:(https://blog.csdn.net/youcans/article/details/135705738)
Copyright 2024 youcans, XUPT
Crated:2024-01-20

《数字图像处理-OpenCV/Python》 独家连载专栏 : https://blog.csdn.net/youcans/category_12418787.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1397603.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

根据基因名批量查找它的Uniprot编号

背景&#xff1a; 前几天老师交给我一个任务&#xff0c;给我一个基因列表&#xff0c;让我查找它们所编码的蛋白质的蛋白质序列。我上了一下uniprot数据库&#xff0c;发现这个任务可以分成两步&#xff1a; 找到这个基因在Uniprot数据库中所对应的蛋白质编码根据蛋白质编码…

街机模拟游戏逆向工程(HACKROM)教程:[12]68K汇编-程序流控制

在之前的文章中&#xff0c;我们测试过一些简短的一小段程序&#xff0c;这些程序都有一个共同的程序运行流程&#xff0c;就是一句一句地向下执行&#xff0c;比如&#xff1a; movea.l #$325, a0 * ↓move.b #$01, (a0) * ↓move.b #$02, $01(a…

【软件测试常见Bug清单】

软件测试中&#xff0c;bug的类型有很多种&#xff0c;比如&#xff1a;代码错误、界面优化、设计缺陷、需求补充和用户体验等&#xff1b; 一般情况下&#xff0c;需求补充和设计缺陷比较好区分&#xff0c;但是代码错误、界面优化和用户体验区分不是很明显&#xff1b; 下面…

主动轮廓——计算机视觉中的图像分割方法

​ 一、说明 简单来说&#xff0c;计算机视觉就是为计算机提供类似人类的视觉。作为人类&#xff0c;我们很容易识别任何物体。我们可以很容易地识别山丘、树木、土地、动物等&#xff0c;但计算机没有眼睛&#xff0c;也没有大脑&#xff0c;因此它很难识别任何图像。计算机只…

PostgreSQL 的对象层次

所有的数据库离开数据量来谈性能都是耍流氓。 就你那几万条的数据库&#xff0c;用啥都行&#xff0c;典型的就是怎么方便怎么来。 不过 PostgreSQL 上手确实比 MySQL 概念更多。 PostgreSQL 比 MySQL 多了一层。 PostgreSQL 是从PostgreSQL 是从 Database&#xff0c;到 S…

RK3568平台 LT9211转接芯片调试笔记

一.简介 龙讯LT9211是一个高性能转换器&#xff0c;支持MIPI LVDS TTL两两之间转换。 使用此款芯片大部分为MIPI与LVDS进行互相转换。 下图为LT9211的典型应用图&#xff1a; 二.LT9211原理图 三.车载显示器和摄像头系统 四.调试LT9211输出 MIPI数据 &#xff08;1&#xf…

【Linux install】Ubuntu和win双系统安装及可能遇到的所有问题

文章目录 1.前期准备1.1关闭快速启动和安全启动1.1.1 shell命令行进入BIOS1.1.2 windows设置中高级启动1.1.3 在开机时狂按某个键进入BIOS1.1.4 关闭Fast boot和Secure boot 1.2 制作启动盘1.3 划分磁盘空间1.3.1 查看目前的虚拟内存大小 2.开始安装2.1 使用启动盘启动2.1.1 法…

洛谷NOIP2002 普及组 选数 +NOIP1999普及组 回文数

两道日常的练习题&#xff0c;废话不多说&#xff0c;直接上题上代码&#xff1a; 这道题目的难点在于怎样去根据一个不同的k值&#xff0c;通过代码来实现将所有符合题目要求的数字相加并且不重复的功能。下面请看代码&#xff0c;会有详细的讲解&#xff1a; #include<io…

又聊代码重构

今天有幸和一位朋友聊了一下代码的重构。回来之后感觉不够尽兴&#xff0c;所以决定再来输出一篇。 代码来至于今天下午的提交。 重构是对代码的觉知和业务的逻辑的进一步归纳总结 只有开发者对代码的不断觉察和理解&#xff0c;才会产生重构代码的念头。因此&#xff0c;驱动…

GO 中如何防止 goroutine 泄露

文章目录 概述如何监控泄露一个简单的例子泄露情况分类chanel 引起的泄露发送不接收接收不发送nil channel真实的场景 传统同步机制MutexWaitGroup 总结参考资料 今天来简单谈谈&#xff0c;Go 如何防止 goroutine 泄露。 概述 Go 的并发模型与其他语言不同&#xff0c;虽说它…

小白水平理解面试经典题目LeetCode 121 Best Time to Buy and Sell Stock

121 Best Time to Buy and Sell Stock (买卖股票的最佳时机) 你好&#xff0c;2024年的第一个月&#xff0c;又是秋风萧瑟天气凉&#xff0c;草木摇落露为霜。.。。在这个特殊的时代&#xff0c;作为我们普通的一个打工人&#xff0c;我们用这道题&#xff0c;开启对这个不符合…

菜鸟关于做前、后端的整理(html、js),以及疑问

涉及到后端的接口py&#xff0c;前端html和js 这三部分就按照如下格式放到server项目主路径下&#xff0c;这样后端机可以作为一个前端server main.pystaticmain.jsmain.htmlhtml 首先是html要设定网页的显示 <!DOCTYPE html> <html> <head><title>…

小米,我请你不要将卖手机那套话术带进汽车圈

文 | AUTO芯球 ​作者 | 雷歌 当你们用卖手机时那一套营销话术玩汽车&#xff0c;整个汽车圈都被你们逗乐了。 这不&#xff0c;在被用户问到“贵公司汽车有哪些驾驶模式”时&#xff0c;你们声称自己有16.8亿种驾驶模式。 你小米说这话的逻辑&#xff0c;不就是将加速、转…

网络安全最大的威胁:洞察数字时代的风险之巅

在数字化时代&#xff0c;网络安全问题越发突显&#xff0c;企业和个人都面临着来自多方面的威胁。究竟网络安全领域的最大威胁是什么&#xff1f;本文将深入探讨这一问题&#xff0c;揭示数字空间中最为严重的威胁。 1. 恶意软件的肆虐&#xff1a; 恶意软件一直是网络安全的…

29、WEB攻防——通用漏洞SQL注入增删改查盲注延迟布尔报错

文章目录 盲注增删改查 盲注 概念&#xff1a;在注入过程中&#xff0c;获取的数据不能回显至前端页面&#xff0c;此时我们需要利用一些方法进行判断或尝试&#xff0c;这个过程被称为盲注。 解决&#xff1a;常规的联合查询注入不行的情况。 分类&#xff1a; 基于布尔的SQ…

Leetcode2957. 消除相邻近似相等字符

Every day a Leetcode 题目来源&#xff1a;2957. 消除相邻近似相等字符 解法1&#xff1a;遍历 分类讨论 遍历字符串 word&#xff0c;比较相邻的 3 个元素 word[i - 1]、word[i] 和 word[i 1]&#xff0c;记 left_distance abs(mid - left)&#xff0c;right_distance…

739.每日温度 496.下一个更大元素 I

739.每日温度 496.下一个更大元素 I 739.每日温度 力扣题目链接(opens new window) 请根据每日 气温 列表&#xff0c;重新生成一个列表。对应位置的输出为&#xff1a;要想观测到更高的气温&#xff0c;至少需要等待的天数。如果气温在这之后都不会升高&#xff0c;请在该位…

(初研) Sentence-embedding fine-tune notebook

由于工作需要&#xff0c;需要对embedding模型进行微调&#xff0c;我调用了几种方案&#xff0c;都比较繁琐。先记录一个相对简单的方案。以下内容并不一定正确&#xff0c;请刷到的大佬给予指正&#xff0c;不胜感激&#xff01;&#xff01;&#xff01; 一.对BGE模型&…

OpenHarmonyOS-gn与Ninja

GN语法及在鸿蒙的使用 [gnninja学习 0x01]gn和ninja是什么 ohos_sdk/doc/subsys-build-gn-coding-style-and-best-practice.md GN 语言与操作 一、gn简介 gn是generate ninja的缩写&#xff0c;它是一个元编译系统&#xff08;meta-build system&#xff09;,是ninja的前端&am…