基于OpenCV-Python的彩色图像傅里叶变换
创始人
2024-11-13 15:40:34
0

在这里插入图片描述

如果用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() 

相关内容

热门资讯

攻略辅助!德州私人局怎么透视,... 攻略辅助!德州私人局怎么透视,wejoker辅助软件视频,解迷教程(竟然有挂)该软件可以轻松地帮助玩...
必知教程!微乐小程序黑科技,7... 必知教程!微乐小程序黑科技,789大菠萝可以控制吗,积累教程(真的有挂)1、上手简单,内置详细流程视...
步骤辅助!竞技联盟破解版最新版... 步骤辅助!竞技联盟破解版最新版,hhpoker免费透视脚本,推荐教程(发现有挂)1、让任何用户在无需...
分享给玩家!创思维激k辅助工具... 分享给玩家!创思维激k辅助工具,约局吧辅助器,讲义教程(有挂总结)该软件可以轻松地帮助玩家将创思维激...
妙招辅助!德扑之心免费透视,w... 妙招辅助!德扑之心免费透视,wepoker怎么开辅助,辅助教程(有挂工具)1、玩家可以在德扑之心免费...
玩家必备教程!皮皮游戏辅助平台... 玩家必备教程!皮皮游戏辅助平台,朱雀开心罗松怎么开挂,资料教程(有挂透视)1、皮皮游戏辅助平台脚本辅...
总结辅助!hhpoker是正品... 总结辅助!hhpoker是正品吗,aapoker透视怎么用,解谜教程(有挂实锤)1)aapoker透...
今日重大通报!微信广东雀神挂件... 今日重大通报!微信广东雀神挂件辅助,随意玩辅助器,指南教程(有挂教学)1.微信广东雀神挂件辅助 选牌...
资料辅助!wepoker有辅助... 资料辅助!wepoker有辅助工具吗,wepoker软件安装包,教你教程(竟然有挂)小薇(辅助器软件...
实测分享!广西友乐免费辅助,新... 实测分享!广西友乐免费辅助,新荣耀辅助软件,指南书教程(有挂规律)1、玩家可以在广西友乐免费辅助透视...