# 数字图像处理（二）傅里叶变换

## 数字图像处理（二）之傅里叶变换

1. 二维傅里叶变换
2. 图像二维傅里叶逆变换
3. 图像中心化傅里叶变换和谱图像
4. 图像2的整数次幂填充

### 二维傅里叶变换和逆变换

\begin{aligned} &F(u, v)=\sum_{x=0}^{M-1} \sum_{y=0}^{N-1} f(x, y) e^{-j 2 \pi\left(\frac{u x}{M}+\frac{v y}{N}\right)} \\ &f(x, y)=\frac{1}{M N} \sum_{u=0}^{M-1} \sum_{v=0}^{N-1} F(u, v) e^{j 2 \pi\left(\frac{u x}{M}+\frac{v y}{N}\right)} \end{aligned}

\begin{aligned} F(u, v) &=\sum_{x=0}^{M-1} e^{-j 2 \pi \frac{u x}{M}} \sum_{y=0}^{N-1} f(x, y) e^{-j 2 \pi \frac{v y}{N}} \\ &=\sum_{x=0}^{M-1} F(x, v) e^{-j 2 \pi \frac{u x}{M}} \\ F(x, v) &=\sum_{y=0}^{N-1} f(x, y) e^{-j 2 \pi \frac{v y}{N}} \end{aligned}

\begin{aligned} &f(x, y)=\frac{1}{M N} \sum_{u=0}^{M-1} \sum_{v=0}^{N-1} F(u, v) e^{j 2 \pi\left(\frac{u x}{M}+\frac{v y}{N}\right)} \\ &M N f^{*}(x, y)=\sum_{u=0}^{M-1} \sum_{v=0}^{N-1} F^{*}(u, v) e^{-j 2 \pi\left(\frac{u x}{M}+\frac{v y}{N}\right)} \end{aligned}

$f(x, y)=\frac{\sum_{u=0}^{M-1} \sum_{v=0}^{N-1} F^{*}(u, v) e^{-j 2 \pi\left(\frac{u x}{M}+\frac{v y}{N}\right)}}{M N}$

def dft2D(self, image: np.array, shift: bool = False):
"""二维傅里叶变换，先对X轴进行傅里叶变换，然后再对Y轴进行傅里叶变换。

Args:
image (np.array): [图像ORkernel]
shift (bool, optional): [是否中心化]. Defaults to False.

Returns:
[type]: [返回傅里叶变换的值：a+bj]
"""
image_copy = image.copy()
if shift:
for i in range(image_copy.shape[0]):
for j in range(image_copy.shape[1]):
image_copy[i][j] = image_copy[i][j]*((-1)**(i+j))

dft_row = np.fft.fft(image_copy, axis=0)
dft_2 = np.fft.fft(dft_row, axis=1)
return dft_2


def idft2D(self, dft_2: np.array, shift: bool = False):
"""使用dft进行idft变换，F -> F*(共轭变换)

Args:
dft_2 (np.array): [傅里叶变换]
shift (bool,optional): [是否反中心化]. Defaults to False.
Returns:
[type]: [image进行反傅里叶变换，可能会产生j虚值。返回幅值]
"""
dft_2_copy = dft_2.copy()
idft_row = np.fft.fft(dft_2_copy.conjugate(), axis=0)
image = np.fft.fft(idft_row, axis=1)
image = image/(image.shape[0]*image.shape[1])
if shift:
for i in range(image.shape[0]):
for j in range(image.shape[1]):
image[i][j] = image[i][j]*(-1)**(i+j)
return abs(image)


def show_dft2D_in_2D(self, title: str, dft2: np.array, set_log: bool = True):
"""在2维平面上展示傅里叶变换，幅值

Args:
title (str): [标题]
dtf2 (np.array): [傅里叶变换的图像]
set_log (bool): [对傅里叶变换后的结果取log]
"""
dft2_copy = dft2.copy()
dft2_copy = abs(dft2_copy)
if set_log:
dft2_copy = np.log2(dft2_copy+1)
self.show_img(title, [dft2_copy], ['gray'])
return dft2_copy

def show_dft2D_in_3D(self, title: str, image: np.array, set_log: bool = True):
"""在3维平面上展示傅里叶变换

Args:
title (str): [标题]
image (np.array): [傅里叶变换的图像]
set_log (bool): [对傅里叶变换后的结果取log]
"""
image = abs(image)
if set_log:
image = np.log10(image+1)
fig = plt.figure()
plt.title(title)
ax3 = plt.axes(projection='3d')

xx = np.arange(0, image.shape[0])
yy = np.arange(0, image.shape[1])
X, Y = np.meshgrid(xx, yy)
ax3.plot_surface(X, Y, image.astype('uint8'), cmap='rainbow')
plt.show()



### 图像2的整数次幂填充

FFT (Fast Fourier Transform) refers to a way the discrete Fourier Transform (DFT) can be calculated efficiently, by using symmetries in the calculated terms. The symmetry is highest when n is a power of 2, and the transform is therefore most efficient for these sizes.

def find2power(self,cap):
"""找到距离cap最近的2的整数次幂,activate by the hashmap in the Java

Args:
cap ([type]): [cap > 0]

Returns:
[type]: [2的整数次幂]
"""
n = cap - 1
n |= n >> 1
n |= n >> 2
n |= n >> 4
n |= n >> 8
n |= n >> 1
return n+1


image_w = image.shape[0]
image_h = image.shape[1]
fit_w = ImageP.find2power(image_w)
fit_h = ImageP.find2power(image_h)