目录
一、傅里叶变换
原理可以参考:傅里叶分析之掐死教程(完整版)
任何连续周期信号,都可以用适当的一组正弦曲线组合而成
相位:
不是同时开始的一组余弦函数,在叠加时要体现开始时间
二、Numpy实现傅里叶变换
1、实现傅里叶变换
实现将低频移动到整个频谱中心
重新设置傅里叶变换返回复数数组的取值范围,重新映射
代码
# encoding: utf-8
import cv2
import matplotlib.pyplot as plt
import numpy as np
def show_img(name="test",img=None):
plt.figure()
channel = img.shape
if channel == 3:
b, g, r = cv2.split(img)
img = cv2.merge([r, g, b])
plt.imshow(img)
plt.title(name)
plt.show()
if __name__ == '__main__':
path = r"lena.jpg"
img = cv2.imread(path)
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
ret,binary = cv2.threshold(gray,127,255,0)
# 对图像进行傅里叶变换
f = np.fft.fft2(gray)
# 将低频移动到中心
fshift = np.fft.fftshift(f)
# 重置 区间,映射到[0,255]之间,以便使用图像显示
result = 20 * np.log(np.abs(fshift))
# 原始灰度图
plt.subplot(1,2,1 ),plt.imshow(gray,'gray'),plt.axis('off'),plt.title('original')
# 频谱图像
plt.subplot(1,2,2),plt.imshow(result,'gray'),plt.axis('off'),plt.title('result')
plt.show()
2、实现傅里叶的逆变换
使用傅里叶变换得到图像的低频和高频,
对低频(图像的细节)处理(保留、舍弃或其他),可以模糊图像等
对高频进行处理()保留、舍弃或其他),可以保留图像边界等
将低频移动到左上角
代码
# encoding: utf-8
import cv2
import matplotlib.pyplot as plt
import numpy as np
def show_img(name="test",img=None):
plt.figure()
channel = img.shape
if channel == 3:
b, g, r = cv2.split(img)
img = cv2.merge([r, g, b])
plt.imshow(img)
plt.title(name)
plt.show()
if __name__ == '__main__':
path = r"lena.jpg"
img = cv2.imread(path)
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
ret,binary = cv2.threshold(gray,127,255,0)
"""实现傅里叶变换"""
# 对图像进行傅里叶变换
f = np.fft.fft2(gray)
# 将低频从左上角移动到中心
fshift = np.fft.fftshift(f)
# 重置 区间,映射到[0,255]之间,以便使用图像显示
# result = 20 * np.log(np.abs(fshift))
"""实现逆傅里叶变换"""
# 将低频从中心移动到左上角
ishift = np.fft.ifftshift(fshift)
# 返回一个复数数组
iimg = np.fft.ifft2(ishift)
# 将上述复数数组重置区间到[0,255],便于图像显示
iimg = np.abs(iimg)
# 原始灰度图
plt.subplot(1,2,1 ),plt.imshow(gray,'gray'),plt.axis('off'),plt.title('original')
# 频谱图像
plt.subplot(1,2,2),plt.imshow(iimg,'gray'),plt.axis('off'),plt.title('result')
plt.show()
三、OpenCV 实现傅里叶变换
1、实现傅里叶变换
代码
# encoding: utf-8
import cv2
import matplotlib.pyplot as plt
import numpy as np
if __name__ == '__main__':
path = r"lena.jpg"
img = cv2.imread(path)
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
ret,binary = cv2.threshold(gray,127,255,0)
"""实现傅里叶变换"""
# 对图像进行傅里叶变换
dft = cv2.dft(np.float32(gray),flags=cv2.DFT_COMPLEX_OUTPUT)
# 将低频从左上角移动到中心
dshift = np.fft.fftshift(dft)
# 重置 区间,映射到[0,255]之间,以便使用图像显示
result = 20 * np.log(cv2.magnitude(dshift[:,:,0],dshift[:,:,1]))
# 原始灰度图
plt.subplot(1,2,1 ),plt.imshow(gray,'gray'),plt.axis('off'),plt.title('original')
# 频谱图像
plt.subplot(1,2,2),plt.imshow(result,'gray'),plt.axis('off'),plt.title('result')
plt.show()
2、实现傅里叶逆变换
代码
# encoding: utf-8
import cv2
import matplotlib.pyplot as plt
import numpy as np
if __name__ == '__main__':
path = r"lena.jpg"
img = cv2.imread(path)
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
ret,binary = cv2.threshold(gray,127,255,0)
"""实现傅里叶变换"""
# 对图像进行傅里叶变换
dft = cv2.dft(np.float32(gray),flags=cv2.DFT_COMPLEX_OUTPUT)
# 将低频从左上角移动到中心
dshift = np.fft.fftshift(dft)
# 重置 区间,映射到[0,255]之间,以便使用图像显示
# result = 20 * np.log(cv2.magnitude(dshift[:,:,0],dshift[:,:,1]))
"""实现逆傅里叶变换"""
# 将低频从中心移动到左上角
ishift = np.fft.ifftshift(dshift)
# 返回一个复数数组
iimg = cv2.idft(ishift)
# 将上述复数数组重置区间到[0,255],便于图像显示
iimg = cv2.magnitude(iimg[:,:,0],iimg[:,:,1])
# 原始灰度图
plt.subplot(1,2,1 ),plt.imshow(gray,'gray'),plt.axis('off'),plt.title('original')
# 频谱图像
plt.subplot(1,2,2),plt.imshow(iimg,'gray'),plt.axis('off'),plt.title('result')
plt.show()
四、高通滤波和低通滤波
1、高通滤波和低通滤波概述
高通滤波器
-
高通滤波器(HPF)是检测图像的某个区域,然后根据像素与周围像素的亮度差值来提升像素的亮度。
-
用于:边缘提取与增强。
-
注意:通过高通滤波器进行滤波后,再和原图像叠加,可以增强图像中灰度级变化较快的部分,即锐化。
低通滤波器
-
低通滤波器是像素与周围像素的亮度差值小于一个特定值时,平滑该像素的亮度。
-
用于:去噪和模糊化。
-
注意:低通滤波器容许低频信号通过,但减弱频率高于截止频率的信号的通过。
2、Numpy 实现高通滤波
# encoding: utf-8
import cv2
import matplotlib.pyplot as plt
import numpy as np
if __name__ == '__main__':
path = r"lena.jpg"
img = cv2.imread(path)
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
ret,binary = cv2.threshold(gray,127,255,0)
"""实现傅里叶变换"""
# 对图像进行傅里叶变换
f = np.fft.fft2(gray)
# 将低频从左上角移动到中心
fshift = np.fft.fftshift(f)
# 重置 区间,映射到[0,255]之间,以便使用图像显示
# result = 20 * np.log(np.abs(fshift))
"""高通滤波"""
# 得到边缘图像
rows,cols = gray.shape
# 取图像中心点
row_mid,col_mid = int(rows / 2), int(cols / 2)
# 去掉低频区域
fshift[row_mid-30:row_mid+30,col_mid-30:col_mid+30] = 0
"""实现逆傅里叶变换"""
# 将低频从中心移动到左上角
ishift = np.fft.ifftshift(fshift)
# 返回一个复数数组
iimg = np.fft.ifft2(ishift)
# 将上述复数数组重置区间到[0,255],便于图像显示
iimg = np.abs(iimg)
# 原始灰度图
plt.subplot(1,2,1 ),plt.imshow(gray,'gray'),plt.axis('off'),plt.title('original')
# 频谱图像
plt.subplot(1,2,2),plt.imshow(iimg,'gray'),plt.axis('off'),plt.title('result')
plt.show()
3、OpenCV 实现低通滤波
调节掩膜区域的大小可以得到不同模糊程度的图像,越大则越清晰,越小则越模糊。
# encoding: utf-8
import cv2
import matplotlib.pyplot as plt
import numpy as np
if __name__ == '__main__':
path = r"lena.jpg"
img = cv2.imread(path)
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
ret,binary = cv2.threshold(gray,127,255,0)
"""实现傅里叶变换"""
# 对图像进行傅里叶变换
dft = cv2.dft(np.float32(gray),flags=cv2.DFT_COMPLEX_OUTPUT)
# 将低频从左上角移动到中心
dshift = np.fft.fftshift(dft)
# 重置 区间,映射到[0,255]之间,以便使用图像显示
# result = 20 * np.log(cv2.magnitude(dshift[:,:,0],dshift[:,:,1]))
"""低通滤波"""
rows,cols = gray.shape
# 取图像中心点
row_mid,col_mid = int(rows / 2), int(cols / 2)
# 构造掩膜图像
mask = np.zeros((rows,cols,2),np.uint8)
# 去掉低频区域
mask[row_mid-30:row_mid+30,col_mid-30:col_mid+30] = 1
# 将频谱图像和掩膜相乘,保留低频部分,高频部分变成0
md = dshift * mask
"""实现逆傅里叶变换"""
# 将低频从中心移动到左上角
imd = np.fft.ifftshift(md)
# 返回一个复数数组
iimg = cv2.idft(imd)
# 将上述复数数组重置区间到[0,255],便于图像显示
iimg = cv2.magnitude(iimg[:,:,0],iimg[:,:,1])
# 原始灰度图
plt.subplot(1,2,1 ),plt.imshow(gray,'gray'),plt.axis('off'),plt.title('original')
# 频谱图像
plt.subplot(1,2,2),plt.imshow(iimg,'gray'),plt.axis('off'),plt.title('result')
plt.show()