【深度好文】二维图像傅里叶变换 YYDS

article/2025/10/3 2:53:21

请添加图片描述

1. 傅里叶变换原理

在数学中进行傅里叶变换为连续模拟信号,通常来说:
二维连续函数f(x,y)的傅里叶正变换为:
在这里插入图片描述

相应的傅里叶逆变换公式为:
在这里插入图片描述
但是在计算机领域,计算机一般处理的是数字信号,只能进行有限次计算,因此将这种受限下的傅里叶变换成为离散傅里叶变换(Discrete Fourier Transform,DFT)。

二维离散函数f(x,y)的傅里叶正变换的公式如下:

在这里插入图片描述
相应的傅里叶逆变换的公式如下:
在这里插入图片描述

2. 傅里叶变换性质

这里列出来书本上介绍的关于傅里叶变换的一些性质,仅供参考,不做详述。
在这里插入图片描述
在这里插入图片描述

3. 傅里叶变换python实现

3.1 傅里叶正变换实现

参考上述傅里叶正变换给出的公式,这里给出其python实现如下:

def DFT2D(x, shift=True):'''Discrete space fourier transformx: Input matrix'''pi2 = 2*np.piN1, N2 = x.shapeX = np.zeros((N1, N2), dtype=np.complex64)n1, n2 = np.mgrid[0:N1, 0:N2]for w1 in range(N1):for w2 in range(N2):j2pi = np.zeros((N1, N2), dtype=np.complex64)j2pi.imag = pi2*(w1*n1/N1 + w2*n2/N2)X[w1, w2] = np.sum(x*np.exp(-j2pi))if shift:X = np.roll(X, N1//2, axis=0)X = np.roll(X, N2//2, axis=1)return X

3.2 傅里叶逆变换实现

参考上述傅里叶逆变换给出的公式,这里给出其python实现如下:

def iDFT2D(X, shift=True):'''Inverse discrete space fourier transformX: Complex matrix'''pi2 = 2*np.piN1, N2 = X.shapex = np.zeros((N1, N2))k1, k2 = np.mgrid[0:N1, 0:N2]if shift:X = np.roll(X, -N1//2, axis=0)X = np.roll(X, -N2//2, axis=1)for n1 in range(N1):for n2 in range(N2):j2pi = np.zeros((N1, N2), dtype=np.complex64)j2pi.imag = pi2*(n1*k1/N1 + n2*k2/N2)x[n1, n2] = abs(np.sum(X*np.exp(j2pi)))return 1/(N1*N2)*x

3.3 测试用例

这里给出测试用例,如下:

import matplotlib.pyplot as plt
import numpy as np
import imageio
from _utils import *
image = imageio.imread('./sample/cameraman.png')
s = 4
image = image[::s, ::s]/255
N1, N2 = image.shape
IMAGE = DFT2D(image)
xX = np.array([image, np.log10(1 + abs(IMAGE))])
panel(xX, [2, 1], text_color='green',texts=['Input image', 'Spectrum'])
image_ = iDFT2D(IMAGE)
Xx_ = np.array([np.log10(1 + abs(IMAGE)), image_])
panel(Xx_, [2, 1], text_color='green',texts=['Spectrum', 'Reconstructed image'])

傅里叶正变换运行结果如下:
在这里插入图片描述
傅里逆正变换运行结果如下:
在这里插入图片描述

4. 傅里叶变换cuda实现

上述Python代码的运行时间复杂度为 O(N^2),图像较大时,运行贼慢。这里考虑用cuda对其加速,搜索了半天,发现有大佬曾经做过类似的实现,并给出了源码,这里直接参考其实现对其进行简单的封装,可以调用完成图像的傅里叶变换以及视频的傅里叶变换。

这里给出FFT.cu的核心代码片段:

#include "fft.h"
#include "cuda_runtime.h"__device__ unsigned char getr(float x) {return (tanh((x - 0.375f) * 6.0f) + 1.0f) * 127.0f;
}
__device__ unsigned char getg(float x) {return (tanh((x - 0.6250f) * 6.0f) + 1.0f) * 127.0f;
}
__device__ unsigned char getb(float x) {return (exp(-20.0f * (x - 0.25f) * (x - 0.25f) - 2.0f * exp(-(x + 0.05f) * (x + 0.05f) * 144.0f)) * 0.5f + 1.0f + tanh((x - 0.875f) * 6.0f)) * 127.0f;
}
__global__ void imgfill(float2* d_k, uchar3* d_img,int size)
{int x = threadIdx.x + blockIdx.x * blockDim.x;int y = threadIdx.y + blockIdx.y * blockDim.y;int imgx, imgy;imgx = (x >= size / 2) ? x - size / 2 : x + size / 2;imgy = (y >= size / 2) ? y - size / 2 : y + size / 2;float2 k = d_k[y * size + x];float in = k.x * k.x + k.y * k.y;in = log(in * (1.0f / 256.0f/size) + 0.8f) * 0.07f;uchar3 c;c.x = getb(in);c.y = getg(in);c.z = getr(in);d_img[imgy * size + imgx] = c;
}__global__ void fill(float2* d_x, uchar3* d_8uc3,int size,int w,int h) {int x = threadIdx.x + blockIdx.x * blockDim.x;int y = threadIdx.y + blockIdx.y * blockDim.y;int imgx, imgy;float cx, cy;unsigned char r;if (x >= size / 2 + w / 2) {imgx = 0;cx = size - x;cx = exp(-cx * cx * (1.0f / 1024.0f));}else if (x < size / 2 + w / 2 && x >= w) {imgx = w - 1;cx = x - w;cx = exp(-cx * cx * (1.0f / 1024.0f));}else {imgx = x;cx = 1.0f;}if (y >= size / 2 + h / 2) {imgy = 0;cy = size - y;cy = exp(-cy * cy * (1.0f / 1024.0f));}else if (y < size / 2 + h / 2 && y >= h) {imgy = h - 1;cy = y - h;cy = exp(-cy * cy * (1.0f / 1024.0f));}else {imgy = y;cy = 1.0f;}r = d_8uc3[imgy * w + imgx].x;d_x[y * size + x].x = r * cx * cy;d_x[y * size + x].y = 0;
}void fft_tranformer(uchar3 * d_8uc3,float2 * d_x,float2 * d_k,uchar3 *d_img,cufftHandle *fftPlan,unsigned char * pframe,unsigned  char * pDst,int width,int height,int size)
{cudaMemcpy(d_8uc3, pframe, width * height * 3, cudaMemcpyHostToDevice);fill << < dim3(size / 128, size, 1), dim3(128, 1, 1) >> > (d_x, d_8uc3,size,width,height);cufftExecC2C(*fftPlan, d_x, d_k, CUFFT_FORWARD);imgfill << < dim3(size / 128, size, 1), dim3(128, 1, 1) >> > (d_k, d_img,size);cudaMemcpy(pDst, d_img, size * size * 3, cudaMemcpyDeviceToHost);
}

5. cuda实现效果

5.1 静态效果

在这里插入图片描述
在这里插入图片描述

5.2 动态效果

在这里插入图片描述

在这里插入图片描述



5.3 完整带音乐视频效果

点我


6. 代码

完整代码可公众号内回复DFT 即可获取


7. 参考


链接一

链接二



关注公众号《AI算法之道》,获取更多AI算法资讯.

在这里插入图片描述


http://chatgpt.dhexx.cn/article/mF64Xtgq.shtml

相关文章

微信公众号开发模式没有域名怎么办?申请免费域名

微信公众号开发采用前后端分离模式&#xff0c;那么前端使用微信开发工具开发时&#xff0c;需要域名才能访问&#xff0c;那么域名从何而来呢&#xff1f; 1、申请域名 a)、NetApp申请免费域名 : https://natapp.cn/login b)、域名申请好以后&#xff0c;下载客户端&#xf…

freenom 申请免费域名

为了降低建站成本&#xff0c;可在freenom上申请免费域名&#xff0c;可以免费使用一年。 一. 注册域名 登录freenom.com&#xff0c;输入域名&#xff0c;检测通过后&#xff0c;输入邮箱&#xff0c;登录邮箱完成激活。 二. 配置DNS 上面申请的域名未绑定外网ip&#xff0c…

如何注册一个免费的网站空间和域名

https://www.jianshu.com/p/016c83f70d43 前几天想搞个网站玩玩&#xff0c;于是就上网搜哪里可以注册免费的网站空间和域名&#xff0c;折腾了好几天都没注册成&#xff0c;国内好像已经没有免费的了。只好用英文去搜国外的网站&#xff0c;才找到了一个能注册成功的&#xff…

Freenom免费域名申请

Freenom免费域名申请 准备条件操作流程注意选择域名确定并提交订单方法一(谷歌&#xff0c;FaceBook)方法二(开发者邮箱注册) 注册谷歌&#xff0c;Facebook 注册 防订单失败操作 准备条件 必须拥有一个 谷歌账号 或 Facebook 账号 亦或者 拥有一个 未注册Freenom的邮箱 登录 …

【免费域名】教你免费申请顶级域名

一、输入网址 &#xff1a;https://my.freenom.com/ 二、点击Service->Register a New Domain&#xff0c;注意这里有网络延时至少30秒 三、输入自己想要的域名&#xff0c;点击Check Avaliability&#xff0c;比如我的是abc5500&#xff0c;延时10秒 四、Get it now! ->…

免费域名证书最新申请方式大全

目前市场环境下&#xff0c;可获得域名SSL证书的方式有很多&#xff0c;一般有付费和免费划分。对于想免费使用域名SSL证书的朋友&#xff0c;这里收集整理了几个常用的SSL证书申请方式。 对于SSL证书的用处&#xff0c;简单的来说&#xff0c;就是加密数据传输&#xff0c;使…

免费域名申请及免费DNS解析

一&#xff1a;免费域名申请 1&#xff1a;freenom免费域名申请&#xff08;有效期12个月&#xff09; 我是通过科学上网才申请成功。普通方式申请容易出现各种问题不成功。因为freenom网站要连接国外各种服务器检测域名的可用性。 如下图申请成功的域名&#xff1a; 域名再DNS…

freenom域名申请教程

freenom域名申请教程 1. 注册&申请域名 打开freenom官网&#xff0c;注册一个账户【注意&#xff1a;如果没有明显的注册按钮&#xff0c;可以通过如下方式同时申请域名和注册账户】 打开域名申请【不用注册】 选择好了域名之后&#xff0c;点击Checkout&#xff1b;选择…

freenom免费域名的申请+cloudflare(域名代理解析)

视频网址:公众号知识浅谈回复 freenom+cloudflare 领取 第一步:注册 freenom{申请免费域名}: https://my.freenom.com/ 注册步骤 首页->partners->Devlopers->下滑找到Get a Random Domains Account today! 这句话,点击之后进入下一个页面 然后去邮箱激活,再次重复上…

免费申请国外免费域名超详细教程

注意事项&#xff1a; 1.需要准备好VPN&#xff08;因为是用的国外的&#xff0c;不会搭建的可以看我之前的笔记笔记地址&#xff09; 2.手机下载Gmail, 注册谷歌邮箱&#xff0c;国内手机号就可以注册手机邮箱 3.谷歌邮箱内验证freenom注册信息时候需要美区手机号验证。这里给…

freenom 加 cloudflare免费域名申请

https://www.freenom.com/zh/index.html?langzh 该网站管理 .tk .ml 等后缀 输入如 aaa.tk购买时需要账号&#xff08;免费购买&#xff09;&#xff0c;需要一个谷歌账号&#xff0c;可以 social login 购买成功后&#xff0c;可以看见域名 打开 https://dash.cloudflare.…

申请免费域名、配置域名以及https证书设置

如何申请免费域名 域名申请官方网站 https://my.freenom.com/clientarea.php 详细的申请教程可以查看都比根据地良心教程 https://doub.io/dbwz-3/ 我申请的免费域名 如何用刚申请到的域名 现在我们有了域名&#xff0c;接下来就是解析域名了&#xff0c;也就是域名配置绑定…

不花一分钱申请免费域名和ssl证书

最近想申请个域名做测试&#xff0c;在网上搜了下&#xff0c;找到了个免费申请的网站&#xff0c;顺便使用这个域名申请了ssl的证书(不用花任何钱)&#xff0c;整理了下分享出来。 如果是想要一个临时使用的域名可以按照下面的办法申请&#xff0c;如果是想长期使用&#xff…

免费申请国外免费域名保姆级教程

注意事项&#xff1a; 1.需要准备好VPN&#xff08;因为是用的国外的&#xff0c;不会搭建的可以看我之前的笔记笔记地址&#xff09; 2.手机下载Gmail, 注册谷歌邮箱&#xff0c;国内手机号就可以注册手机邮箱 3.gg邮箱内验证freenom注册信息时候需要美区手机号验证。这里给大…

Freenom 申请免费域名(二)

需要准备的东西 能用代理上网能安装一下 chrome 浏览器插件 Gooreplacer 注册一个账号 说个最简单的方法&#xff0c; 进 freenom官网&#xff0c;点击合作伙伴下的开发者&#xff08;这个网站可以改中文&#xff0c;最右边&#xff09;找到今天就获得一个随机域账户&#x…

免费域名的申请

最近打算自己做个网站玩玩&#xff0c;于是去freenom申请了免费域名&#xff0c;记录一下具体流程。 freenom的网址&#xff1a;https://my.freenom.com/clientarea.php 首先&#xff0c;点击右上角services里面的Register a New Domain。 在对话框里面输入想要申请的域名&am…

免费域名申请

title: 免费域名申请 20230428153405|left &#x1f308;Description&#xff1a; ​ 本文将介绍如何免费申请域名&#xff0c;在最近的折腾中发现&#xff0c;域名真的很重要&#xff0c;不然好多服务是无法访问的。 备注&#xff1a;由于freenom基于技术原因&#xff0c;暂时…

如何免费注册一个域名?

1、今天教大家如何不花钱免费获取一个商用域名&#xff0c;首先打开浏览器&#xff0c;新建一个无痕窗口&#xff0c;然后在无痕模式下输入freenom.com&#xff0c;进入网站是这样的界面&#xff1a; 2、由于海外环境原因&#xff0c;如果打不开网站或者打开慢的请使用那个啥。…

给自己记录下申请免费域名的过程

网上已经有很多这类教程&#xff0c;所以在这里我只是给自己记录下这个过程&#xff0c;包括给二级域名申请证书和设置DDNS。 我是想给群晖自行搭建个Bitwarden密码库&#xff0c;本来我是想局域网访问就行&#xff0c;奈何Bitwarden密码库必须要https才能注册账号&#xff0c;…

Freenom申请免费域名

准备材料 一枚邮箱 过程 1.点击这里&#xff0c;查看你自己的IP所在国家 2.打开Freenom官网 3.依次点击“Partners”→“Developers” 4.把网页往下拉&#xff0c;点击绿色的“Get a Random Domains Account today!” 5.输入邮箱地址&#xff0c;然后点击“Verify my Emai…