【经典算法实现 42】二维傅里叶变换 及 逆变换代码实现
二维傅里叶变换:
F ( u , v ) = ∑ M x = 0 , M y = 0 M x − 1 , M y − 1 f ( x , y ) e − j 2 π ( u x M x + v y M y ) , u = 0 , 1 , 2 , ⋯ , M − 1 F(u,v) = \sum_{M_x=0,M_y=0}^{M_x-1,M_y-1} f(x,y) e^{-j 2\pi (\frac {ux} {M_x}+\frac {vy} {M_y})}, u=0,1,2,\cdots,M-1 F(u,v)=Mx=0,My=0∑Mx−1,My−1f(x,y)e−j2π(Mxux+Myvy),u=0,1,2,⋯,M−1
二维傅里叶逆变换:
f
(
x
,
y
)
=
1
M
u
⋅
M
v
∑
M
u
=
0
,
M
v
=
0
M
u
−
1
,
M
v
−
1
F
(
u
,
v
)
e
−
j
2
π
(
u
x
M
x
+
v
y
M
y
)
,
x
=
0
,
1
,
2
,
⋯
,
M
−
1
f(x,y) = {\frac 1 {M_u\cdot M_v}} \sum_{M_u=0,M_v=0}^{M_u-1,M_v-1} F(u,v) e^{-j 2\pi (\frac {ux} {M_x}+\frac {vy} {M_y})}, x=0,1,2,\cdots,M-1
f(x,y)=Mu⋅Mv1Mu=0,Mv=0∑Mu−1,Mv−1F(u,v)e−j2π(Mxux+Myvy),x=0,1,2,⋯,M−1
令 w = 2 π ( u x M x + v y M y ) w = 2\pi (\frac {ux} {M_x}+\frac {vy} {M_y}) w=2π(Mxux+Myvy),可得:
二维傅里叶变换:
F ( u , v ) = ∑ M x = 0 , M y = 0 M x − 1 , M y − 1 f ( x , y ) ⋅ { cos ( w ) − sin ( w ) j } , u = 0 , 1 , 2 , ⋯ , M − 1 F(u,v) = \sum_{M_x=0,M_y=0}^{M_x-1,M_y-1} f(x,y) \cdot \lbrace \cos(w) - \sin(w) j \rbrace , u=0,1,2,\cdots,M-1 F(u,v)=Mx=0,My=0∑Mx−1,My−1f(x,y)⋅{cos(w)−sin(w)j},u=0,1,2,⋯,M−1
二维傅里叶逆变换:
f
(
x
,
y
)
=
1
M
u
⋅
M
v
∑
M
u
=
0
,
M
v
=
0
M
u
−
1
,
M
v
−
1
F
(
u
,
v
)
⋅
{
cos
(
w
)
−
sin
(
w
)
j
}
,
x
=
0
,
1
,
2
,
⋯
,
M
−
1
f(x,y) = {\frac 1 {M_u\cdot M_v}} \sum_{M_u=0,M_v=0}^{M_u-1,M_v-1} F(u,v) \cdot \lbrace \cos(w) - \sin(w) j \rbrace , x=0,1,2,\cdots,M-1
f(x,y)=Mu⋅Mv1Mu=0,Mv=0∑Mu−1,Mv−1F(u,v)⋅{cos(w)−sin(w)j},x=0,1,2,⋯,M−1
f ( x , y ) = 1 M u ⋅ M v ∑ M u = 0 , M v = 0 M u − 1 , M v − 1 { F ( u , v ) . r e a l ⋅ cos ( w ) − F ( u , v ) . i m a g ⋅ sin ( w ) } + j ⋅ { F ( u , v ) . i m a g ⋅ cos ( w ) + F ( u , v ) . r e a l ⋅ sin ( w ) } , x = 0 , 1 , 2 , ⋯ , M − 1 f(x,y) = {\frac 1 {M_u\cdot M_v}} \sum_{M_u=0,M_v=0}^{M_u-1,M_v-1} \lbrace F(u,v).real \cdot \cos(w) - F(u,v).imag \cdot\sin(w) \rbrace + \\ j \cdot \lbrace F(u,v).imag \cdot \cos(w) + F(u,v).real \cdot \sin(w) \rbrace , x=0,1,2,\cdots,M-1 f(x,y)=Mu⋅Mv1Mu=0,Mv=0∑Mu−1,Mv−1{F(u,v).real⋅cos(w)−F(u,v).imag⋅sin(w)}+j⋅{F(u,v).imag⋅cos(w)+F(u,v).real⋅sin(w)},x=0,1,2,⋯,M−1
代码实现如下:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <math.h>
#define VALUE_MAX 255
#define X_NUM 6
#define Y_NUM 6
struct _complex f[Y_NUM][X_NUM]; // 傅里叶变换的原始数据
struct _complex F[Y_NUM][X_NUM]; // 傅里叶变换后的数据
struct _complex IF[Y_NUM][X_NUM]; // 傅里叶逆变换后的数据
void Init_data(void)
{
int x, y;
srand(time(NULL));
printf("初始化数据:\n");
for(y = 0; y<Y_NUM; y++){
for(x = 0; x<X_NUM; x++){
f[y][x].x = rand() %VALUE_MAX;
f[y][x].y = 0;
printf("%7.3f ", f[y][x].x);
F[y][x].x = 0;
F[y][x].y = 0;
IF[y][x].x = 0;
IF[y][x].y = 0;
}
printf("\n");
}
printf("\n\n");
}
void dft_2d(void)
{
int u, v, x, y;
double w;
for(v = 0; v<Y_NUM; v++)
{
for(u = 0; u<X_NUM; u++)
{
// 开始变换
for(y = 0; y<Y_NUM; y++){
for(x = 0; x<X_NUM; x++)
{
w = 2 * M_PI *((double)u*x/(double)X_NUM + (double)v*y/(double)Y_NUM);
F[v][u].x += cos(w) * f[y][x].x;
F[v][u].y += -1 * sin(w) * f[y][x].x;
}
}
printf("F[%2d][%2d] = %11lf %s %11lfj \n", v, u, F[v][u].x, F[v][u].y<0?"-":"+", F[v][u].y<0?-F[v][u].y:F[v][u].y);
}
printf("\n");
}
}
void idft_2d(void)
{
int u, v, x, y;
double w;
for(v = 0; v<Y_NUM; v++)
{
for(u = 0; u<X_NUM; u++)
{
// 开始变换
for(y = 0; y<Y_NUM; y++){
for(x = 0; x<X_NUM; x++)
{
w = 2 * M_PI *((double)u*x/(double)X_NUM + (double)v*y/(double)Y_NUM);
IF[v][u].x += cos(w) * F[y][x].x - sin(w) * F[y][x].y;
IF[v][u].y += cos(w) * F[y][x].y + sin(w) * F[y][x].x;
}
}
IF[v][u].x /= (X_NUM * Y_NUM);
IF[v][u].y /= (X_NUM * Y_NUM);
printf("%3.0lf %s%2.0fj ", IF[v][u].x, IF[v][u].y<0?"-":"+", IF[v][u].y<0?-IF[v][u].y<0:IF[v][u].y<0);
}
printf("\n");
}
}
int main(void)
{
Init_data();
printf("傅里叶变换:\n");
dft_2d();
printf("傅里叶逆变换:\n");
idft_2d();
return 0;
}
运行结果如下:
初始化数据:
76.000 99.000 36.000 60.000 88.000 57.000
26.000 89.000 219.000 154.000 84.000 165.000
199.000 166.000 224.000 117.000 85.000 225.000
240.000 66.000 72.000 48.000 121.000 249.000
142.000 219.000 57.000 223.000 181.000 107.000
50.000 213.000 164.000 216.000 43.000 47.000
傅里叶变换:
F[ 0][ 0] = 4627.000000 + 0.000000j
F[ 0][ 1] = 79.000000 - 148.956369j
F[ 0][ 2] = 13.000000 + 145.492268j
F[ 0][ 3] = -413.000000 - 0.000000j
F[ 0][ 4] = 13.000000 - 145.492268j
F[ 0][ 5] = 79.000000 + 148.956369j
F[ 1][ 0] = -617.500000 - 78.808312j
F[ 1][ 1] = -308.000000 - 439.940905j
F[ 1][ 2] = 422.000000 + 105.655099j
F[ 1][ 3] = -150.500000 - 267.601850j
F[ 1][ 4] = -613.000000 + 323.893501j
F[ 1][ 5] = -512.000000 + 185.329436j
F[ 2][ 0] = -495.500000 + 71.880109j
F[ 2][ 1] = 628.000000 + 538.667801j
F[ 2][ 2] = -95.000000 - 8.660254j
F[ 2][ 3] = 287.500000 + 25.114737j
F[ 2][ 4] = 172.000000 + 32.908965j
F[ 2][ 5] = 148.000000 - 239.023011j
F[ 3][ 0] = 95.000000 - 0.000000j
F[ 3][ 1] = 157.000000 + 48.497423j
F[ 3][ 2] = 77.000000 - 374.122974j
F[ 3][ 3] = 43.000000 + 0.000000j
F[ 3][ 4] = 77.000000 + 374.122974j
F[ 3][ 5] = 157.000000 - 48.497423j
F[ 4][ 0] = -495.500000 - 71.880109j
F[ 4][ 1] = 148.000000 + 239.023011j
F[ 4][ 2] = 172.000000 - 32.908965j
F[ 4][ 3] = 287.500000 - 25.114737j
F[ 4][ 4] = -95.000000 + 8.660254j
F[ 4][ 5] = 628.000000 - 538.667801j
F[ 5][ 0] = -617.500000 + 78.808312j
F[ 5][ 1] = -512.000000 - 185.329436j
F[ 5][ 2] = -613.000000 - 323.893501j
F[ 5][ 3] = -150.500000 + 267.601850j
F[ 5][ 4] = 422.000000 - 105.655099j
F[ 5][ 5] = -308.000000 + 439.940905j
傅里叶逆变换:
76 - 0j 99 - 0j 36 - 0j 60 - 0j 88 + 0j 57 - 0j
26 - 0j 89 + 0j 219 - 0j 154 + 0j 84 + 0j 165 + 0j
199 - 0j 166 + 0j 224 - 0j 117 + 0j 85 + 0j 225 + 0j
240 - 0j 66 + 0j 72 + 0j 48 - 0j 121 + 0j 249 + 0j
142 + 0j 219 + 0j 57 + 0j 223 - 0j 181 + 0j 107 + 0j
50 + 0j 213 - 0j 164 - 0j 216 + 0j 43 - 0j 47 + 0j
请按任意键继续. . .
《二维图像的傅立叶变换》
《【数字图像处理】2.2:二维DFT》
《形象理解二维傅里叶变换》
《二维傅里叶变换是怎么进行的?》
《如何理解傅里叶变换公式?》
《图像的傅里叶变换》