图像处理(十):傅里叶变换

2023-05-16

图像处理笔记总目录


一、在opencv中实现图像的傅里叶变换

傅里叶变换的物理意义是将图像的灰度分布函数变换为图像的频率分布函数;
傅里叶逆变换是将图像的频率分布函数变换为灰度分布函数。

正变换:dft = cv2.dft(src, dst=None)

参数:

  • src: 输入图像,要转换成np.float32格式
  • dst:参数是可选的, 决定输出数组的大小。默认输出数组的大小和输入图像大小一样。如果输出结果比输入图像大,输入图像就需要在进行变换前补 0。如果输出结果比输入图像小的话,输入图像就会被切割。

返回:

  • dft: 傅里叶变换后的结果,有两个通道,第一个通道是结果的实数部分,第二个通道是结果的虚数部分。我们需要在此基础上计算傅里叶变换的频谱和相位。

逆变换:img = cv.idft(dft)

参数:

  • dft: 图像的频域表示

返回:

  • img: 图像的空域表示

实现:

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

# 1 读取图像
img = cv2.imread('../image/deer.jpeg',0)

# 2 傅里叶变换
# 2.1 正变换
dft = cv2.dft(np.float32(img),flags = cv2.DFT_COMPLEX_OUTPUT) 
# 2.2 频谱中心化
dft_shift = np.fft.fftshift(dft)
# 2.3 计算频谱和相位谱
mag, angle = cv2.cartToPolar(dft_shift[:,:,0], dft_shift[:,:,1], angleInDegrees=True)
mag=20*np.log(mag)

# 3 傅里叶逆变换
# 3.1 反变换
img_back = cv2.idft(dft)
# 3.2 计算灰度值
img_back = cv2.magnitude(img_back[:,:,0],img_back[:,:,1])

# 4 图像显示
plt.figure(figsize=(10,8))
plt.subplot(221),plt.imshow(img, cmap = 'gray') 
plt.title('输入图像'), plt.xticks([]), plt.yticks([]) 
plt.subplot(222),plt.imshow(mag, cmap = 'gray')
plt.title('频谱'), plt.xticks([]), plt.yticks([]) 
plt.subplot(223),plt.imshow(angle, cmap = 'gray')
plt.title('相位谱'), plt.xticks([]), plt.yticks([])
plt.subplot(224),plt.imshow(img_back, cmap = 'gray')
plt.title('逆变换结果'), plt.xticks([]), plt.yticks([])
plt.show()

在这里插入图片描述

二、高通和低通滤波器

我们知道,图像在经过傅里叶变换后,经频谱中心化后,从中间到外面,频率上依次是从低频到高频的。那么我们假设把中间规定一小部分去掉,是不是相对于把低频信号去掉了呢?这也就是相当于进行了高通滤波。

这个滤波模板如下图所示:

在这里插入图片描述
其中黑色部分为0,白色部分为1,我们将这个模板与图像的傅里叶变换相与就实现了高通滤波。如下所示:

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

# 1 读取图像
img = cv2.imread('../image/deer.jpeg',0)

# 2 设计高通滤波器(傅里叶变换结果中有两个通道,所以高通滤波中也有两个通道)
rows,cols = img.shape
mask = np.ones((rows,cols,2),np.uint8)
mask[int(rows/2)-30:int(rows/2)+30,int(cols/2)-30:int(cols/2)+30,:] = 0

# 3 傅里叶变换
# 3.1 正变换
dft = cv2.dft(np.float32(img),flags = cv2.DFT_COMPLEX_OUTPUT) 
# 3.2 频谱中心化
dft_shift = np.fft.fftshift(dft)
# 3.3 滤波
dft_shift = dft_shift * mask
# 3.4 频谱去中心化
dft_shift = np.fft.fftshift(dft_shift)

# 4 傅里叶逆变换
# 4.1 反变换
img_back = cv2.idft(dft_shift)
# 4.2 计算灰度值
img_back = cv2.magnitude(img_back[:,:,0],img_back[:,:,1])
plt.subplot(121),plt.imshow(img, cmap = 'gray') 
plt.title('输入图像'), plt.xticks([]), plt.yticks([]) 
plt.subplot(122),plt.imshow(img_back, cmap = 'gray')
plt.title('高通滤波结果'), plt.xticks([]), plt.yticks([])
plt.show()

在这里插入图片描述

从结果中可以看出,高通滤波器有利于提取图像的轮廓,图像的轮廓或者边缘或者一些噪声处,灰度变化剧烈,那么在把它们经过傅里叶变换后。就会变成高频信号(高频是捕捉细节的),所以在把图像低频信号滤掉以后剩下的自然就是轮廓了。

现在我们看下低通滤波的效果,构造一个低通滤波器很简单,只要把上述模板中的1改为0,0改为1即可。把设计高通滤波器部分的代码改成如下所示:

rows,cols = img.shape
mask = np.zeros((rows,cols,2),np.uint8)
mask[int(rows/2)-30:int(rows/2)+30,int(cols/2)-30:int(cols/2)+30,:] = 1

低通滤波的效果如下图所示:
在这里插入图片描述
从结果中可看到低通滤波后图像轮廓变模糊了,图像的大部分信息基本上都保持了。图像的主要信息都集中在低频上,所以结果会如上图所示。

三、带通和带阻滤波器

我们把高通和低通的一部分结合在模板中就形成了带通滤波器,它允许一定频率范围信号通过, 但减弱(或减少)频率低于下限截止频率和高于上限截止频率的信号的通过,如下图所示:
在这里插入图片描述
还是以理想的带通滤波器演示如下,将构建的滤波的代码修改如下:

rows,cols = img.shape
mask1 = np.ones((rows,cols,2),np.uint8)
mask1[int(rows/2)-8:int(rows/2)+8,int(cols/2)-8:int(cols/2)+8] = 0
mask2 = np.zeros((rows,cols,2),np.uint8)
mask2[int(rows/2)-80:int(rows/2)+80,int(cols/2)-80:int(cols/2)+80] = 1
mask = mask1*mask2

在这里插入图片描述
这就是带通的效果,它既能保留一部分低频,也能保留一部分高频。至于保留多少,根据需求选择就可以了。

带阻滤波器减弱(或减少)一定频率范围信号, 但允许频率低于下限截止频率和高于上限截止频率的信号的通过,如下示:
在这里插入图片描述

在代码中将设计滤波器部分改为如下所示:

mask = np.ones((rows,cols,2),np.uint8)
mask[int(rows/2)+80:int(rows/2)+150,int(cols/2)-150:int(cols/2)+150] = 0
mask[int(rows/2)-150:int(rows/2)-80,int(cols/2)-150:int(cols/2)+150] = 0
mask[int(rows/2)-150:int(rows/2)+150,int(cols/2)+80:int(cols/2)+150] = 0
mask[int(rows/2)-150:int(rows/2)+150,int(cols/2)-150:int(cols/2)-80] = 0
plt.imshow(mask[:,:,1],cmap=plt.cm.gray)

在这里插入图片描述
从结果中可看到带阻滤波器保持了原图像的大部分信息,图像的主要信息都集中在低频上,而边缘轮廓信息都在高频位置。带阻滤波器滤除了中频信息,保留了低频和高频信息,所以对图像的信息破坏是比较小的。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

图像处理(十):傅里叶变换 的相关文章

  • 进程如何判断是否在docker环境里运行

    一 判断根目录下 dockerenv 文件 docker环境下 xff1a ls alh dockerenv 非docker环境 xff0c 没有这个 dockerenv文件的 root 64 4cb54de415d4 ls alh doc
  • lua元表、元方法

    lua元表 元方法 lua官方参考手册 xff1a https www runoob com manual lua53doc manual html 2 4 一 总结 xff1a 1 普通的表 xff0c 找不到了 xff0c 或者无法进行
  • 一个less文件中引入另一个less文件

    假设有两个 less的文件1 less 和2 less 在1 less 中引入2 less文件 64 import 34 2 less 34 34 34 是一定不可以忘记的
  • Python——函数

    函数的创建和调用 xff1a 函数的创建和调用 为什么需要函数 xff1a 复用代码 隐藏实现细节 提高可维护性 提高可读性便于调试 函数的创建 def 函数名 输入参数 函数体 return xxx span class token ke
  • ubuntu18.04安装微信

    1 安装deepin wine 使用shell的方法下载各种deb包 1 具体的操作为 xff1a 在home中打开终端 xff08 terminal xff09 xff0c 运行以下语句 xff1a gedit install sh 弹出
  • 实现MySql的主从复制(两台虚拟机)详解

    实现MySql的主从复制 xff08 非单机 xff09 文章目录 实现MySql的主从复制 xff08 非单机 xff09 首先了解心跳线实现数据同步一 mysql主从复制原理是什么 xff1f 二 使用步骤1 安装Mysql2 数据库进
  • ubuntu安装完anaconda,添加快捷启动方式

    1 进入文件夹 xff0c 找到anaconda的bin文件并进入 home 用户 anaconda3 bin 2 进入后右键打开terminal 3 在terminal中输入 anaconda navigator 4 这时候就会发现ana
  • 分别用汇编语言、C语言编程实现LED流水灯

    一 C语言编程 1 先创建一个新的工程 2 文件名 3 右键Source Group创建一个 c文件 4 在 c文件中放入以下代码 APB2使能时钟寄存器 define RCC AP2ENR unsigned volatile int 0x
  • SyntaxError: invalid syntax的问题原因和解决办法

    写在这里的初衷 xff0c 一是备忘 xff0c 二是希望得到高人指点 xff0c 三是希望能遇到志同道合的朋友 目录 一 问题二 原因及解决办法 一 问题 span class token comment An highlighted b
  • Java 字符串匹配的三种方法

    文章目录 一 示例二 解释1 replace 方法2 replaceAll 方法3 replaceFirst 方法4 常用的字符列表 一 示例 如图 xff0c 都是为了替换字符串s中的 34 34 符号 xff0c 但三种匹配方法 xff
  • 【VMware+ubuntu】关闭还原虚拟机后网络断开的解决办法

    使用ifconfig和ip addr 发现对应网卡down掉了 手动执行ifcconfig ens33 up把网卡up起来 xff0c 发现网卡是起来了 xff0c 但是没有IP 重启网络服务sudo service network man
  • MySQL中的视图

    视图概述 视图是一种虚拟存在的表 xff0c 并不在数据库中实际存在 xff0c 它的数据依赖于真实存在的数据表 通过视图不仅可以看到其依赖数据表中的数据 xff0c 还可以像操作数据表一样 xff0c 对数据表中的数据进行添加 修改和删除
  • ubuntu在更新软件时出现E: Release file for http://security.ubuntu.com/ubuntu/dists/bionic-security/InRelease

    问题 E Release file for http security ubuntu com ubuntu dists bionic security InRelease is not valid yet invalid for anoth
  • 配置pip环境变量以及PYTHONPATH的作用

    配置pip环境变量 python的环境变量PYTHONPATH PYTHONPATH是Python搜索路径 xff0c 默认我们import的模块都会从PYTHONPATH里面寻找
  • AtCoder Beginner Contest 218 C - Shapes (模拟)

    linkkkk 题意 xff1a 给两个 n n n n n n 的矩阵 xff0c
  • CF1169C. Increasing by Modulo(二分)

    linkkkkk 题意 xff1a 给出 n k n k n k 和数组 a a
  • 【c++类的构造函数】几种写法及问题

    c 43 43 类的构造函数 几种写法及问题 一 构造函数的定义 类通过一个或几个特殊的与类同名的成员函数来控制其对象的初始化过程 xff0c 这些函数叫构造函数 构造函数的任务是初始化类对象的数据成员 xff0c 无论何时只要类的对象被创
  • 【洛谷】P1786 帮贡排序 2020-11-07

    洛谷 P1786 帮贡排序 简单结构体排序题 xff0c 用bool函数加sort就可以 主要的点是如果需要按某种奇怪的顺序排序的话 xff0c 就把那个奇怪的顺序表上号好了 题解 xff1a xff08 还是多加注释比较好 xff09 s
  • 链表:头插法与尾插法(简易图解和代码)

    头插法 定义 xff1a 输入的数据次序生成的链表节点次序相反 xff0c 例如 xff1a 按1 2 3顺序进行头插之后 xff0c 最终排序却变成了3 2 1 简而言之就是逆序插入 定义图解 xff1a 代码图解 xff1a 代码 xf
  • Robomaster基于传统算法的视觉识别教程

    文章目录 前言一 装甲板的分析二 预处理降低曝光度ROI区域 三 颜色提取提取目标颜色阈值化与膨胀 四 灯条轮廓提取五 灯柱筛选六 灯柱匹配其他总结 前言 本文记载个人在RM视觉组中学习到的传统算法和opencv用法及代码实例讲解 xff0

随机推荐