基于OpenCV-Python的彩色图像傅里叶变换

news2024/9/25 17:16:51

在这里插入图片描述

如果用OpenCV-Python进行图像的离散傅里叶变换与逆变换其实还蛮简单的,流程就是上图所示,值得注意的是,如果是多通道的图像,譬如多光谱、高光谱图像,需要对每个通道都进行傅里叶变换,最后再聚合,如果只是RGB,可以用如下方式合成灰度图,只需要对灰度图做处理即可。

img1 = 0.2126 * image1[:,:,0] + 0.7152 * image1[:,:,1] + 0.0722 * image1[:,:,2]
import cv2 as cv  
import numpy as np  
import matplotlib.pyplot as plt  
  
# 测试图像  
ori=cv.imread(r"F:\ori.jpg")  
  
# numpy 中的 fft 需要输入灰度图,我们需要将图像分割成不同的通道  
def getRGBDFT(img):  
    # cv2默认的图像通道是BGR,需要进行转换  
    img=cv.cvtColor(img,cv.COLOR_BGR2RGB)  
    # 分离通道  
    r,g,b=cv.split(img)  
    # 对每个通道进行傅里叶变换  
    f_r,f_g,f_b=_dft(r),_dft(g),_dft(b)  
    # 组合通道,还是以bgr格式返回  
    return cv.merge([f_b,f_g,f_r])  
  
def _dft(img):  
    f=cv.dft(np.float32(img),flags=cv.DFT_COMPLEX_OUTPUT)  
    # 计算幅度谱  
    magnitude=cv.magnitude(f[:,:,0],f[:,:,1])  
    # 对数变换增强对比度  
    res=np.log(magnitude+1)  
    # 移动低频分量至中心  
    return np.fft.fftshift(res)  
  
out=getRGBDFT(ori)  
  
# 选取
plt.subplot(121),plt.imshow(ori[:,:,0],cmap='gray')  
plt.title("Ori"),plt.xticks([]),plt.yticks([])  
plt.subplot(122),plt.imshow(out[:,:,0],cmap='gray')  
plt.title("Magnitude"),plt.xticks([]),plt.yticks([])  
plt.show()

我们查看B通道的图像与傅里叶幅度谱:
在这里插入图片描述
接下来要进行傅里叶逆变换,代码如下:

def _idft(img):  
    img=np.fft.ifftshift(img)  
    img=cv.idft(img)  
    return cv.magnitude(img[:,:,0],img[:,:,1])

在这里插入图片描述

若要在频域上做处理,可以添加掩膜:

def _Mask(img,type=None,d=2,size=4):  
    row,col=img.shape[:-1]  
    if type==None:  
        return np.ones((row,col,d),np.uint8)  
    if type == "LPF":  
        mask=np.zeros((row,col,d),np.uint8)  
        mask[row//size:row//size*(size-1),col//size:col//size*(size-1)]=1  
    elif type=="HPF":  
        mask = np.ones((row, col,d), np.uint8)  
        mask[row//size:row//size*(size-1),col//size:col//size*(size-1)] = 0  
    else:  
        mask=np.ones((row,col,d),np.uint8)  
        mask[row // 2-30:row // 2+30, col // 2-30:col // 2+30] = 0  
    return mask

def _idft(img,mask=None):  
    # img=_Mask(img,type)*img  
    if mask!=None:  
        img=mask*np.fft.ifftshift(img)  
    else:  
        img=np.fft.ifftshift(img)  
    img=cv.idft(img)  
    return cv.magnitude(img[:,:,0],img[:,:,1])

在这里插入图片描述

彩色图像结果:
在这里插入图片描述

如果想要用A图的高频细节替换B图,可以如下处理:

def _normal(img):  
    a,b=img.max(),img.min()  
    return np.clip((img-b)/(a-b),0,1)

def swap(ori,aug):  
    oriFFT=getRGBDFT(ori)  
    augFFT=getRGBDFT(aug)  
    HPF=_Mask(ori,"HPF",size=3)  
    LPF=_Mask(ori,"LPF",size=16)  
    res=[augFFT[i]*LPF+oriFFT[i]*HPF for i in range(len(oriFFT))]  
    res=[_normal(_idft(i)) for i in res]  
    return cv.merge(res)

在这里插入图片描述

完整代码如下:

import cv2 as cv  
import numpy as np  
import matplotlib.pyplot as plt  
  
# 测试图像  
ori=cv.imread(r"F:\ori.jpg")  
aug=cv.imread(r"F:\129.jpg")  
  
# numpy 中的 fft 需要输入灰度图,我们需要将图像分割成不同的通道  
def getRGBDFT(img):  
    # cv2默认的图像通道是BGR,需要进行转换  
    img=cv.cvtColor(img,cv.COLOR_BGR2RGB)  
    # 分离通道  
    r,g,b=cv.split(img)  
    # 对每个通道进行傅里叶变换  
    f_r,f_g,f_b=_dft(r,False),_dft(g,False),_dft(b,False)  
    # 组合通道,还是以bgr格式返回  
    # return cv.merge([f_b,f_g,f_r])  
    return [f_b,f_g,f_r]  
def _dft(img,to_show=True):  
    f=cv.dft(np.float32(img),flags=cv.DFT_COMPLEX_OUTPUT)  
    # 计算幅度谱  
    if to_show:  
        # 对数变换增强对比度  
        magnitude = cv.magnitude(f[:, :, 0], f[:, :, 1])  
        f=np.log(magnitude+1)  
    # 移动低频分量至中心  
    return np.fft.fftshift(f)  
def _idft(img,mask=None):  
    # img=_Mask(img,type)*img  
    if mask!=None:  
        img=mask*np.fft.ifftshift(img)  
    else:  
        img=np.fft.ifftshift(img)  
    img=cv.idft(img)  
    return cv.magnitude(img[:,:,0],img[:,:,1])  
def _Mask(img,type=None,d=2,size=4):  
    row,col=img.shape[:-1]  
    if type==None:  
        return np.ones((row,col,d),np.uint8)  
    if type == "LPF":  
        mask=np.zeros((row,col,d),np.uint8)  
        mask[row//size:row//size*(size-1),col//size:col//size*(size-1)]=1  
    elif type=="HPF":  
        mask = np.ones((row, col,d), np.uint8)  
        mask[row//size:row//size*(size-1),col//size:col//size*(size-1)] = 0  
    else:  
        mask=np.ones((row,col,d),np.uint8)  
        mask[row // 2-30:row // 2+30, col // 2-30:col // 2+30] = 0  
    return mask  
def _normal(img):  
    a,b=img.max(),img.min()  
    return np.clip((img-b)/(a-b),0,1)  
def getRGBIDFT(img,type):  
    fft=getRGBDFT(img)  
    ifft=[_normal(_idft(i,type)) for i in fft]  
    return cv.merge(ifft)  
  
def swap(ori,aug):  
    oriFFT=getRGBDFT(ori)  
    augFFT=getRGBDFT(aug)  
    HPF=_Mask(ori,"HPF",size=3)  
    LPF=_Mask(ori,"LPF",size=4)  
    res=[augFFT[i]*LPF+oriFFT[i]*HPF for i in range(len(oriFFT))]  
    res=[_normal(_idft(i)) for i in res]  
    return cv.merge(res)  
  
  
res=swap(ori,aug)  
plt.subplot(131),plt.imshow(ori)  
plt.title("Ori"),plt.xticks([]),plt.yticks([])  
plt.subplot(132),plt.imshow(aug)  
plt.title("Aug"),plt.xticks([]),plt.yticks([])  
plt.subplot(133),plt.imshow(res)  
plt.title("res"),plt.xticks([]),plt.yticks([])  
plt.show()

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

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

相关文章

数字乡村 | 是什么、建什么、怎么建?附200份详尽解决方案下载

数字乡村是什么 如何将数字乡村建设与全面实施乡村振兴战略有效衔接,已成为当前农业农村工作的重要课题。 200份资料下载方式,请看每张图片右下角信息 数字乡村作为一种新的乡村社会发展形态,是当今第四次工业革命工业互联网 生态系统的持…

如何在Java中调用数学中的log函数

在Java中,调用数学中的对数(log)函数通常是通过Math类来实现的。Math类提供了多种对数函数的实现,但最常用的是自然对数(底数为e的对数)和以10为底的对数。 自然对数(底数为e) 使用…

深度学习之参数初始化问题

参数初始化 1、 参数初始化可以减缓梯度爆炸和梯度消失问题 2、tanh一般使用Xavier初始化方法 3、Relu及其变种使用Kaiming初始化方法 V a r ( X ) E ( X 2 ) − E ( X ) 2 V a r ( X Y ) V a r ( X ) V a r ( Y ) , 当 X 和 Y 互相独立 V a r ( X Y ) V a r ( X ) V a r…

【机器学习基础】Scikit-learn主要用法

【作者主页】Francek Chen 【专栏介绍】 ⌈ ⌈ ⌈Python机器学习 ⌋ ⌋ ⌋ 机器学习是一门人工智能的分支学科,通过算法和模型让计算机从数据中学习,进行模型训练和优化,做出预测、分类和决策支持。Python成为机器学习的首选语言,…

C语言 ——— 学习、使用 strstr函数 并模拟实现

目录 strstr函数的功能 学习strstr函数​编辑 使用strstr函数 模拟实现strstr函数 strstr函数的功能 在字符串 str1 中找 str2 字符串,如果在 str1 字符串中找到了 str2 字符串,就返回 str1 中找到的 dtr2 的地址,没找到的话就返回 NU…

[CR]厚云填补_MSDA-CR

Cloud Removal in Optical Remote Sensing Imagery Using Multiscale Distortion-Aware Networks Abstract 云层污染是光学遥感图像中常见的问题。基于深度学习的遥感图像去云技术近年来受到越来越多的关注。然而,由于缺乏对云失真效果的有效建模和网络较弱的特征表…

EasyMR如何为服务开启Kerberos

作者:雅泽 一、Hadoop为什么需要安全 最早部署Hadoop集群时并没有考虑安全问题,未开启安全认证时,Hadoop 是以客户端提供的用户名作为用户凭证, 一般即是发起任务的Unix 用户。一般线上机器部署服务会采用统一账号,当…

CPU与Load

1、CPU和LOAD分别是什么load就是负载吗,跟CPU啥关系,啥区别 CPU和Load(负载)是衡量计算机系统性能的两个重要指标,但它们关注的侧重点和意义不同。理解这两个指标及它们之间的关系对于系统优化和性能监控非常重要。 CP…

【C++】数组案例 五只小猪称体重

题目:给出物质小猪体重,找出最大的体重的值并打印 思路:利用菽粟写入五只小猪的体重,让每一个元素都赋值给一个整型变量并每赋值一次就于下一个数组中的元素比,若是大就继续赋值给这个变量,若是小则不赋值…

【QT】qss

目录 基本语法 设置全局样式 问题 分离样式代码 方案1 方案2 选择器 概况 子控件选择器 伪类选择器 盒子模型 修改控件样式示例 按钮 属性小结 复选框 属性小结 输入框 属性小结 列表框 属性小结 渐变色 示例: 菜单栏 设置菜单栏的背景…

clang 编译cuda原理

背景 最近在看一门julia的语言,里面是原生支持cuda的,不过在国产卡上却无法适配,为了开展工作有必要了解非常清楚整个编译的机制。此外在研究过程中发现openai 的triton,以及tvm等一些ai框架对nvidia的支持原理都及其类似&#x…

LinkedList接口源码解读

LinkedList 接口源码解读(一) 前言 因为追求质量,所以写的较慢。大概在接下来的三天内会把LinkedList源码解析出完。大概还有两篇文章。废话不多说,正片开始! 大家都知道,LinkedList是在Java底层中是由 …

【C++标准模版库】模拟实现vector+迭代器失效问题

模拟实现vector 一.vector成员变量二.构造函数1.无参(默认)构造2.有参构造3.拷贝构造1.传统写法2.现代写法 三.vector对象的容量操作1.size2.capacity3.clear4.empty5.reserve6.resize 四.vector对象的访问及遍历操作1.operator[]2.实现迭代器&#xff1…

一次Linux端口冲突问题排查记录

更多技术博客,请关注微信公众号:运维之美 一、问题现象 实施同学反馈说我们的服务部署到客户环境后,运行正常,但是后台页面就是无法打开,出现访问白屏问题 从console报错看是其中一个接口响应存在问题,…

老兵永远跟党走,团结奋进新征程-百余老兵庆八一暨《永远闪光的军徽》新书发布座谈会在昆举行

7月30日上午,由中国红色文化研究会老山精神专业委员会主办,昆明乡羊香园承办的百余老兵庆祝“八一”建军节暨《永远闪光的军徽》新书发布座谈会在昆明滇池湖畔乡羊香园举行。 上午10时左右,老战士、曾担任云南省军区领导的黄光汉、陶昌廉、和志光、李继才、雷玉德、王永银老将军…

海思Hi35XX系列(一)环境搭建与挂载

小白一个,新的开发板刚到手有点懵,之前没弄过没有经验,简单记录一下吧 一般买开发板都会给带一个已经配置好的虚拟机文件,直接使用就可以 一、下载安装虚拟机与镜像文件 VMware-workstation16.1.0 我的镜像文件是官方文档资料…

亨廷顿小勇士必看!你的维生素补给站来啦~

Hey小伙伴们~👋 今天咱们来聊聊一个超勇敢的话题——亨廷顿舞蹈症宝贝们的健康小秘密!🎉 虽然路途偶尔有点小颠簸,但记得哦,你们是最闪耀的星星✨!让我们一起加油,用对维生素,守护这…

C#知识|文件与目录操作:对象的创建、保存、读取

哈喽,你好啊,我是雷工! 面向对象编程的特点就是一切皆对象,操作的也是对象,本节学习文件与目录操作中,对象的保存; 以下为学习笔记。 01 对象的特点 ①:对象运行在内存中&#xff…

4.5K Stars!为 RAG 而生的数据工程神器

—1 大模型 RAG 的难题是什么? RAG 或者 Fine-tuning 微调作为大模型的增强技术,最核心的技术在于如何把企业的私有数据清洗转换成知识,企业中能够第一时间拿到的私有数据,往往是异构的、数据质量参差不齐,通过数据…

ICM-20948芯片详解(3)

接前一篇文章:ICM-20948芯片详解(2) 三、引脚图、信号描述及内部框图 1. 引脚图 ICM-20948的引脚图如下图所示: 2. 引脚详细描述 ICM-20948的引脚详细描述如下表所示: 注意:不支持在SCL/SCLK和nCS引脚保…