这里我们只提取灰度信息,所以OpencV的imgread的flags参数选择0.其次,两个图像的信息可以交换必须保证图像大小一致,这里用resize把两个图像统一为512*288大小。
import numpy as np
import cv2
# read image
figure1_filename = 'leopard.jpg'
figure2_filename = 'lion.jpg'
figure1 = cv2.imread(figure1_filename, 0)
figure2 = cv2.imread(figure2_filename, 0)
# Uniform image size
figure1 = cv2.resize(figure1, (512, 288))
figure2 = cv2.resize(figure2, (512, 288))
这里用numpy的fft包,使用fft2快速傅里叶变换,会返回一个复数类型,用type函数提取到的类型为
# Fourier transform
fft_fig1 = np.fft.fft2(figure1)
fft_fig2 = np.fft.fft2(figure2) # the result from is complex number
numpy有angle和abs可以提取复数的相位、幅度信息
# Extract the amplitude phase information
fig1_amp = np.abs(fft_fig1)
fig1_pha = np.angle(fft_fig1)
fig2_amp = np.abs(fft_fig2)
fig2_pha = np.angle(fft_fig2)
我们都知道欧拉公式 e j ω = c o s ω + j s i n ω e^{j\omega}=cos\omega +jsin\omega ejω=cosω+jsinω
欧拉公式告诉了我们复数信息可以用sin和cos实现。幅度也好理解,对于虚数 z = a + b j z = a+bj z=a+bj,其 幅值为 a 2 + b 2 \sqrt{a^2+b^2} a2+b2
有了这些,我们可以通过一下代码交换幅度信息
# exchange amplitude
fig1_transform = fig2_amp*np.cos(fig1_pha) + fig2_amp*np.sin(fig1_pha)*1j
fig2_transform = fig1_amp*np.cos(fig2_pha) + fig1_amp*np.sin(fig2_pha)*1j
得到这样一个复数的信息之后,我们要把频域变换为时域显示,这里仍然使用numpy的fft包,使用ifft2函数,最后一定的一定要用unit8类型强制转换,因为灰度图像只能允许0~255的值存在。
# IFFT
fig1_Amp2_Pha1 = np.uint8(np.fft.ifft2(fig1_transform))
fig2_Amp1_Pha2 = np.uint8(np.fft.ifft2(fig2_transform))
# show
cv2.imshow('figure1_has_amp2', fig1_Amp2_Pha1)
cv2.imshow('figure2_has_amp1', fig2_Amp1_Pha2)
这类其实对步骤三稍微改一下就好了,剩下的都是重复的步骤
# exchange phase
fig1_transform_p = fig1_amp*np.cos(fig2_pha) + fig1_amp*np.sin(fig2_pha)*1j
fig2_transform_p = fig2_amp*np.cos(fig1_pha) + fig2_amp*np.sin(fig1_pha)*1j
# IFFT
fig1_Amp1_Pha2 = np.uint8(np.fft.ifft2(fig1_transform_p))
fig2_Amp2_Pha1 = np.uint8(np.fft.ifft2(fig2_transform_p))
# show
cv2.imshow('figure1_has_pha2', fig1_Amp1_Pha2)
cv2.imshow('figure2_has_pha1', fig2_Amp2_Pha1)
cv2.waitKey(0)
附上代码下载地址:
https://download.csdn.net/download/qq_42635142/12502662