当前位置: 首页 > news >正文

【OpenCV】图像转换

理论

傅立叶变换用于分析各种滤波器的频率特性。对于图像,使用 2D离散傅里叶变换(DFT) 查找频域。快速算法称为 快速傅立叶变换(FFT) 用于计算DFT。

Numpy中的傅立叶变换

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

现在,一旦获得结果,零频率分量(DC分量)将位于左上角。如果要使其居中,只需通过函数 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()

结果如下:

fft1.jpg

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

因此,您已经进行了频率变换,您可以在频域中执行一些操作,例如高通滤波和重建图像,若进行逆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()

结果如下:

fft2.jpg

结果表明高通滤波是边缘检测操作。

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

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()

查看结果:

fft4.jpg

注意 像往常一样,OpenCV函数 cv.dft() 和 cv.idft() 比Numpy对应函数要快。但是Numpy功能更加人性化。

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倍左右。

apachecn.github.io/opencv-doc-zh/#/

相关文章:

【OpenCV】图像转换

理论 傅立叶变换用于分析各种滤波器的频率特性。对于图像,使用 2D离散傅里叶变换(DFT) 查找频域。快速算法称为 快速傅立叶变换(FFT) 用于计算DFT。 Numpy中的傅立叶变换 首先,我们将看到如何使用Numpy查…...

力扣 重排链表-143

重排链表-143 /*** Definition for singly-linked list.* struct ListNode {* int val;* ListNode *next;* ListNode() : val(0), next(nullptr) {}* ListNode(int x) : val(x), next(nullptr) {}* ListNode(int x, ListNode *next) : val(x), next(next)…...

【Kubernetes理论篇】容器集群管理系统Kubernetes(K8S)

Kubernetes集群部署基本管理实战 这么好的机会,还在等什么! 01、Kubernetes 概述 K8S是什么 K8S 的全称为 Kubernetes (K12345678S),PS:“嘛,写全称也太累了吧,写”。不如整个缩写 K8s 作为缩写的结果…...

Kubernetes 常用操作大全:全面掌握 K8s 基础与进阶命令

Kubernetes(简称 K8s)作为一种开源的容器编排工具,已经成为现代分布式系统中的标准。它的强大之处在于能够自动化应用程序的部署、扩展和管理。在使用 Kubernetes 的过程中,熟悉常用操作对于高效地管理集群资源至关重要。本文将详…...

爬虫基础之Web网页基础

网页的组成 网页可以分为三大部分–HTML、CSS 和 JavaScript。如果把网页比作一个人,那么 HTML 相当于骨架、JavaScript 相当于肌肉、CSS 相当于皮肤,这三者结合起来才能形成一个完善的网页。下面我们分别介绍一下这三部分的功能。 HTML HTML(Hypertext…...

k8s, deployment

控制循环(control loop) for {实际状态 : 获取集群中对象X的实际状态(Actual State)期望状态 : 获取集群中对象X的期望状态(Desired State)if 实际状态 期望状态{什么都不做} else {执行编排动作&#xf…...

使用ensp搭建OSPF+BGP和静态路由,底层PC使用dhcp,实现PC互通

1.4种方式,实现PC2可以互通底层的所有设备 OSPF:OSPF是一种用于互联网协议网络的链路状态路由协议 BGP:是一种用于互联网上进行路由和可达性信息传递的外部网关协议(EGP) 静态路由: 静态路由是一种路由方…...

TÜLU 3: Pushing Frontiers in Open Language Model Post-Training

基本信息 📝 原文链接: https://arxiv.org/abs/2411.15124👥 作者: Nathan Lambert, Jacob Morrison, Valentina Pyatkin, Shengyi Huang, Hamish Ivison, Faeze Brahman, Lester James V. Miranda, Alisa Liu, Nouha Dziri, Shane Lyu, Yuling Gu, Sau…...

深入解读 MySQL EXPLAIN 与索引优化实践

MySQL 是当今最流行的关系型数据库之一,为了提升查询性能,合理使用 EXPLAIN 工具和优化索引显得尤为重要。本文将结合实际示例,探讨如何利用 EXPLAIN 分析查询执行计划,并分享索引优化的最佳实践。 一、EXPLAIN 工具简介 EXPLAIN …...

Flume——进阶(agent特性+三种结构:串联,多路复用,聚合)

目录 agent特性ChannelSelector描述: SinkProcessor描述: 串联架构结构图解定义与描述配置示例Flume1(监测端node1)Flume3(接收端node3)启动方式 复制和多路复用结构图解定义描述配置示例node1node2node3启…...

ragflow连ollama时出现的Bug

ragflow和ollama连接后,已经添加了两个模型但是ragflow仍然一直warn:Please add both embedding model and LLM in Settings > Model providers firstly.这里可能是我一开始拉取的镜像容器太小,容不下当前添加的模型,导…...

基于centos7.7编译Redis6.0

背景: OS:CentOs 7.7 Redis: 6.0.6 编译构建报错如下: In file included from server.c:30:0: server.h:1044:5: error: expected specifier-qualifier-list before ‘_Atomic’_Atomic unsigned int lruclock; /* Clock for LRU eviction …...

uni-app项目无法在Android Studio模拟器上运行

目录 1 问题描述2 尝试解决3 引发原因4 解决方法4.1 换用 MuMu 模拟器 5 结语 1 问题描述 在使用 uni-app 开发 Pad 端 App 时,初始化项目后打算先运行一下确保初始化正常。打开 Android Studio 模拟器后,然后在 HbuilderX 中选择使用 App 标准基座 运…...

第一部分:Linux系统(基础及命令)

Linux操作系统的实操性非常强,纯操作,不适用于日常的办公使用 1.初始Linux 1.1 操作系统概述 1.1.1 了解OS的作用 OS:是计算机软件的一种,主要负责:作为用户和计算机硬件之间的桥梁,调度和管理计算机硬…...

No module named ‘_ssl‘ No module named ‘_ctypes‘

如果你使用的是基于 yum 的 Linux 发行版(例如 CentOS、RHEL、Fedora),安装 libc6-dev 的方式稍有不同。在这些系统中,通常对应的包是 glibc-devel。 No module named ‘_ctypes’ 使用 yum 安装 glibc-devel 更新系统的软件包列…...

【QT】编写第一个 QT 程序 对象树 Qt 编程事项 内存泄露问题

目录 1. 编写第一个 QT 程序 1.1 使用 标签 实现 🐇 图形化界面实现 🐇 纯代码形式实现 1.2 使用 按钮 实现 🐋 图形化界面实现 🐋 纯代码形式实现 1.3 使用 编辑框 实现 🥝 图形化界面实现 &#x1f95…...

VTK编程指南<六>:VTK可视化管线与渲染详解

1、VTK渲染引擎 回顾前几章节的RenderCylinder示例 可以找到以下的类: vtkProp; ytkAbstractMapper; vtkProperty; vtkCamera; vtkLight; vtkRenderer; vtkRenderWindow; vtkRenderWindowInteractor vtkTransform; vtkLookupTable;可以发现这些类都是与数据显示或渲染相关的。…...

基于STM32的智能计步器

引言 随着健康意识的提高,计步器逐渐成为人们日常生活中重要的健康管理工具。本文将指导你如何使用STM32微控制器制作一个智能计步器。该计步器通过加速度传感器检测步伐,并使用OLED显示屏显示步数。通过这个项目,你将学习到STM32开发的基本流…...

VB.NET 从入门到精通:开启编程进阶之路

摘要: 本文全面深入地阐述了 VB.NET 的学习路径,从基础的环境搭建与语法入门开始,逐步深入到面向对象编程、图形用户界面设计、数据访问、异常处理、多线程编程以及与其他技术的集成等核心领域,通过详细的代码示例与理论讲解&…...

射频电路屏蔽简略

电磁波的干扰是每个射频设备的自带属性,不管是内部还是外部,怎样去更好的抑制掉干扰,关系到射频设备的工作状态,而能够找到产生干扰的来源就是重中之重,电磁波的干扰与其产生的源密不可分,而源就离不开所需…...

ARM活动监视器(AMU)架构解析与性能监控实践

1. ARM活动监视器架构概述在ARMv8/v9架构中,活动监视器(Activity Monitors)是一组用于性能监控的硬件计数器,它们能够精确记录处理器执行过程中的各类微架构事件。作为性能分析子系统(PMU)的核心组件,AMU通过非侵入式的方式为开发者提供芯片级…...

浏览器资源嗅探技术深度解析:从网络请求到媒体文件提取

浏览器资源嗅探技术深度解析:从网络请求到媒体文件提取 【免费下载链接】cat-catch 猫抓 浏览器资源嗅探扩展 / cat-catch Browser Resource Sniffing Extension 项目地址: https://gitcode.com/GitHub_Trending/ca/cat-catch 在当今多媒体的互联网时代&…...

CANN/pyasc:add_deq_relu API文档

asc.language.basic.add_deq_relu 【免费下载链接】pyasc 本项目为Python用户提供算子编程接口,支持在昇腾AI处理器上加速计算,接口与Ascend C一一对应并遵守Python原生语法。 项目地址: https://gitcode.com/cann/pyasc asc.language.basic.add_…...

ARM MBIST控制器架构与存储测试技术详解

1. ARM MBIST控制器架构解析在SoC芯片设计中,内存内建自测试(MBIST)是不可或缺的验证环节。作为ARM提供的专业测试解决方案,其MBIST控制器采用硬件自动化测试架构,显著提升了存储阵列的测试效率和覆盖率。与软件实现的存储器测试相比&#xf…...

如何删除三星手机和平板电脑上的应用程序

你有这样的经历吗?您可能一时兴起在 Samsung Galaxy 上安装了一些软件,但后来发现它没有用或不合适。或者,您最近安装的应用程序不断弹出广告、提醒或频繁刷新背景。不用担心。您可以卸载这些程序以保证您的手机安全。但你是否觉得将软件一一…...

IDE内嵌AI产品副驾驶:用对话式工作流实现文档即代码

1. 项目概述:在IDE里嵌入一个产品经理副驾驶如果你和我一样,既是开发者,又时不时要客串产品经理的角色,那你肯定对下面这个场景不陌生:脑子里蹦出一个绝妙的产品点子,兴奋地打开代码编辑器准备大干一场&…...

Slack与Cursor AI本地自动化助手:提升开发效率的智能工作流

1. 项目概述:一个连接Slack与Cursor AI的本地自动化开发助手 如果你和我一样,每天大部分工作时间都泡在Slack和代码编辑器里,那你肯定也经历过这种场景:产品经理或同事在Slack里提了一个需求,你看到了,然后…...

CANN/ops-math 3D反射填充算子

aclnnReflectionPad3d 【免费下载链接】ops-math 本项目是CANN提供的数学类基础计算算子库,实现网络在NPU上加速计算。 项目地址: https://gitcode.com/cann/ops-math 📄 查看源码 产品支持情况 产品是否支持Ascend 950PR/Ascend 950DT√Atlas …...

VSCode扩展离线下载器:原理、部署与内网开发实践

1. 项目概述:一个解决离线安装痛点的实用工具 作为一名长期在多种网络环境下工作的开发者,我深知离线安装开发工具的痛点。尤其是在内网开发、网络受限或需要批量部署开发环境的场景下,如何获取并安装VSCode扩展,常常是一个令人头…...

易元AI保姆级上手指南:30分钟从小白到批量出片生成式AI将重新定义电商

易元AI保姆级上手指南:30分钟从小白到批量出片 生成式AI将重新定义电商增长,你的认知准备好了吗?电商AI视频生成正在成为短视频电商未来趋势中的关键变量。过去,电商增长依赖流量红利与运营能力,而在当前阶段&#xf…...