我正在研究图像处理问题,想知道是否DFT(rotation(image)) == rotation(DFT(image)) (1)。我的最终目标是在傅里叶域中应用旋转,然后进行傅里叶逆变换并获得旋转后的图像。
这个问题非常接近我正在寻找的内容。该问题链接到资源说(1)在理论上是正确的(对于无限信号和无限频率箱),并且公认的答案表明它在数学上是如此。然而,答案还指出,由于人工制品,使用 DFT 算法在“现实世界”中重现可能实际上很困难。
我试图重现 (1) 但到目前为止未能这样做,而且我的印象是有些东西比“人工制品”更错误。我的实验可以总结为下图:

我在傅里叶域中显示的图像是 FT 虚部的缩放,具有标准化强度以增强可视化。但是,该点代表实部,如果您选择像这样可视化它们,也代表幅度和相位谱。
如您所见,我没有得到与(1)一致的结果,因为最后一列的两个图像(根本不相等)。我觉得问题出在傅里叶图像的旋转上。旋转后的傅里叶图像看起来与旋转后的傅里叶图像完全不同。我实际上并没有真正理解后者是如何计算的:即使旋转 45 度,例如中间部分保持大致相同(看看中心白色像素的 4 个黑色邻居,它们在两个图像中都是相同的第 2 列)。
为了强调我的观点,我制作了一个动画,显示(左)原始图像的 FT,(中)傅里叶的旋转,(右)旋转的傅里叶,角度在 0 到 90 之间变化

我尝试过对原始图像进行更严格的填充,注意位深度,尝试旋转幅度和相位而不是实部和虚部,但到目前为止还没有运气。有什么我做错了吗?如何实现在傅里叶域中“正确”应用旋转的目标?
这是重现大部分实验的代码(在 Python 中,使用 OpenCV 和 Scipy)以及原始图像

import numpy as np
import cv2
from scipy import ndimage
# Helper function to save an image with a normalized range for visualization
def normalize_and_cvt_to_uint8(im):
min_ = np.min(im)
max_ = np.max(im)
im_norm = (im - min_) / (max_ - min_) * 255
return im_norm.astype(np.uint8)
# Rotate a complex image
def rot(im_tot, angle):
# Get real and imaginary part
im_real = im_tot[:,:,0]
im_imag = im_tot[:,:,1]
# Rotate each part individually
im_real_rot = ndimage.rotate(im_real, angle, reshape = False)
im_imag_rot = ndimage.rotate(im_imag, angle, reshape = False)
# Recreate complex image
im_rot = np.dstack((im_real_rot, im_imag_rot))
return im_rot
# Helper function to pad an image to a given shape
def pad_to_shape(im, goal_h, goal_w):
[h, w] = im.shape[:2]
delta_w = goal_w - w
delta_h = goal_h - h
top, bottom = delta_h // 2, delta_h - (delta_h // 2)
left, right = delta_w // 2, delta_w - (delta_w // 2)
return cv2.copyMakeBorder(im, top, bottom, left, right, cv2.BORDER_CONSTANT, value=0)
path_im = "poivrons.png"
im = cv2.imread(path_im, 0)
im_shape = 801
im = pad_to_shape(im, im_shape, im_shape)
cv2.imwrite("starting_im.png", im)
# Compute DFT of original image
dft1 = cv2.dft(np.float32(im), flags=cv2.DFT_COMPLEX_OUTPUT)
dft1 = np.fft.fftshift(dft1)
cv2.imwrite("dft1.png", normalize_and_cvt_to_uint8(dft1[:,:,1]))
# Rotate original image
angle = 45
im_rot = ndimage.rotate(im, angle, reshape=False)
cv2.imwrite("rotated_img.png", im_rot)
# Compute DFT of rotated image
dft2 = cv2.dft(np.float32(im_rot), flags=cv2.DFT_COMPLEX_OUTPUT)
dft2 = np.fft.fftshift(dft2)
cv2.imwrite("dft2.png", normalize_and_cvt_to_uint8(dft2[:,:,1]))
# Rotate DFT of original image
dft3 = rot(dft1, angle)
dft3 = np.fft.fftshift(dft3)
# Compute IDFT of rotated DFT
cv2.imwrite("dft3.png", normalize_and_cvt_to_uint8(dft3[:,:,1]))
im_back = cv2.idft(np.fft.ifftshift(dft3), flags=cv2.DFT_SCALE | cv2.DFT_REAL_OUTPUT)
cv2.imwrite("back_img.png", im_back)