OpenCV学习(4.11) OpenCV中的图像转换

1. 目标

在本节中,我们将学习

  • 使用OpenCV查找图像的傅立叶变换
  • 利用Numpy中可用的FFT功能
  • 傅立叶变换的一些应用
  • 我们将看到以下函数:**cv.dft()** ,**cv.idft()** 等

理论

傅立叶变换用于分析各种滤波器的频率特性。对于图像,使用 2D离散傅里叶变换(DFT) 查找频域。快速算法称为 快速傅立叶变换(FFT) 用于计算DFT。关于这些的详细信息可以在任何图像处理或信号处理教科书中找到。请参阅其他资源_部分。

对于正弦信号,$x(t)=Asin(2\pi ft)$ ,我们可以说 $f$ 是信号的频率,如果采用其频域,我们可以在 $f$ 处看到一个尖峰。如果信号进行采样,以形成离散信号,我们得到了相同的频域,但在范围周期性 $[-π,π]$ 或 $[0,2\pi]$(或 $[0,N]$ 用于N点DFT)。您可以将图像视为在两个方向上采样的信号。因此,在X和Y方向都进行傅立叶变换,可以得到图像的频率表示。

更直观地说,对于正弦信号,如果振幅在短时间内变化如此之快,则可以说它是高频信号。如果变化缓慢,则为低频信号。您可以将相同的想法扩展到图像。图像中的振幅在哪里急剧变化?在边缘点或噪音。因此,可以说边缘和噪声是图像中的高频内容。如果幅度没有太大变化,则它是低频分量。(一些链接已添加到“其他资源”,其中通过示例直观地说明了频率变换)。

现在,我们将看到如何找到傅立叶变换。

2.Numpy中的傅里叶变换

首先,我们将看到如何使用Numpy查找傅立叶变换。Numpy具有FFT软件包来执行此操作。np.fft.fft2() 为我们提供了频率转换,它将是一个复杂的数组。它的第一个参数是输入图像,即灰度图像。第二个参数是可选的,它决定输出数组的大小。如果它大于输入图像的大小,则在计算FFT之前用零填充输入图像。如果小于输入图像,将裁切输入图像。如果未传递任何参数,则输出数组的大小将与输入的大小相同。

现在,一旦获得结果,零频率分量(DC分量)将位于左上角。如果要使其居中,则需要将结果偏移 $\frac{N}{2}$ 在两个方向上。只需通过函数 np.fft.fftshift() 即可完成。(它更容易分析)。找到频率变换后,就可以找到幅度谱。

import cv2 as cv
import numpy as np
from matplotlib import pyplot as plt
img = cv.imread('messi5.jpg',0)
f = np.fft.fft2(img)
fshift = np.fft.fftshift(f)
magnitude_spectrum = 20*np.log(np.abs(fshift))
plt.subplot(121),plt.imshow(img, cmap = 'gray')
plt.title('Input Image'), plt.xticks([]), plt.yticks([])
plt.subplot(122),plt.imshow(magnitude_spectrum, cmap = 'gray')
plt.title('Magnitude Spectrum'), plt.xticks([]), plt.yticks([])
plt.show()

结果如下: 

看,您可以在中心看到更多白色区域,这表明低频内容更多。

因此,您已经进行了频率变换,您可以在频域中执行一些操作,例如高通滤波和重建图像,若进行逆DFT。为此,您需用尺寸为60x60的矩形窗口遮罩来消除低频。然后,使用 np.fft.ifftshift() 应用反向移位,以使DC分量再次出现在左上角。然后使用 np.ifft2() 函数找到逆FFT 。同样,结果将是一个复数。您可以采用其绝对值来进行

rows, cols = img.shape
crow,ccol = rows//2 , cols//2
fshift[crow-30:crow+31, ccol-30:ccol+31] = 0
f_ishift = np.fft.ifftshift(fshift)
img_back = np.fft.ifft2(f_ishift)
img_back = np.real(img_back)
plt.subplot(131),plt.imshow(img, cmap = 'gray')
plt.title('Input Image'), plt.xticks([]), plt.yticks([])
plt.subplot(132),plt.imshow(img_back, cmap = 'gray')
plt.title('Image after HPF'), plt.xticks([]), plt.yticks([])
plt.subplot(133),plt.imshow(img_back)
plt.title('Result in JET'), plt.xticks([]), plt.yticks([])
plt.show()

结果如下: 

结果表明高通滤波是边缘检测操作。这就是我们在“图像渐变”一章中看到的。这也表明大多数图像数据都存在于频谱的低频区域。无论如何,我们已经看到了如何在Numpy中找到DFT,IDFT等。现在,让我们看看如何在OpenCV中进行操作。

如果您仔细观察结果,尤其是最后一张JET颜色的图像,您会看到一些伪像(我用红色箭头标记的一个实例)。它在那里显示出一些波纹状结构,称为 振铃效应 。这是由我们用于遮罩的矩形窗口引起的。此蒙版转换为正弦形状,从而导致此问题。因此,矩形窗口不用于过滤。更好的选择是高斯窗口。

3. OpenCV中傅里叶变换

OpenCV 为此提供了功能 cv.dft() 和 cv.idft() 。它返回与以前相同的结果,但是有两个通道。第一个通道将具有结果的实部,第二个通道将具有结果的虚部。输入的图像应首先转换为np.float32 。我们将看到如何做。

import numpy as np
import cv2 as cv
from matplotlib import pyplot as plt
img = cv.imread('messi5.jpg',0)
dft = cv.dft(np.float32(img),flags = cv.DFT_COMPLEX_OUTPUT)
dft_shift = np.fft.fftshift(dft)
magnitude_spectrum = 20*np.log(cv.magnitude(dft_shift[:,:,0],dft_shift[:,:,1]))
plt.subplot(121),plt.imshow(img, cmap = 'gray')
plt.title('Input Image'), plt.xticks([]), plt.yticks([])
plt.subplot(122),plt.imshow(magnitude_spectrum, cmap = 'gray')
plt.title('Magnitude Spectrum'), plt.xticks([]), plt.yticks([])
plt.show()

注意 您还可以使用 cv.cartToPolar() 一次返回大小和相位 

因此,现在我们必须进行逆DFT。在上一部分中,我们创建了一个HPF,这次我们将看到如何去除图像中的高频内容,即我们将LPF应用于图像。实际上会使图像模糊。为此,我们首先创建一个在低频时具有高值(1)的蒙版,即,我们传递LF含量,并在HF区域传递0。 

rows, cols = img.shape
crow,ccol = rows/2 , cols/2
# create a mask first, center square is 1, remaining all zeros
mask = np.zeros((rows,cols,2),np.uint8)
mask[crow-30:crow+30, ccol-30:ccol+30] = 1
# apply mask and inverse DFT
fshift = dft_shift*mask
f_ishift = np.fft.ifftshift(fshift)
img_back = cv.idft(f_ishift)
img_back = cv.magnitude(img_back[:,:,0],img_back[:,:,1])
plt.subplot(121),plt.imshow(img, cmap = 'gray')
plt.title('Input Image'), plt.xticks([]), plt.yticks([])
plt.subplot(122),plt.imshow(img_back, cmap = 'gray')
plt.title('Magnitude Spectrum'), plt.xticks([]), plt.yticks([])
plt.show()

查看结果: 

 注意 像往常一样,OpenCV函数 cv.dft() 和 cv.idft() 比Numpy对应函数要快。但是Numpy功能更加人性化。有关性能问题的更多详细信息,请参阅以下部分。

 4. DFT的性能优化

 

对于某些阵列大小,DFT计算的性能更好。当阵列大小为2的幂时,它是最快的。大小为2、3和5的乘积的数组也得到了有效处理。因此,如果您担心代码的性能,可以在找到DFT之前将数组的大小修改为任何最佳大小(通过填充零)。对于OpenCV,您必须手动填充零。但是对于Numpy,您可以指定FFT计算的新大小,它将自动为您填充零。

那么我们如何找到这个最佳尺寸呢?OpenCV 为此提供了一个函数 cv.getOptimalDFTSize() 。它适用于 cv.dft() 和 np.fft.fft2() 。让我们使用IPython magic命令timeit检查它们的性能。

In [16]: img = cv.imread('messi5.jpg',0)
In [17]: rows,cols = img.shape
In [18]: print("{} {}".format(rows,cols))
342 548
In [19]: nrows = cv.getOptimalDFTSize(rows)
In [20]: ncols = cv.getOptimalDFTSize(cols)
In [21]: print("{} {}".format(nrows,ncols))
360 576

参见,将大小(342,548)修改为(360,576)。现在让我们用零填充(对于OpenCV),并找到其DFT计算性能。您可以通过创建一个新的大零数组并将数据复制到其中来完成此操作,或者使用 cv.copyMakeBorder() 。 

nimg = np.zeros((nrows,ncols))
nimg[:rows,:cols] = img

要么: 

right = ncols - cols
bottom = nrows - rows
bordertype = cv.BORDER_CONSTANT #just to avoid line breakup in PDF file
nimg = cv.copyMakeBorder(img,0,bottom,0,right,bordertype, value = 0)

现在,我们计算Numpy函数的DFT性能比较:

In [22]: %timeit fft1 = np.fft.fft2(img)
10 loops, best of 3: 40.9 ms per loop
In [23]: %timeit fft2 = np.fft.fft2(img,[nrows,ncols])
100 loops, best of 3: 10.4 ms per loop

它显示了4倍的加速。现在,我们将尝试使用OpenCV函数。 

In [24]: %timeit dft1= cv.dft(np.float32(img),flags=cv.DFT_COMPLEX_OUTPUT)
100 loops, best of 3: 13.5 ms per loop
In [27]: %timeit dft2= cv.dft(np.float32(nimg),flags=cv.DFT_COMPLEX_OUTPUT)
100 loops, best of 3: 3.11 ms per loop

它还显示了4倍的加速。您还可以看到OpenCV函数比Numpy函数快3倍左右。也可以对逆FFT进行测试,这留给您练习。 

5. 为什么拉普拉斯算子是高通滤波器?

在论坛上提出了类似的问题。问题是,为什么拉普拉斯算子是高通滤波器?为什么Sobel是HPF?等等。第一个得到的答案是傅里叶变换。只需对Laplacian进行傅立叶变换,以获得更大的FFT大小。分析一下:

import cv2 as cv
import numpy as np
from matplotlib import pyplot as plt
# simple averaging filter without scaling parameter
mean_filter = np.ones((3,3))
# creating a gaussian filter
x = cv.getGaussianKernel(5,10)
gaussian = x*x.T
# different edge detecting filters
# scharr in x-direction
scharr = np.array([[-3, 0, 3],[-10,0,10],[-3, 0, 3]])
# sobel in x direction
sobel_x= np.array([[-1, 0, 1],[-2, 0, 2],[-1, 0, 1]])
# sobel in y direction
sobel_y= np.array([[-1,-2,-1],[0, 0, 0],[1, 2, 1]])
# laplacian
laplacian=np.array([[0, 1, 0],[1,-4, 1],[0, 1, 0]])
filters = [mean_filter, gaussian, laplacian, sobel_x, sobel_y, scharr]
filter_name = ['mean_filter', 'gaussian','laplacian', 'sobel_x', \'sobel_y', 'scharr_x']
fft_filters = [np.fft.fft2(x) for x in filters]
fft_shift = [np.fft.fftshift(y) for y in fft_filters]
mag_spectrum = [np.log(np.abs(z)+1) for z in fft_shift]
for i in xrange(6):plt.subplot(2,3,i+1),plt.imshow(mag_spectrum[i],cmap = 'gray')plt.title(filter_name[i]), plt.xticks([]), plt.yticks([])
plt.show()

查看结果: 

从图像中,您可以看到每个内核阻止的频率区域以及它经过的区域。从这些信息中,我们可以说出为什么每个内核都是HPF或LPF

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

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

相关文章

CoppeliaSim机器人模拟器与Matlab Simulink环境

一、CoppeliaSim机器人模拟器 CoppeliaSim(原名V-REP,Virtual Robot Experimentation Platform)是一款基于物理引擎的动力学机器人模拟器。它提供了一个集成的开发环境,支持传感器、机械、机器人、环境的系统建模与仿真。Coppeli…

【第9章】“基础工作流”怎么用?(图生图/局部重绘/VAE/更多基础工作流)ComfyUI基础入门教程

🎁引言 学到这里,大家是不是会比较纠结,好像还在持续学习新的东西,未来还有多少基础的东西要学习,才能正常使用ComfyUI呢? 这其实需要转变一个心态。 AI绘画还处于一个快速迭代的过程,隔三岔五的就会有很多新技术、新模型出现,ComfyUI目前同样处于一个快速更新的阶…

vue3之toRefs

import { reactive, toRefs } from vue;export default {setup() {// 创建一个响应式对象const state reactive({count: 0,name: Vue 3});// 使用toRefs将响应式对象的属性转换为响应式引用const refs toRefs(state);// 返回响应式引用,以便在模板中使用return {.…

白嫖 kimi 接口 api

说明:kimi当然是免费使用的人工智能AI,但是要调用api是收费的. 项目: https://github.com/LLM-Red-Team/kimi-free-api 原文地址: https://blog.taoshuge.eu.org/p/272/ railway部署 步骤: 打开Github,新建仓库新建名为Dockerfile文件(没有后缀&…

C#异步编程是怎么回事

首先以一个例子开始 我说明一下这个例子。 这是一个演示异步编程的例子。 输入job [name],在一个同步的Main方法中,以一发即忘的方式调用异步方法StartJob()。输入time,调用同步方法PrintCurrentTime()输出时间。输出都带上线程ID,便于观察。 可以看到,主线程不会阻塞。主…

RunMe_About PreparationForDellBiosWUTTest

:: ***************************************************************************************************************************************************************** :: 20240613 :: 该脚本可以用作BIOS WU测试前的准备工作,包括:自动检测"C:\DellB…

关于自学编程的9点忠告

打牢基础,精通一门语言。没有最好的语言,只有特定场景下更合适的语言。例如java开发安卓\大数据,php开发web ,python人工智能, go语言做区块链… 不同的编程有大量内容都是重复的,例如类与对象的思想,无论在…

深度探索:智能家居背后的科技力量与伦理思考

目录 科技力量:创新驱动下的智慧生活引擎 1. 人工智能与机器学习 2. 物联网技术 3. 大数据分析 4. 5G与边缘计算 伦理与隐私:智能家居的双刃剑 1. 隐私侵犯风险 2. 数据安全挑战 3. 算法偏见与决策透明度 应对策略:构建安全、负责任的智能…

Vision-LSTM: xLSTM 作为通用视觉主干

摘要 尽管Transformer最初是为自然语言处理引入的,但它现在已经被广泛用作计算机视觉中的通用主干结构。最近,长短期记忆(LSTM)已被扩展为一种可扩展且性能优越的架构——xLSTM,它通过指数门控和可并行化的矩阵内存结…

综合数据分析及可视化实战

【实验目的】 1、掌握数据分析常用的几种扩展库: numpy、pandas、matplotlib。 2、理解数据分析的几种方法,即描述性数据分析,探索性数据分析 和验证性数据分析。 3、理解数据分析的基本步骤:数据准备、数据导入、数据预处理、数 据分析和数据可视化…

机器学习笔记 - 用于3D数据分类、分割的Point Net的网络实现

上一篇,我们大致了解了Point Net的原理,这里我们要进行一下实现。 机器学习笔记 - 用于3D数据分类、分割的Point Net简述-CSDN博客文章浏览阅读3次。在本文中,我们将了解Point Net,目前,处理图像数据的方法有很多。从传统的计算机视觉方法到使用卷积神经网络到Transforme…

【MySQL】MySQL45讲-读书笔记

1、基础架构:一条SQL查询语句是如何执行的? 1.1 连接器 连接器负责跟客户端建立连接、获取权限、维持和管理连接。 mysql -h$ip -P$port -u$user -p输完命令之后,输入密码。 1.2 查询缓存 MySQL 拿到一个查询请求后,会先到查询缓…

透明屏幕的显示效果如何

透明屏幕的显示效果可以从以下几个方面进行评估和描述: 透明度:透明屏幕的透光率通常在50-90%左右,具体取决于屏幕的设计和用途。这种高透明度使得屏幕在不用时可以像普通玻璃一样透明,保持视野的清晰。 色彩表现:透明…

PDF格式分析(八十六)——修订注释(Redaction)

修订注释(PDF 1.7及其以上版本),该注释的做用是标识要从文档中删除的内容。 修订注释启用的步骤如下: 1、内容标识。PDF编辑器可指定应删除的文档内容片段或区域,在执行下一个步骤前,用户可以看到、移动和重新定义这些注释。 2、内容移除。PDF阅读器应删除修订注释指…

SAP MMRV/MMPV 物料账期月结月底月初开关

公告:周一至周五每日一更,周六日存稿,请您点“关注”和“在看”,后续推送的时候不至于看不到每日更新内容,感谢。 这是一条刮刮乐,按住全部选中:点关注的人最帅最美,欢迎&#xff1…

######## golang各章节终篇索引 ########

slice、map #### golang 切片及append操作 ####_golang切片线程 append 和下表操作-CSDN博客 #### go map 底层结构(详细) ####-CSDN博客 并发安全问题、syncmap ###### golang sync.map 原理和使用 ######_go sync.map删除原理-CSDN博客 #### 并发读…

spring 常用注解

Component:这将 java 类标记为 bean。它是任何 Spring 管理组件的通用 构造型。spring 的组件扫描机制现在可以将其拾取并将其拉入应用程序环境 中。 Controller:这将一个类标记为 Spring Web MVC 控制器。标有它的 Bean 会自动导入到 IoC 容器中。 Se…

多商家抽奖管理系统介绍和小程序APP演示

阿基米德多商家抽奖管理系统,采用Thinkphp8.0vue3.0uniapp技术栈开发,前后端分离,客户端支持小程序、H5、APP一键打包,功能完善、成熟稳定,使用简单易上手,是一套可以直接商业化运营的好系统,其…

JavaScript快速入门系列-2(JavaScript语言基础)

第二章:JavaScript语言基础 2.1 变量声明:let, const, var2.1.1 变量是什么?2.1.2 var2.1.3 let与const2.1.4 选择哪个关键字? 2.2 数据类型2.2.1 基本数据类型2.2.2 复杂数据类型2.2.3 示例与类型检测 2.3 运算符2.3.1 算术运算符…

CATIA P3 V5-6R 中文版软件下载安装 达索CATIA三维设计软件获取

CATIA的建模和装配能力堪称业界翘楚。其强大的建模工具能够轻松应对各种复杂的几何形状和结构,帮助设计师们快速构建出精准的产品模型。同时,装配模块则能够实现零部件的快速装配,大大提高了设计效率。 在分析和仿真方面,CATIA同样…