首页 >> 大全

数字图像处理关于傅立叶变换的小记

2023-10-07 大全 31 作者:考证青年

数字图像处理关于傅里叶变换的小记

文章目录 傅立叶变换与傅立叶逆变换 冲激卷积 采样定理图像的内插和重采样

背景

傅里叶级数得名于法国数学家约瑟夫·傅里叶(1768年–1830年),他提出任何周期函数都可以展开为三角级数。此前数学家如拉格朗日等已经找到了一些非周期函数的三角级数展开,而认定一个函数有三角级数展开之后,通过积分方法计算其系数的公式,欧拉、达朗贝尔和克莱罗早已发现,傅里叶的工作得到了丹尼尔·伯努利的赞助。傅里叶介入三角级数用来解热传导方程,其最初论文在1807年经拉格朗日、拉普拉斯和勒让德评审后被拒绝出版,他的现在被称为傅里叶逆转定理的理论后来发表于1820年的《热的解析理论》中。将周期函数分解为简单振荡函数的总和的最早想法,可以追溯至公元前3世纪古代天文学家的均轮和本轮学说。

傅里叶级数在数论、组合数学、信号处理、概率论、统计学、密码学、声学、光学等领域都有着广泛的应用。

傅里叶在这个领域的贡献是,他指出任何周期函数都可以表示为不同频率的正弦和/或余弦函数之后的形式,每一个正弦项和/或余弦都乘以不同的系数,无论函数多么复杂,只要它是周期性的,并且满足一些适度的数学条件,都可以用这样的和来表示。即任何周期函数,都可以看作是不同振幅,不同相位正弦波的叠加。甚至非周期函数(但该曲线的面积是有限的情况下)也可用正弦和/或余弦乘以加权函数的积分来表示。

傅里叶变换原来就是一种变换而已,只是这种变换是从时间转换为频率的变化

参考链接 %E5%82%85%E9%87%8C%E5%8F%B6%E7%BA%A7%E6%95%B0

复数

∣ Z ∣ = x 2 + y 2 |Z|=\sqrt{x^2+y^2} ∣Z∣=x2+y2​

Z =|Z|(cosθ+jsinθ)

ejθ=cosθ+jsinθ

则可得:θ

import math
print(math.acos(1/math.sqrt(5)))

输出

1.1071487177940904

傅里叶级数 频域与时域

傅立叶变换,傅里叶级数和频谱

复数形式的傅里叶级数的证明

傅立叶变换与傅立叶逆变换 一维离散傅立叶变换

# 单变量的离散傅立叶变换 P138
import numpy as npdef DFT(x):M = np.size(x)new_x = np.zeros((M, ), dtype=np.complex)for n in range(0, M):for m in range(0, M):new_x[n] += x[m]*np.exp(-2j*np.pi*m*n/M)return new_xx = np.random.rand(1024, )
x1 = DFT(x)
x2 = np.fft.fft(x)
print("x1", x1)
print("x2", x2)
print('Is DFT close to fft?', np.allclose(x1, x2, 1e-12))

二维离散傅立叶变换

# 二维离散傅立叶变换
import numpy
import cv2 as cv
import timedef FFT_v1(Img, Wr):if Img.shape[0] == 2:pic = numpy.zeros([2], dtype=complex)pic = pic * (1 + 0j)pic[0] = Img[0] + Img[1] * Wr[0]pic[1] = Img[0] - Img[1] * Wr[0]return picelse:pic = numpy.empty([Img.shape[0]], dtype=complex)pic[0:Img.shape[0] // 2] = FFT_v1(Img[::2], Wr[::2]) + Wr * FFT_v1(Img[1::2], Wr[::2])pic[Img.shape[0] // 2:Img.shape[0]] = FFT_v1(Img[::2], Wr[::2]) - Wr * FFT_v1(Img[1::2], Wr[::2])return picdef FFT_1d(Img):Wr = numpy.ones([Img.shape[0] // 2]) * [numpy.cos(2 * numpy.pi * i / Img.shape[0]) - 1j * numpy.sin(2 * numpy.pi * i / Img.shape[0]) for i innumpy.arange(Img.shape[0] / 2)]return FFT_v1(Img, Wr)def FFT_2d(Img):pic = numpy.zeros([Img.shape[0], Img.shape[1]], dtype=complex)for i in numpy.arange(Img.shape[0]):pic[:, i] = FFT_1d(Img[:, i])for i in numpy.arange(Img.shape[1]):pic[i, :] = FFT_1d(pic[i, :])return picif __name__ == "__main__":array = numpy.zeros([512], dtype=complex)img = cv.imread('p1.jpg', 0)print("numpy.fft.fft2()函数计算结果:")t_s1 = time.time()a=numpy.fft.fft2(img)print(a)t_e1 = time.time()print("计算时间:" + str(t_e1 - t_s1))print("FFT_2d()函数的计算结果:")t_s2 = time.time()b=FFT_2d(img)print(b)t_e2 = time.time()print("计算时间:" + str(t_e2 - t_s2))print(a == b)print(numpy.allclose(a, b), 1e-12)

时间消耗

import time
import numpy
import matplotlib.pyplot as pyplotdef DFT(x):N = numpy.size(x)X = numpy.zeros((N,),dtype=numpy.complex128)for m in range(0,N):for n in range(0,N):X[m] += x[n]*numpy.exp(-numpy.pi*2j*m*n/N)return Xdft_time = []
fft_time = []
n_series = []
for N in numpy.power(2,range(1,11)):print(N)x = numpy.ones((N,))t0 = time.time()for pp in range(0,2):X = DFT(x)print(X)t1 = (time.time()-t0)/2.0t0 = time.time()for pp in range(0,2):Y = numpy.fft.fft(x)t2 = (time.time()-t0)/2.0n_series.append(N)dft_time.append(t1)fft_time.append(t2)line_dft, = pyplot.plot(n_series, dft_time, label='DFT')
line_fft, = pyplot.plot(n_series, fft_time,'r',label='FFT')
pyplot.legend(handles=[line_dft, line_fft])
pyplot.ylabel('times(second)')
pyplot.xlabel('N')pyplot.show()
print(dft_time)
print(fft_time)
print(numpy.allclose(X, Y), 1e-12)
print(X == Y)

import cv2 as cv
import numpy as np
import matplotlib.pyplot as plt
import timeimg = cv.imread('t1.png', 0)plt.subplot(131)
plt.title("original")
plt.axis('off')
plt.imshow(img, cmap='gray')f = np.fft.fft2(img)  # 快速傅里叶变换算法得到频率分布
fshift = np.fft.fftshift(f)  # 默认结果中心点位置是在左上角,调用fftshift()函数转移到中间位置
fimg = np.log(np.abs(fshift))  # fft结果是复数, 其绝对值结果是振幅,频谱对数变换,取对数放大波动#展示结果
plt.subplot(132)
plt.title('Fourier Fourier')
plt.axis('off')
plt.imshow(fimg, 'gray')# 傅立叶逆变换
plt.subplot(133)
ifshift = np.fft.ifftshift(fshift)
iimg = np.fft.ifft2(ifshift)
iimg = np.abs(iimg)
plt.axis('off')
plt.title('Inverse Fourier Image')
plt.imshow(iimg, 'gray')plt.savefig('test0.png')
plt.show()

左边为原始图像,中间为频率分布图谱,其中越靠近中心位置频率越低,越亮(灰度值越高)的位置代表该频率的信号振幅越大,右边为傅立叶逆变换得到的图像。

#计算一维傅里叶变换

numpy.fft.fft(a, n=None, axis=-1, norm=None)

#计算二维的傅里叶变换

numpy.fft.fft2(a, n=None, axis=-1, norm=None)

#计算n维的傅里叶变换

numpy.fft.fftn()

#计算n维实数的傅里叶变换

numpy.fft.rfftn()

#返回傅里叶变换的采样频率

numpy.fft.()

#将FFT输出中的直流分量移动到频谱中央

numpy.fft.shift()

#实现图像逆傅里叶变换,返回一个复数数组

numpy.fft.ifft2(a, n=None, axis=-1, norm=None)

#()函数的逆函数,它将频谱图像的中心低频部分移动至左上角

numpy.fft.()

#将复数转换为0至255范围

iimg = numpy.abs(逆傅里叶变换结果)

冲激

以一个面积为1的三角形为例,底边不断收缩,当底边a->0时,高->∞

卷积

卷积的求法(利用傅立叶变换)

卷积与傅里叶变换有着密切的关系。例如两函数的傅里叶变换的乘积等于它们卷积后的傅里叶变换,利用此一性质,能简化傅里叶分析中的许多问题。

采样定理

象一个白色的圆盘,有一条沿着半径的黑线,圆盘以角速度[公式]旋转。

你以一定的周期拍照,就是采样。

你拍照的频率恰好为圆盘自转频率两倍的时候,你的照片里黑线的位置,永远是下一张和上一张呈180度,看不出圆盘原来到底是顺时针转的还是逆时针转的。

图像的内插和重采样

# 最近邻内插算法import cv2 as cv
import numpy as npimg = cv.imread("Fig0417(a)(barbara).tif", 0)
height, width = img.shape
fx = 0.5
fy = 0.5new_height = int(fx*height)
new_width = int(fy*width)
new_img = np.zeros((new_height, new_width), dtype=np.uint8)for i in range(height):for j in range(width):new_i = int(fx*i)new_j = int(fy*j)new_img[new_i, new_j] = img[i, j]new_img1 = cv.resize(img, (0, 0), fx=0.5, fy=0.5, interpolation=cv.INTER_NEAREST)
new_img2 = cv.resize(new_img1, (0, 0), fx=2, fy=2, interpolation=cv.INTER_NEAREST)
new_img3 = cv.resize(new_img, (0, 0), fx=2, fy=2, interpolation=cv.INTER_NEAREST)while 1:cv.imshow("img", img)cv.imshow('new_img', new_img)cv.imshow('new_img1', new_img1)cv.imshow('new_img2', new_img2)cv.imshow('new_img3', new_img3)if cv.waitKey(1) == 27:break

# 双线性内插法
import cv2 as cv
import numpy as np
import timedef resize(src, fx, fy):src_h, src_w = src.shape[:2]dst_w, dst_h = int(src_w*fx), int(src_h*fy)if fx == 1 and fy == 1:return src.copy()# 遍历目标图像,插值dst = np.zeros((dst_h, dst_w, 3), dtype=np.uint8)for n in range(3):  # 对channel循环for dst_y in range(dst_h):  # 对height循环for dst_x in range(dst_w):  # 对width循环# 目标在源上的坐标src_x = (dst_x + 0.5) / fx - 0.5src_y = (dst_y + 0.5) / fy - 0.5# 计算在源图上四个近邻点的位置src_x_0 = int(np.floor(src_x))src_y_0 = int(np.floor(src_y))src_x_1 = min(src_x_0 + 1, src_w - 1)src_y_1 = min(src_y_0 + 1, src_h - 1)# 双线性插值value0 = (src_x_1 - src_x) * src[src_y_0, src_x_0, n] + (src_x - src_x_0) * src[src_y_0, src_x_1, n]value1 = (src_x_1 - src_x) * src[src_y_1, src_x_0, n] + (src_x - src_x_0) * src[src_y_1, src_x_1, n]dst[dst_y, dst_x, n] = int((src_y_1 - src_y) * value0 + (src_y - src_y_0) * value1)return dstif __name__ == '__main__':img = cv.imread('Fig0417(a)(barbara).tif')start = time.time()img_out = resize(img, fx=0.5, fy=0.5)img_out0 = cv.resize(img, (0, 0), fx=0.5, fy=0.5, interpolation=cv.INTER_LINEAR_EXACT)print('cost '+str(time.time() - start)+' seconds')while 1:cv.imshow('src_image', img)cv.imshow('dst_image', img_out)cv.imshow('dst_image0', img_out0)if cv.waitKey(1) == 27:break

参考

傅立叶变换,傅立叶序列以及频谱

傅立叶级数

深入浅出的讲解傅里叶变换(真正的通俗易懂)

numpy.fft.fft

关于我们

最火推荐

小编推荐

联系我们


版权声明:本站内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 88@qq.com 举报,一经查实,本站将立刻删除。备案号:桂ICP备2021009421号
Powered By Z-BlogPHP.
复制成功
微信号:
我知道了